idmission-web-sdk 2.0.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/models/helpers.d.ts +2 -0
- package/dist/sdk2.cjs.development.js +89 -49
- package/dist/sdk2.cjs.development.js.map +1 -1
- package/dist/sdk2.cjs.production.js +1 -1
- package/dist/sdk2.cjs.production.js.map +1 -1
- package/dist/sdk2.esm.js +89 -49
- package/dist/sdk2.esm.js.map +1 -1
- package/dist/sdk2.umd.development.js +89 -49
- package/dist/sdk2.umd.development.js.map +1 -1
- package/dist/sdk2.umd.production.js +1 -1
- package/dist/sdk2.umd.production.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk2.cjs.development.js","sources":["../src/version.ts","../src/lib/utils/platform.ts","../src/lib/utils/dataUrlToBase64.ts","../src/contexts/SubmissionContext.ts","../src/components/common/Page.tsx","../src/components/common/overlay.tsx","../src/components/common/LoaderButton.tsx","../src/components/submission/GeolocationAccessDeniedOverlay.tsx","../src/components/submission/Errors.ts","../src/components/submission/SubmissionErrorOverlay.tsx","../src/components/submission/SessionIdMissingOverlay.tsx","../src/components/submission/SessionValidationFailedOverlay.tsx","../src/components/submission/AuthUrlNotAllowedOverlay.tsx","../src/components/submission/SessionValidationErrorOverlay.tsx","../src/components/common/spinner.tsx","../src/contexts/AuthStateContext.tsx","../src/lib/utils/logger.ts","../src/components/submission/SubmissionProvider.tsx","../src/lib/barcode/Scan.ts","../src/lib/utils/getFrameDimensions.ts","../src/components/common/InvisibleCanvas.tsx","../src/lib/camera/Camera.ts","../src/components/camera/CameraProvider.tsx","../src/lib/models/VisionRuntime.ts","../src/lib/utils/isMobile.ts","../src/lib/utils/cropping.ts","../src/lib/models/CapabilityProbing.ts","../src/lib/models/Focus.ts","../node_modules/@mediapipe/face_detection/face_detection.js","../src/lib/models/helpers.ts","../src/lib/models/FaceDetection.ts","../src/lib/models/preloadModels.ts","../src/lib/models/DocumentDetection.ts","../src/lib/models/FrameLoop.ts","../src/components/id_capture/DocumentDetectionModelProvider.tsx","../src/components/id_capture/IdCaptureModelsProvider.tsx","../src/components/id_capture/CapturedDocuments.ts","../src/components/id_capture/IdCaptureRequirementOption.ts","../src/components/id_capture/IdCaptureStateProvider.tsx","../src/components/common/debug.tsx","../src/lib/locales/en/translation.js","../src/lib/locales/es/translation.js","../src/lib/locales/index.ts","../src/components/common/GuidanceMessage.tsx","../src/components/common/cdn.ts","../src/components/id_capture/IdCapture.tsx","../src/components/common/ExitCaptureButton.tsx","../src/components/common/ButtonsRow.tsx","../src/components/id_capture/IdCaptureLoadingGraphic.tsx","../src/components/id_capture/IdCaptureLoadingOverlayDefault.tsx","../src/components/id_capture/IdCaptureLoadingOverlayLegacy.tsx","../src/components/common/CapturedDocumentImg.tsx","../src/components/id_capture/IdCaptureSuccess.tsx","../src/components/camera/CameraVideoTag.tsx","../src/components/common/useShowSuccessScreen.ts","../src/lib/utils/canvas.ts","../src/components/id_capture/IdCaptureGuideOverlay.tsx","../src/components/id_capture/FlipIdPrompt.tsx","../src/components/id_capture/IdCaptureFitGuide.tsx","../src/components/id_capture/IdCaptureGuides.tsx","../src/components/common/SelfieProgressPreview.tsx","../src/components/document_capture/DocumentCaptureStateProvider.tsx","../src/components/document_capture/DocumentCaptureGuideOverlay.tsx","../src/components/document_capture/DocumentCaptureScreen.tsx","../src/lib/utils/resizeFile.tsx","../src/components/fallback_flows/IdCapture.tsx","../src/components/id_capture/IdCaptureWizard.tsx","../src/components/selfie_capture/SelfieGuidanceModelsProvider.tsx","../src/lib/utils/useTimeout.ts","../src/components/fallback_flows/SelfieCapture.tsx","../src/components/selfie_capture/SelfieCapture.tsx","../src/components/face_liveness/FaceLivenessCapture.tsx","../src/components/selfie_capture/SelfieCaptureLoadingOverlayLegacy.tsx","../src/components/selfie_capture/SelfieCaptureLoadingGraphic.tsx","../src/components/selfie_capture/SelfieCaptureLoadingOverlayDefault.tsx","../src/components/face_liveness/FaceLivenessWizard.tsx","../src/components/GuideOrientationProvider.tsx","../src/components/submission/SubmissionSuccess.tsx","../src/components/additional_document_capture/AdditionalDocumentCapture.tsx","../src/components/additional_document_capture/AdditionalDocumentCaptureWizard.tsx","../src/components/signature_capture/data.ts","../src/components/common/signature.tsx","../src/lib/camera/useVideoRecorder.ts","../src/components/video_signature_capture/VideoSignatureCapture.tsx","../src/components/video_signature_capture/VideoSignatureWizard.tsx","../src/components/video_id/IdVideoCaptureFlipIdPrompt.tsx","../src/components/video_id/IdVideoCaptureGuides.tsx","../src/components/read_text_prompt/ReadTextPrompt.tsx","../src/components/video_id/IdVideoCapture.tsx","../src/components/CompositeWizard.tsx","../src/themes/index.tsx","../src/components/customer_verification/CustomerVerificationCapture.tsx","../src/components/customer_identification/CustomerIdentificationCapture.tsx","../src/index.tsx"],"sourcesContent":["export const webSdkVersion = '2.0.2';\n","'use client'\n\nimport platform from 'platform'\n\nexport type Platform = typeof platform\n\nexport function getPlatform(): Platform | undefined {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof window !== 'undefined' && typeof window.platform !== 'undefined')\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return window.platform\n\n return platform\n}\n","export async function dataUrlToBase64(url: string): Promise<string> {\n if (url.indexOf('blob:') >= 0) {\n return new Promise((resolve, reject) => {\n // Fetch the Blob content\n fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error('Failed to fetch Blob content');\n }\n return response.blob();\n })\n .then(blob => {\n const reader = new FileReader();\n reader.onload = () => {\n const base64String = reader.result ? (reader.result as string).split(',')[1] : ''\n resolve(base64String);\n };\n reader.onerror = () => {\n reader.abort();\n reject(new Error('Error converting blob to base64'));\n };\n reader.readAsDataURL(blob);\n })\n .catch(error => {\n reject(error);\n });\n });\n }\n return url.replace(/^data:image\\/(png|jpeg);base64,/, '')\n}\n\nexport function dataUrlToBase64Sync(url: string): string {\n return url.replace(/^data:.*;base64,/, '')\n}\n\nexport function contentDispositionFromDataUrl(url: string): string {\n return url.match(/^(data:.*;base64),/)?.[1] ?? ''\n}\n\nexport function b64toBlob(b64Data: string, contentType = '', sliceSize = 512) {\n const byteCharacters = atob(b64Data)\n const byteArrays = []\n\n for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {\n const slice = byteCharacters.slice(offset, offset + sliceSize)\n\n const byteNumbers = new Array(slice.length)\n for (let i = 0; i < slice.length; i++) {\n byteNumbers[i] = slice.charCodeAt(i)\n }\n\n const byteArray = new Uint8Array(byteNumbers)\n byteArrays.push(byteArray)\n }\n\n return new Blob(byteArrays, { type: contentType })\n}\n\nexport function blobToB64(blob: Blob): Promise<string> {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.readAsDataURL(blob)\n })\n}\n","import { UploadedDocument } from '../components/additional_document_capture/AdditionalDocumentCapture'\nimport { webSdkVersion } from '../version'\nimport { getPlatform } from '../lib/utils/platform'\nimport { dataUrlToBase64Sync } from '../lib/utils/dataUrlToBase64'\nimport { DetectedObjectBox } from '../lib/models/DocumentDetection'\n\nexport enum SubmissionAction {\n NONE = 'NONE',\n ENROLL = 'ENROLL',\n IDENTIFY = 'IDENTIFY',\n VALIDATE = 'VALIDATE',\n VERIFY = 'VERIFY',\n}\n\nexport enum SubmissionStatus {\n READY = 'READY',\n SUBMITTING = 'SUBMITTING',\n SUBMITTED = 'SUBMITTED',\n FAILED = 'FAILED',\n}\n\nexport type SubmissionEnvironment = 'prod' | 'demo'\n\nexport const submissionHosts = {\n prod: 'https://api.idmission.com',\n demo: 'https://apidemo.idmission.com',\n}\n\nexport type SubmissionRequest = {\n securityData: {\n userName: string\n password: string\n merchantId: number\n }\n customerData: {\n idData: {\n idImageFront?: string\n idImageBack?: string\n videoIdImageFront?: string\n videoIdImageBack?: string\n\n idType: 'NSP'\n idCountry: 'NSP'\n idState: ''\n }\n personalData?: PersonalData\n cardData?: CardData\n biometricData?: {\n selfie?: string\n videoData?: string\n voiceData?: string\n voiceStartTime?: number\n expectedAudioText?: string\n }\n signatureData?: {\n signatureImage?: string\n signatureVideo?: string\n }\n additionalDocuments?: UploadedDocument[]\n }\n // TODO: remove once API is fixed\n biometricData?: {\n selfie?: string\n }\n additionalData: {\n uniqueRequestId: string\n clientRequestID?: string\n clientTraceId?: string\n manualReviewRequired: 'Y' | 'N'\n bypassAgeValidation: 'Y' | 'N'\n deDuplicationRequired: 'Y' | 'N'\n bypassNameMatching: 'Y' | 'N'\n postDataAPIRequired: 'Y' | 'N'\n postDataOnReviewRequired: 'Y' | 'N'\n sendInputImagesInPost: 'Y' | 'N'\n sendProcessedImagesInPost: 'Y' | 'N'\n needImmediateResponse: 'Y' | 'N'\n deduplicationSynchronous: 'Y' | 'N'\n verifyDataWithHost: 'Y' | 'N'\n idBackImageRequired: 'Y' | 'N'\n stripSpecialCharacters: 'Y' | 'N'\n idImageResolutionCheck: 'Y' | 'N'\n metadata?: string\n }\n employee?: { companyId?: string }\n}\n\nexport type CaptureAttemptMetadata = {\n autoCapture: 'Y' | 'N' // always Y until we add support for manual capture\n captureTime: number // time from start of the camera start to camera stop in ms\n operationTime?: number // time from start of the selfie detection or ID detection to capture in ms\n bestDetectionScore?: number\n bestFocusScore?: number\n boundingBox?: DetectedObjectBox\n}\n\nexport type PersonalData = {\n uniqueNumber?: string\n name?: string\n phone?: string\n phoneCountryCode?: string\n email?: string\n dob?: string // date of birth, formatted DD/MM/YYYY, e.g. 31/12/2019\n gender?: 'M' | 'F'\n addressLine1?: string\n addressLine2?: string\n city?: string\n district?: string // two-letter code indicating state if USA, e.g. CA\n postalCode?: string\n country?: string // three-letter code indicating country, e.g. USA\n}\n\nexport type CardData = {\n cardToken?: string\n cardLast4?: string\n cardExpDate?: string\n nameOnCard?: string\n}\n\nexport type SubmissionMetadata = {\n selfie: CaptureAttemptMetadata[]\n back: CaptureAttemptMetadata[]\n front: CaptureAttemptMetadata[]\n sdkVersion: string\n isRealIDCheckRequired: 'true' | 'false'\n os?: string\n osVersion?: string\n browserVersion?: string\n Resolution?: string\n GeoLocation?: string\n}\n\nexport type SubmissionResponseStatus = {\n statusCode: string\n statusMessage?: string\n errorData?: string\n}\n\nexport type SubmissionResponse = {\n status: SubmissionResponseStatus\n resultData: Record<string, unknown>\n}\n\nexport type LivenessCheckRequest = {\n securityData: {\n userName: string\n password: string\n merchantId: number\n }\n customerData: {\n additionalData?: {\n uniqueRequestId?: string\n }\n biometricData: {\n selfie: string\n }\n idData?: {\n idImageFront?: string\n }\n }\n additionalData: {\n uniqueRequestId: string\n clientRequestID?: string\n stripSpecialCharacters: 'Y' | 'N'\n estimateAge: 'Y' | 'N'\n predictGender: 'Y' | 'N'\n metadata?: string\n }\n}\nexport type LiveCheckResponse = {\n status: { statusCode: string; statusMessage: string; errorData: string }\n resultData: {\n verificationResult: string\n eyeCovering: 'true' | 'false'\n faceMask: 'true' | 'false'\n headCovering: 'true' | 'false'\n cellPhone: 'true' | 'false'\n }\n}\n\nexport function parseJwt(token: string): Record<string, unknown> {\n const base64Url = token.split('.')[1]\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')\n const jsonPayload = decodeURIComponent(\n window\n .atob(base64)\n .split('')\n .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n )\n\n return JSON.parse(jsonPayload)\n}\n\nexport function determineSubmissionHost(\n environment: SubmissionEnvironment,\n token?: string,\n): string {\n if (token) {\n switch (parseJwt(token)['iss']) {\n case 'https://auth.idmission.com/auth/realms/identity':\n return submissionHosts.prod\n case 'https://demoauth.idmission.com/auth/realms/identity':\n return submissionHosts.demo\n }\n }\n\n const host = submissionHosts[environment]\n if (!host)\n throw new Error(`unrecognized SubmissionEnvironment ${environment}`)\n return host\n}\n\nexport function determineSubmissionEndpoint(\n action: SubmissionAction,\n hasId: boolean,\n hasSelfie: boolean,\n): string {\n switch (action) {\n case SubmissionAction.ENROLL:\n return hasId ? `/v4/customer/enroll` : `/v4/customer/enroll-biometrics`\n\n case SubmissionAction.IDENTIFY:\n return `/v4/customer/identify`\n\n case SubmissionAction.VALIDATE:\n return hasSelfie\n ? `/v4/customer/validate-id-match-face`\n : `/v4/customer/validate-id`\n\n case SubmissionAction.VERIFY:\n return `/v4/customer/verify`\n\n default:\n throw new Error(`unrecognized SubmissionAction ${action}`)\n }\n}\n\nexport function liveCheckEndpoint(hasDocumentToMatchFace = false): string {\n return hasDocumentToMatchFace\n ? `/v4/customer/match-id-face`\n : `/v4/customer/live-check`\n}\n\nexport function apiHeaders(\n sessionId?: string,\n sendBase64DocumentsInSwaggerProxy = false,\n): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'X-Send-Base64-Documents': sendBase64DocumentsInSwaggerProxy ? '1' : '0',\n Origin: '*',\n }\n if (sessionId) {\n headers['X-Session-Id'] = sessionId\n }\n return headers\n}\n\nexport function attachMetadataToRequest(\n request: SubmissionRequest | LivenessCheckRequest,\n {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n }: {\n selfieCaptureAttempts: CaptureAttemptMetadata[]\n idFrontCaptureAttempts: CaptureAttemptMetadata[]\n idBackCaptureAttempts: CaptureAttemptMetadata[]\n geolocationResult: GeolocationPosition | null\n },\n) {\n const metadata: SubmissionMetadata = {\n selfie: selfieCaptureAttempts,\n front: idFrontCaptureAttempts,\n back: idBackCaptureAttempts,\n isRealIDCheckRequired: 'false',\n sdkVersion: `WebSDK_${webSdkVersion}`,\n Resolution:\n typeof window !== 'undefined'\n ? `${window.innerWidth} x ${window.innerHeight}`\n : 'unknown',\n }\n const platform = getPlatform()\n if (platform) {\n metadata.os = platform.os?.family\n metadata.osVersion = platform.os?.version\n metadata.browserVersion = `${platform.name} ${platform.version}`\n }\n if (geolocationResult) {\n metadata.GeoLocation = JSON.stringify(geolocationResult)\n }\n request.additionalData.metadata = JSON.stringify(metadata)\n}\n\nexport function videoDataUrlToB64(url: string): Promise<string> {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => {\n resolve(dataUrlToBase64Sync(reader.result as string))\n }\n fetch(url)\n .then((resp) => resp.blob())\n .then((blob) => reader.readAsDataURL(blob))\n })\n}\n","import React, {\n CSSProperties,\n forwardRef,\n ReactElement,\n ReactNode,\n RefCallback,\n useEffect,\n useState,\n} from 'react'\nimport styled from 'styled-components'\n\nexport const PageContainerDiv = styled.div<{\n $heightOffset?: number\n}>`\n ${(props) =>\n props.theme.isFullscreen === false\n ? ``\n : `\n position: fixed;\n top: 0;\n left: 0;\n width: var(--app-width);\n height: calc(\n var(--app-height) - ${props.$heightOffset ?? 0}px\n );\n overflow-x: hidden;\n overflow-y: auto;\n `}\n\n ${(props) =>\n props.theme.fontFamily ? `font-family: ${props.theme.fontFamily};` : ``}\n\n &.flex {\n display: flex;\n }\n\n &.padded {\n box-sizing: border-box;\n padding: 16px 24px;\n }\n`\n\nexport const PageContainer = forwardRef(\n (\n {\n children,\n className,\n heightOffset = 0,\n style,\n onClick,\n }: {\n ref?: RefCallback<HTMLDivElement>\n children: ReactNode\n className?: string\n heightOffset?: number\n style?: CSSProperties\n onClick?: () => void\n },\n ref: React.ForwardedRef<HTMLDivElement>,\n ): ReactElement => {\n const [dimensionsCalculated, setDimensionsCalculated] = useState(false)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n setDimensionsCalculated(false)\n const calcAppDimensions = () => {\n const doc = document.documentElement\n doc.style.setProperty('--app-width', `${window.innerWidth}px`)\n doc.style.setProperty('--app-height', `${window.innerHeight}px`)\n }\n window.addEventListener('resize', calcAppDimensions)\n calcAppDimensions()\n setDimensionsCalculated(true)\n\n return () => {\n window.removeEventListener('resize', calcAppDimensions)\n }\n }, [])\n\n return (\n <PageContainerDiv\n ref={ref}\n style={style}\n onClick={onClick}\n className={className}\n $heightOffset={heightOffset}\n >\n {dimensionsCalculated && children}\n </PageContainerDiv>\n )\n },\n)\n\nPageContainer.displayName = 'PageContainer'\n","import styled from 'styled-components'\nimport { PageContainer } from './Page'\n\nexport const OverlayContainer = styled(PageContainer)`\n background: ${(props) =>\n props.theme.background ? `${props.theme.background}` : `white`};\n ${(props) =>\n props.theme.textColor ? `color: ${props.theme.textColor};` : ``}\n z-index: 10000;\n`\n\nexport const OverlayInner = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n max-height: var(--app-height);\n height: 100%;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n`\n\nexport const OverlayImageContainer = styled.div`\n position: relative;\n display: flex;\n flex-grow: 1;\n padding-bottom: 25px;\n max-width: var(--app-width);\n max-height: var(--app-height);\n overflow: hidden;\n\n & > img,\n & > svg {\n margin: 0 auto;\n width: max-content;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: initial;\n object-fit: contain;\n display: block;\n }\n`\n\nexport const OverlayImageRow = styled.div`\n display: flex;\n margin: auto;\n\n & > div {\n max-height: calc(100vh - 320px);\n\n & > img {\n width: 100%;\n max-height: 100%;\n height: auto;\n object-fit: contain;\n }\n }\n`\n","import React, {\n CSSProperties,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { LaddaButton } from 'ladda'\nimport styled from 'styled-components'\n\nexport type LoaderButtonVariant =\n | 'primary'\n | 'secondary'\n | 'positive'\n | 'negative'\n | 'warning'\n\nexport type LoaderButtonColors = {\n backgroundColor?: string\n textColor?: string\n loadingBackgroundColor?: string\n loadingTextColor?: string\n}\n\nexport type LoaderButtonProps = {\n children?: ReactNode\n className?: string\n disabled?: boolean\n finished?: boolean\n colors?: LoaderButtonColors\n onClick?: () => void\n style?: CSSProperties\n variant?: LoaderButtonVariant\n}\n\nexport const LoaderButton = ({\n children,\n className,\n colors = {},\n disabled,\n finished,\n onClick,\n style,\n variant = 'primary',\n}: LoaderButtonProps) => {\n const buttonRef = useRef<HTMLButtonElement | null>(null)\n const laddaRef = useRef<LaddaButton | null>(null)\n const [laddaLoaded, setLaddaLoaded] = useState(false)\n\n useEffect(() => {\n if (laddaLoaded || finished) return\n\n let interval: NodeJS.Timeout\n\n import('ladda').then((Ladda) => {\n if (!buttonRef.current) return\n laddaRef.current = Ladda.create(buttonRef.current)\n laddaRef.current.start()\n setLaddaLoaded(true)\n\n let currentProgress = 0\n interval = setInterval(() => {\n if (currentProgress < 0.9) currentProgress += 0.1\n laddaRef.current?.setProgress(currentProgress)\n }, 250)\n })\n\n return () => {\n laddaRef.current?.remove()\n clearInterval(interval)\n }\n }, [finished, laddaLoaded])\n\n useEffect(() => {\n if (laddaLoaded && finished) laddaRef.current?.stop()\n }, [finished, laddaLoaded])\n\n return (\n <StyledButton\n className={`ladda-button ${className} ${disabled ? 'disabled' : ''}`}\n data-style=\"expand-right\"\n disabled={disabled}\n ref={buttonRef}\n onClick={onClick}\n $backgroundColor={colors.backgroundColor}\n $textColor={colors.textColor}\n $disabledBackgroundColor={colors.loadingBackgroundColor}\n $disabledTextColor={colors.loadingTextColor}\n $variant={variant}\n style={style}\n >\n <span className=\"ladda-label\">{children}</span>\n </StyledButton>\n )\n}\n\nconst StyledButton = styled.button<{\n $backgroundColor?: string\n $textColor?: string\n $disabledBackgroundColor?: string\n $disabledTextColor?: string\n $variant?: LoaderButtonVariant\n}>`\n ${(props) =>\n props.theme.buttons?.style === 'bootstrap' &&\n `\n border-radius: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-transform: none;\n -webkit-appearance: button;\n \n &:not(:disabled),\n &[type='button']:not(:disabled),\n &[type='reset']:not(:disabled),\n &[type='submit']:not(:disabled) {\n cursor: pointer;\n }\n \n &:focus:not(:focus-visible) {\n outline: 0;\n }\n \n --bs-btn-padding-x: 0.75rem;\n --bs-btn-padding-y: 0.375rem;\n --bs-btn-font-family: ;\n --bs-btn-font-size: 1rem;\n --bs-btn-font-weight: 400;\n --bs-btn-line-height: 1.5;\n --bs-btn-color: var(--bs-body-color);\n --bs-btn-bg: transparent;\n --bs-btn-border-width: var(--bs-border-width);\n --bs-btn-border-color: transparent;\n --bs-btn-border-radius: var(--bs-border-radius);\n --bs-btn-hover-border-color: transparent;\n --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 1px 1px rgba(0, 0, 0, 0.075);\n --bs-btn-disabled-opacity: 0.65;\n --bs-btn-focus-box-shadow: 0 0 0 0.25rem\n rgba(var(--bs-btn-focus-shadow-rgb), 0.5);\n display: inline-block;\n padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);\n font-family: var(--bs-btn-font-family);\n font-size: var(--bs-btn-font-size);\n font-weight: var(--bs-btn-font-weight);\n line-height: var(--bs-btn-line-height);\n color: var(--bs-btn-color);\n text-align: center;\n text-decoration: none;\n vertical-align: middle;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);\n border-radius: var(--bs-btn-border-radius);\n background-color: var(--bs-btn-bg);\n //transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,\n // border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n \n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n \n &:hover {\n filter: brightness(1.15);\n }\n \n &:focus-visible {\n color: var(--bs-btn-hover-color);\n background-color: var(--bs-btn-hover-bg);\n border-color: var(--bs-btn-hover-border-color);\n outline: 0;\n box-shadow: var(--bs-btn-focus-box-shadow);\n }\n \n &:disabled,\n &.disabled,\n fieldset:disabled & {\n color: var(--bs-btn-disabled-color);\n pointer-events: none;\n background-color: var(--bs-btn-disabled-bg);\n border-color: var(--bs-btn-disabled-border-color);\n opacity: var(--bs-btn-disabled-opacity);\n }\n \n --bs-btn-color: ${\n props.$textColor ??\n props.theme.buttons?.[props.$variant ?? 'primary']?.textColor ??\n '#fff'\n };\n --bs-btn-bg: ${\n props.$backgroundColor ??\n props.theme.buttons?.[props.$variant ?? 'primary']?.backgroundColor ??\n '#0d6efd'\n };\n --bs-btn-border-color: var(--bs-btn-bg);\n --bs-btn-focus-shadow-rgb: 49, 132, 253;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #0a58ca;\n --bs-btn-active-border-color: #0a53be;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: ${\n props.$disabledTextColor ??\n props.theme.buttons?.loading?.textColor ??\n '#fff'\n };\n --bs-btn-disabled-bg: ${\n props.$disabledBackgroundColor ??\n props.theme.buttons?.loading?.backgroundColor ??\n 'gray'\n };\n --bs-btn-disabled-border-color: ${\n props.$disabledBackgroundColor ?? '#0d6efd'\n };\n \n --bs-btn-padding-y: 14px;\n --bs-btn-padding-x: 1rem;\n --bs-btn-font-size: 18px;\n --bs-btn-border-radius: 4px;\n `}\n\n /*!\n * Ladda\n * http://lab.hakim.se/ladda\n * MIT licensed\n *\n * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n */\n @keyframes ladda-spinner-line-fade {\n 0%,\n 100% {\n opacity: 0.22;\n }\n 1% {\n opacity: 1;\n }\n }\n\n position: relative;\n\n .ladda-spinner {\n position: absolute;\n z-index: 2;\n display: inline-block;\n width: 32px;\n top: 50%;\n margin-top: 0;\n opacity: 0;\n pointer-events: none;\n }\n .ladda-label {\n position: relative;\n z-index: 3;\n }\n .ladda-progress {\n position: absolute;\n width: 0;\n height: 100%;\n left: 0;\n top: 0;\n background: rgba(0, 0, 0, 0.2);\n display: none;\n transition: 0.1s linear all !important;\n }\n &[data-loading] .ladda-progress {\n display: block;\n }\n\n transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;\n\n .ladda-spinner,\n .ladda-label {\n transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;\n }\n &[data-style='zoom-in'],\n &[data-style='zoom-in'] .ladda-spinner,\n &[data-style='zoom-in'] .ladda-label,\n &[data-style='zoom-out'],\n &[data-style='zoom-out'] .ladda-spinner,\n &[data-style='zoom-out'] .ladda-label {\n transition: 0.3s ease all !important;\n }\n &[data-style='expand-right'] .ladda-spinner {\n right: -6px;\n }\n &[data-style='expand-right'][data-size='s'] .ladda-spinner,\n &[data-style='expand-right'][data-size='xs'] .ladda-spinner {\n right: -12px;\n }\n &[data-style='expand-right'][data-loading] {\n padding-right: 56px;\n }\n &[data-style='expand-right'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-right'][data-loading][data-size='s'],\n &[data-style='expand-right'][data-loading][data-size='xs'] {\n padding-right: 40px;\n }\n &[data-style='expand-left'] .ladda-spinner {\n left: 26px;\n }\n &[data-style='expand-left'][data-size='s'] .ladda-spinner,\n &[data-style='expand-left'][data-size='xs'] .ladda-spinner {\n left: 4px;\n }\n &[data-style='expand-left'][data-loading] {\n padding-left: 56px;\n }\n &[data-style='expand-left'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-left'][data-loading][data-size='s'],\n &[data-style='expand-left'][data-loading][data-size='xs'] {\n padding-left: 40px;\n }\n &[data-style='expand-up'] {\n overflow: hidden;\n }\n &[data-style='expand-up'] .ladda-spinner {\n top: -32px;\n left: 50%;\n margin-left: 0;\n }\n &[data-style='expand-up'][data-loading] {\n padding-top: 54px;\n }\n &[data-style='expand-up'][data-loading] .ladda-spinner {\n opacity: 1;\n top: 26px;\n margin-top: 0;\n }\n &[data-style='expand-up'][data-loading][data-size='s'],\n &[data-style='expand-up'][data-loading][data-size='xs'] {\n padding-top: 32px;\n }\n &[data-style='expand-up'][data-loading][data-size='s'] .ladda-spinner,\n &[data-style='expand-up'][data-loading][data-size='xs'] .ladda-spinner {\n top: 4px;\n }\n &[data-style='expand-down'] {\n overflow: hidden;\n }\n &[data-style='expand-down'] .ladda-spinner {\n top: 62px;\n left: 50%;\n margin-left: 0;\n }\n &[data-style='expand-down'][data-size='s'] .ladda-spinner,\n &[data-style='expand-down'][data-size='xs'] .ladda-spinner {\n top: 40px;\n }\n &[data-style='expand-down'][data-loading] {\n padding-bottom: 54px;\n }\n &[data-style='expand-down'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-down'][data-loading][data-size='s'],\n &[data-style='expand-down'][data-loading][data-size='xs'] {\n padding-bottom: 32px;\n }\n &[data-style='slide-left'] {\n overflow: hidden;\n }\n &[data-style='slide-left'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-left'] .ladda-spinner {\n left: 100%;\n margin-left: 0;\n }\n &[data-style='slide-left'][data-loading] .ladda-label {\n opacity: 0;\n left: -100%;\n }\n &[data-style='slide-left'][data-loading] .ladda-spinner {\n opacity: 1;\n left: 50%;\n }\n &[data-style='slide-right'] {\n overflow: hidden;\n }\n &[data-style='slide-right'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-right'] .ladda-spinner {\n right: 100%;\n margin-left: 0;\n left: 16px;\n }\n [dir='rtl'] &[data-style='slide-right'] .ladda-spinner {\n right: auto;\n }\n &[data-style='slide-right'][data-loading] .ladda-label {\n opacity: 0;\n left: 100%;\n }\n &[data-style='slide-right'][data-loading] .ladda-spinner {\n opacity: 1;\n left: 50%;\n }\n &[data-style='slide-up'] {\n overflow: hidden;\n }\n &[data-style='slide-up'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-up'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n margin-top: 1em;\n }\n &[data-style='slide-up'][data-loading] .ladda-label {\n opacity: 0;\n top: -1em;\n }\n &[data-style='slide-up'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-top: 0;\n }\n &[data-style='slide-down'] {\n overflow: hidden;\n }\n &[data-style='slide-down'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-down'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n margin-top: -2em;\n }\n &[data-style='slide-down'][data-loading] .ladda-label {\n opacity: 0;\n top: 1em;\n }\n &[data-style='slide-down'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-top: 0;\n }\n &[data-style='zoom-out'] {\n overflow: hidden;\n }\n &[data-style='zoom-out'] .ladda-spinner {\n left: 50%;\n margin-left: 32px;\n transform: scale(2.5);\n }\n &[data-style='zoom-out'] .ladda-label {\n position: relative;\n display: inline-block;\n }\n &[data-style='zoom-out'][data-loading] .ladda-label {\n opacity: 0;\n transform: scale(0.5);\n }\n &[data-style='zoom-out'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-left: 0;\n transform: none;\n }\n &[data-style='zoom-in'] {\n overflow: hidden;\n }\n &[data-style='zoom-in'] .ladda-spinner {\n left: 50%;\n margin-left: -16px;\n transform: scale(0.2);\n }\n &[data-style='zoom-in'] .ladda-label {\n position: relative;\n display: inline-block;\n }\n &[data-style='zoom-in'][data-loading] .ladda-label {\n opacity: 0;\n transform: scale(2.2);\n }\n &[data-style='zoom-in'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-left: 0;\n transform: none;\n }\n &[data-style='contract'] {\n overflow: hidden;\n width: 100px;\n }\n &[data-style='contract'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n }\n &[data-style='contract'][data-loading] {\n border-radius: 50%;\n width: 52px;\n }\n &[data-style='contract'][data-loading] .ladda-label {\n opacity: 0;\n }\n &[data-style='contract'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='contract-overlay'] {\n overflow: hidden;\n width: 100px;\n box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0, 0);\n }\n &[data-style='contract-overlay'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n }\n &[data-style='contract-overlay'][data-loading] {\n border-radius: 50%;\n width: 52px;\n box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0, 0.8);\n }\n &[data-style='contract-overlay'][data-loading] .ladda-label {\n opacity: 0;\n }\n &[data-style='contract-overlay'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n [dir='rtl'] .ladda-spinner > div {\n left: 25% !important;\n }\n`\n","import React, { ReactElement, useContext } from 'react'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { useTranslation } from 'react-i18next'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { SubmissionContext } from './SubmissionProvider'\n\nexport type GeolocationAccessDeniedOverlayProps = {\n accessBlockedImageUrl?: string\n}\n\nexport const GeolocationAccessDeniedOverlay = ({\n accessBlockedImageUrl,\n}: GeolocationAccessDeniedOverlayProps): ReactElement => {\n const { t } = useTranslation()\n const { retryLocationAccess } = useContext(SubmissionContext)\n\n return (\n <OverlayContainer>\n <div style={{ display: 'flex', height: '100%' }}>\n <OverlayInner style={{ maxWidth: 500, height: 'auto', margin: 'auto' }}>\n <OverlayImageContainer style={{ flexGrow: 0 }}>\n <img src={accessBlockedImageUrl} alt={''} />\n </OverlayImageContainer>\n\n <h3>{t('Your location access is disabled')}</h3>\n <p style={{ lineHeight: 1.5, marginBottom: 50 }}>\n {t(\n 'This application requires access to your location to continue. ' +\n 'Please accept the permission once prompted by the browser. ' +\n 'If the browser does not prompt for location permissions, you must go to settings ' +\n 'and provide location access to the current browser.',\n )}\n </p>\n\n <LoaderButton\n variant=\"primary\"\n onClick={retryLocationAccess}\n style={{ width: 200, marginLeft: 'auto', marginRight: 'auto' }}\n finished\n >\n {t('Retry')}\n </LoaderButton>\n </OverlayInner>\n </div>\n </OverlayContainer>\n )\n}\n","import { SubmissionResponseStatus } from '../../contexts/SubmissionContext'\n\nexport class SubmissionError extends Error {\n constructor(public status: SubmissionResponseStatus) {\n super(status.statusMessage)\n }\n}\n\nexport class NetworkError extends Error {}\n\nexport class SessionValidationFailedError extends Error {\n constructor(\n public err: Error,\n public host: string,\n ) {\n super(err.message)\n }\n}\n","import React, { ReactElement } from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { NetworkError, SubmissionError } from './Errors'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslation } from 'react-i18next'\n\nexport type SubmissionErrorOverlayProps = {\n error: SubmissionError | NetworkError\n onRetry?: () => void\n}\n\nexport const SubmissionErrorOverlay = ({\n error,\n onRetry,\n}: SubmissionErrorOverlayProps): ReactElement => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n {error instanceof NetworkError ? (\n <NetworkErrorContent error={error} onRetry={onRetry} />\n ) : (\n <SubmissionErrorContent error={error} />\n )}\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst SubmissionErrorContent = ({ error }: { error: SubmissionError }) => {\n const { t } = useTranslation()\n\n const headingText = t(`We're sorry, an unexpected error has occurred.`)\n\n return (\n <>\n <h3 style={{ marginBottom: 8 }}>{headingText}</h3>\n {error.status.statusCode && (\n <p style={{ marginBottom: 0 }}>\n <code>Status: {error.status.statusCode}</code>\n </p>\n )}\n <p style={{ marginBottom: 0 }}>\n Message: <code>{error.message}</code>\n </p>\n {error.status.errorData && (\n <p style={{ marginBottom: 0 }}>\n Data: <code>{error.status.errorData}</code>\n </p>\n )}\n </>\n )\n}\n\nconst NetworkErrorContent = ({\n onRetry,\n}: {\n error: NetworkError\n onRetry?: () => void\n}) => {\n const { t } = useTranslation()\n const headingText = t('Network unreachable')\n const messageText = t(\n `We're having trouble reaching our services, please check your connection and try again.`,\n )\n const retryText = t('Retry')\n\n return (\n <>\n <h3 style={{ marginBottom: 8 }}>{headingText}</h3>\n <p style={{ marginBottom: 0 }}>{messageText}</p>\n\n {onRetry && (\n <div style={{ marginTop: 32 }}>\n <LoaderButton variant=\"warning\" finished onClick={onRetry}>\n {retryText}\n </LoaderButton>\n </div>\n )}\n </>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const SessionIdMissingOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>sessionId</code> is missing.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const SessionValidationFailedOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>sessionId</code> is not valid.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const AuthUrlNotAllowedOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>authUrl</code> comes from an unrecognized\n issuer.\n </p>\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n Ensure you are generating a fresh session for each request to the\n IDmission WebSDK.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { SessionValidationFailedError } from './Errors'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslation } from 'react-i18next'\n\nexport const SessionValidationErrorOverlay = ({\n error,\n onRetry,\n}: {\n error: SessionValidationFailedError | null\n onRetry?: () => void\n}) => {\n const { t } = useTranslation()\n const retryText = t('Retry')\n\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n {error?.host ? (\n <>\n Failed to reach <code>{error.host}</code>.\n </>\n ) : (\n <>\n Failed to validate <code>sessionId</code>.\n </>\n )}\n </p>\n {error?.message && (\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n <code>{error.message}</code>\n </p>\n )}\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n Please ensure that IDmission's servers can be reached. If you\n believe you have reached this page in error, please contact us at{' '}\n <a href=\"mailto:support@idmission.com\">support@idmission.com</a>.\n </p>\n\n {onRetry && (\n <div style={{ marginTop: 32 }}>\n <LoaderButton variant=\"warning\" finished onClick={onRetry}>\n {retryText}\n </LoaderButton>\n </div>\n )}\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import styled from 'styled-components'\n\nexport const Spinner = styled.div<{\n $size?: number\n $thickness?: number\n $color?: string\n}>`\n display: inline-block;\n width: ${({ $size }) => $size ?? 80}px;\n height: ${({ $size }) => $size ?? 80}px;\n margin: auto;\n\n &:after {\n content: ' ';\n display: block;\n width: ${({ $size }) => ($size ?? 80) - 16}px;\n height: ${({ $size }) => ($size ?? 80) - 16}px;\n margin: 8px;\n border-radius: 50%;\n border: ${({ $thickness }) => $thickness ?? 6}px solid\n ${({ $color }) => $color ?? '#888'};\n border-color: ${({ $color }) => $color ?? '#888'} transparent\n ${({ $color }) => $color ?? '#888'} transparent;\n animation: lds-dual-ring 1.2s linear infinite;\n box-sizing: content-box;\n }\n\n @keyframes lds-dual-ring {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n`\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useContext,\n useEffect,\n useReducer,\n} from 'react'\nimport { SessionValidationFailedError } from '../components/submission/Errors'\nimport { SessionIdMissingOverlay } from '../components/submission/SessionIdMissingOverlay'\nimport { SessionValidationFailedOverlay } from '../components/submission/SessionValidationFailedOverlay'\nimport { AuthUrlNotAllowedOverlay } from '../components/submission/AuthUrlNotAllowedOverlay'\nimport { SessionValidationErrorOverlay } from '../components/submission/SessionValidationErrorOverlay'\nimport { PageContainer } from '../components/common/Page'\nimport { Spinner } from '../components/common/spinner'\n\nexport const defaultAuthUrl = 'https://portal-api.idmission.com'\nexport const allowedAuthUrls = [\n 'https://portal-api.idmission.com',\n 'https://portal-api-uat.idmission.com',\n 'https://portal-api-demo.idmission.com',\n 'https://portal-api-dev.idmission.com',\n 'http://localhost:10000',\n]\n\nexport type SessionCheckState =\n | 'READY'\n | 'RUNNING'\n | 'PASSED'\n | 'FAILED'\n | 'MISSING'\n | 'AUTH_URL_NOT_ALLOWED'\n | 'ERROR'\n\nexport type AuthState = {\n authUrl: string\n sessionCheckState: SessionCheckState\n sessionId?: string\n authError?: SessionValidationFailedError\n}\n\nconst initialState = {\n authUrl: defaultAuthUrl,\n sessionCheckState: 'READY',\n} satisfies AuthState\n\nexport const AuthStateContext = createContext<AuthState>(initialState)\n\nexport type AuthAction =\n | {\n type: 'setSessionId'\n payload: string\n }\n | { type: 'setCheckState'; payload: SessionCheckState }\n | {\n type: 'setError'\n payload: SessionValidationFailedError\n }\n | { type: 'retry' }\n\nexport type AuthDispatch = Dispatch<AuthAction>\n\nexport const AuthDispatchContext = createContext<AuthDispatch>(() => {})\n\nconst reducer = (state: AuthState, action: AuthAction): AuthState => {\n switch (action.type) {\n case 'setSessionId':\n return { ...state, sessionId: action.payload }\n\n case 'setCheckState':\n return { ...state, sessionCheckState: action.payload }\n\n case 'setError':\n return { ...state, sessionCheckState: 'ERROR', authError: action.payload }\n\n case 'retry':\n return {\n ...state,\n sessionCheckState: 'READY',\n authError: undefined,\n sessionId: undefined,\n }\n\n default:\n return state\n }\n}\n\nexport function useAuthReducer(\n authUrl = defaultAuthUrl,\n sessionId?: string | (() => Promise<string>),\n): [AuthState, AuthDispatch] {\n const [state, dispatch] = useReducer(reducer, { ...initialState, authUrl })\n const { sessionId: resolvedSessionId, sessionCheckState } = state\n\n useEffect(() => {\n if (!allowedAuthUrls.includes(authUrl))\n return dispatch({\n type: 'setCheckState',\n payload: 'AUTH_URL_NOT_ALLOWED',\n })\n }, [authUrl])\n\n useEffect(() => {\n if (sessionCheckState !== 'READY') return\n\n if (!resolvedSessionId) {\n if (!sessionId)\n return dispatch({ type: 'setCheckState', payload: 'MISSING' })\n\n if (typeof sessionId === 'string')\n return dispatch({ type: 'setSessionId', payload: sessionId })\n\n if (sessionId instanceof Function) {\n sessionId()\n .then((sessionId) => {\n dispatch({ type: 'setSessionId', payload: sessionId })\n })\n .catch((e) => {\n console.error('failed to resolve session id', e)\n dispatch({\n type: 'setError',\n payload: new SessionValidationFailedError(e, authUrl),\n })\n })\n }\n } else {\n dispatch({ type: 'setCheckState', payload: 'RUNNING' })\n ;(async () => {\n try {\n const resp = await fetch(\n `${authUrl}/portal.sessions.v1.SessionsService/ValidateSession`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id: resolvedSessionId }),\n },\n )\n const { valid } = await resp.json()\n dispatch({\n type: 'setCheckState',\n payload: valid ? 'PASSED' : 'FAILED',\n })\n } catch (e) {\n dispatch({\n type: 'setError',\n payload: new SessionValidationFailedError(e as Error, authUrl),\n })\n }\n })()\n }\n }, [authUrl, sessionCheckState, resolvedSessionId, sessionId])\n\n return [state, dispatch]\n}\n\nexport function useAuthContext(): [AuthState, AuthDispatch] {\n const state = useContext(AuthStateContext)\n const dispatch = useContext(AuthDispatchContext)\n if (!state || !dispatch)\n throw new Error('useAuthContext cannot be used without AuthStateProvider')\n\n return [state, dispatch]\n}\n\nexport function AuthProvider({\n authUrl = defaultAuthUrl,\n sessionId,\n children,\n}: {\n authUrl?: string\n sessionId: string | (() => Promise<string>)\n children: ReactNode\n}) {\n const [state, dispatch] = useAuthReducer(authUrl, sessionId)\n\n if (state.sessionCheckState === 'MISSING') {\n return <SessionIdMissingOverlay />\n }\n\n if (state.sessionCheckState === 'FAILED') {\n return <SessionValidationFailedOverlay />\n }\n\n if (state.sessionCheckState === 'AUTH_URL_NOT_ALLOWED') {\n return <AuthUrlNotAllowedOverlay />\n }\n\n if (state.sessionCheckState === 'ERROR') {\n return (\n <SessionValidationErrorOverlay\n error={state.authError!}\n onRetry={() => dispatch({ type: 'retry' })}\n />\n )\n }\n\n if (\n state.sessionCheckState === 'READY' ||\n state.sessionCheckState === 'RUNNING'\n )\n return (\n <PageContainer className=\"flex\">\n <Spinner />\n </PageContainer>\n )\n\n return (\n <AuthStateContext.Provider value={state}>\n <AuthDispatchContext.Provider value={dispatch}>\n {children}\n </AuthDispatchContext.Provider>\n </AuthStateContext.Provider>\n )\n}\n","import { useEffect } from 'react'\n\nexport enum LogLevel {\n Off,\n Error,\n Warn,\n Info,\n Debug,\n}\n\nlet logLevel: LogLevel = LogLevel.Warn\n\nexport function useLogLevel(newLogLevel: LogLevel) {\n useEffect(() => {\n const oldLogLevel = logLevel\n if (newLogLevel === oldLogLevel) return\n logLevel = newLogLevel\n return () => {\n logLevel = oldLogLevel\n }\n }, [newLogLevel])\n}\n\nexport function useDebugLogging(enabled: boolean) {\n useLogLevel(enabled ? LogLevel.Debug : logLevel)\n}\n\nexport function debug(...parts: unknown[]) {\n if (logLevel < LogLevel.Debug) return\n console.debug(...parts) // eslint-disable-line\n}\n\nexport function log(...parts: unknown[]) {\n if (logLevel < LogLevel.Info) return\n console.log(...parts) // eslint-disable-line\n}\n\nexport function warn(...parts: unknown[]) {\n if (logLevel < LogLevel.Warn) return\n console.warn(...parts) // eslint-disable-line\n}\n\nexport function error(...parts: unknown[]) {\n if (logLevel < LogLevel.Error) return\n console.error(...parts) // eslint-disable-line\n}\n\nexport function time(label?: string) {\n if (logLevel < LogLevel.Info) return\n console.time(label) // eslint-disable-line\n}\n\nexport function timeEnd(label?: string) {\n if (logLevel < LogLevel.Info) return\n console.timeEnd(label) // eslint-disable-line\n}\n\nexport default log\n","import React, {\n createContext,\n ReactElement,\n useCallback,\n useEffect,\n useState,\n} from 'react'\nimport {\n apiHeaders,\n attachMetadataToRequest,\n CaptureAttemptMetadata,\n CardData,\n determineSubmissionEndpoint,\n determineSubmissionHost,\n liveCheckEndpoint,\n LiveCheckResponse,\n LivenessCheckRequest,\n PersonalData,\n SubmissionAction,\n SubmissionEnvironment,\n SubmissionRequest,\n SubmissionResponse,\n SubmissionStatus,\n videoDataUrlToB64,\n} from '../../contexts/SubmissionContext'\nimport {\n blobToB64,\n dataUrlToBase64,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport { UploadedDocument } from '../additional_document_capture/AdditionalDocumentCapture'\nimport { SignatureData } from '../signature_capture/data'\nimport { GeolocationAccessDeniedOverlay } from './GeolocationAccessDeniedOverlay'\nimport { SubmissionErrorOverlay } from './SubmissionErrorOverlay'\nimport { NetworkError, SubmissionError } from './Errors'\nimport { CapturedDocuments } from '../id_capture/CapturedDocuments'\nimport { useAuthContext } from '../../contexts/AuthStateContext'\nimport { Upload, UploadOptions } from 'tus-js-client'\nimport log from '../../lib/utils/logger'\n\nexport const defaultSubmissionUrl = 'https://portal-api.idmission.com/swagger'\nexport const defaultDocumentServiceUrl =\n 'https://portal-api.idmission.com/files/'\n\nexport type DocumentMetadata = { filename?: string; filetype?: string }\nexport type DocumentUploadProgressEvent = {\n bytesUploaded: number\n bytesTotal: number\n percentage: string\n metadata?: DocumentMetadata\n}\nexport type OnBeforeDocumentUpload = (\n content: Blob,\n metadata?: DocumentMetadata,\n) => Promise<void | false>\nexport type OnDocumentUploadProgress = (\n event: DocumentUploadProgressEvent,\n) => void\nexport type OnDocumentUploaded = (\n documentId: string,\n metadata?: DocumentMetadata,\n) => Promise<void>\nexport type OnDocumentUploadFailed = (\n error: Error,\n metadata?: DocumentMetadata,\n) => void\n\nexport type SubmissionState = {\n submit: () => Promise<SubmissionResponse | null>\n submissionStatus: SubmissionStatus\n submissionRequest: SubmissionRequest | null\n submissionResponse: SubmissionResponse | null\n submissionError: SubmissionError | NetworkError | null\n submissionEnvironment: SubmissionEnvironment\n\n idFrontImage: string | null\n idBackImage: string | null\n passportImage: string | null\n selfieImage: string | null\n signatureData: SignatureData | null\n signatureVideoUrl: string | null\n idCaptureVideoUrl: string | null\n idCaptureVideoIdFrontImage: string | null\n idCaptureVideoIdBackImage: string | null\n idCaptureVideoAudioUrl: string | null\n idCaptureVideoAudioStartsAt: number | null\n additionalDocuments: UploadedDocument[] | null\n\n setIdFrontImage: (image: string) => void\n setIdBackImage: (image: string) => void\n setPassportImage: (image: string) => void\n setSelfieImage: (image: string) => void\n setSignatureData: (signatureData: SignatureData) => void\n setSignatureVideoUrl: (videoDataUrl: string) => void\n setIdCaptureVideoUrl: (videoDataUrl: string) => void\n setIdCaptureVideoIdFrontImage: (image: string) => void\n setIdCaptureVideoIdBackImage: (image: string) => void\n setIdCaptureVideoAudioUrl: (videoDataUrl: string) => void\n setIdCaptureVideoAudioStartsAt: (value: number) => void\n setExpectedAudioText: (value: string) => void\n setAdditionalDocuments: (uploadedDocuments: UploadedDocument[]) => void\n\n uploadDocument: (blob: Blob, metadata?: DocumentMetadata) => Promise<string>\n\n logIdFrontCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n logIdBackCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n logSelfieCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n\n livenessCheckRequest: LivenessCheckRequest | null\n checkLiveness: (imageDataUrl: string) => Promise<LiveCheckResponse>\n\n retryLocationAccess: () => void\n}\n\nexport const SubmissionContext = createContext<SubmissionState>({\n submit: async () => null,\n submissionStatus: SubmissionStatus.READY,\n submissionRequest: null,\n submissionResponse: null,\n submissionError: null,\n submissionEnvironment: 'prod',\n\n idFrontImage: null,\n idBackImage: null,\n passportImage: null,\n selfieImage: null,\n signatureData: null,\n signatureVideoUrl: null,\n idCaptureVideoUrl: null,\n idCaptureVideoIdFrontImage: null,\n idCaptureVideoIdBackImage: null,\n idCaptureVideoAudioUrl: null,\n idCaptureVideoAudioStartsAt: null,\n additionalDocuments: null,\n\n setIdFrontImage: () => null,\n setIdBackImage: () => null,\n setPassportImage: () => null,\n setSelfieImage: () => null,\n setSignatureData: () => null,\n setSignatureVideoUrl: () => null,\n setIdCaptureVideoUrl: () => null,\n setIdCaptureVideoIdFrontImage: () => null,\n setIdCaptureVideoIdBackImage: () => null,\n setIdCaptureVideoAudioUrl: () => null,\n setIdCaptureVideoAudioStartsAt: () => null,\n setExpectedAudioText: () => null,\n setAdditionalDocuments: () => null,\n\n uploadDocument: Promise.resolve,\n\n logIdFrontCaptureAttempt: () => null,\n logIdBackCaptureAttempt: () => null,\n logSelfieCaptureAttempt: () => null,\n\n livenessCheckRequest: null,\n checkLiveness: async () => {\n throw new Error('checkLiveness is not implemented')\n },\n\n retryLocationAccess: () => null,\n})\n\nexport type SubmissionProviderProps = {\n action: SubmissionAction\n children: ReactElement\n submissionUrl?: string\n environment?: SubmissionEnvironment\n companyId?: string\n enrollmentId?: string\n personalData?: PersonalData\n cardData?: CardData\n bypassAgeValidation?: boolean\n bypassNameMatching?: boolean\n needImmediateResponse?: boolean\n manualReviewRequired?: boolean\n idBackImageRequired?: boolean\n idImageResolutionCheck?: boolean\n verifyIdWithExternalDatabases?: boolean\n deduplicationEnabled?: boolean\n deduplicationSynchronous?: boolean\n idCardForFaceMatch?: string\n geolocationEnabled?: boolean\n geolocationRequired?: boolean\n webhooksEnabled?: boolean\n webhooksClientTraceId?: string\n webhooksStripSpecialCharacters?: boolean\n webhooksSendInputImages?: boolean\n webhooksSendProcessedImages?: boolean\n webhooksFireOnReview?: boolean\n precapturedDocuments?: CapturedDocuments\n documentServiceUrl?: string\n sendBase64DocumentsInSwaggerProxy?: boolean\n onSubmit?: (payload: SubmissionRequest) => void\n onBeforeSubmit?: (req: SubmissionRequest) => Promise<SubmissionRequest>\n onBeforeLivenessCheck?: (\n req: LivenessCheckRequest,\n ) => Promise<LivenessCheckRequest>\n onBeforeDocumentUpload?: OnBeforeDocumentUpload\n onDocumentUploadProgress?: OnDocumentUploadProgress\n onDocumentUploaded?: OnDocumentUploaded\n onDocumentUploadFailed?: OnDocumentUploadFailed\n onResponseReceived?: (res: SubmissionResponse, req: SubmissionRequest) => void\n onRequestFailure?: (err: Error) => void\n readTextPrompt?: string // by the time we get to the submission context, the type should have resolved to string\n clientRequestID?: string\n}\n\nexport const SubmissionProvider = ({\n action,\n children,\n submissionUrl = defaultSubmissionUrl,\n environment = 'prod',\n companyId,\n enrollmentId,\n personalData,\n cardData,\n bypassAgeValidation = false,\n bypassNameMatching = true,\n needImmediateResponse = false,\n manualReviewRequired = false,\n idBackImageRequired = true,\n idImageResolutionCheck = true,\n verifyIdWithExternalDatabases = false,\n deduplicationEnabled = false,\n deduplicationSynchronous = false,\n idCardForFaceMatch,\n geolocationEnabled = true,\n geolocationRequired = false,\n webhooksEnabled = false,\n webhooksClientTraceId,\n webhooksStripSpecialCharacters = true,\n webhooksSendInputImages = false,\n webhooksSendProcessedImages = false,\n webhooksFireOnReview = false,\n precapturedDocuments,\n documentServiceUrl = defaultDocumentServiceUrl,\n sendBase64DocumentsInSwaggerProxy = false,\n onSubmit,\n onBeforeSubmit,\n onBeforeLivenessCheck,\n onBeforeDocumentUpload,\n onDocumentUploadProgress,\n onDocumentUploaded,\n onDocumentUploadFailed,\n onResponseReceived,\n onRequestFailure,\n clientRequestID,\n}: SubmissionProviderProps): ReactElement => {\n const [{ sessionId }] = useAuthContext()\n const [submissionStatus, setSubmissionStatus] = useState<SubmissionStatus>(\n SubmissionStatus.READY,\n )\n const [submissionRequest, setSubmissionRequest] =\n useState<SubmissionRequest | null>(null)\n const [submissionResponse, setSubmissionResponse] =\n useState<SubmissionResponse | null>(null)\n const [submissionError, setSubmissionError] = useState<\n SubmissionError | NetworkError | null\n >(null)\n const [retrySubmission, setRetrySubmission] = useState<(() => void) | null>(\n null,\n )\n const [livenessCheckRequest, setLivenessCheckRequest] =\n useState<LivenessCheckRequest | null>(null)\n\n const [idFrontImage, setIdFrontImage] = useState<string | null>(null)\n const [idBackImage, setIdBackImage] = useState<string | null>(null)\n const [passportImage, setPassportImage] = useState<string | null>(null)\n const [selfieImage, setSelfieImage] = useState<string | null>(null)\n const [signatureData, setSignatureData] = useState<SignatureData | null>(null)\n const [signatureVideoUrl, setSignatureVideoUrl] = useState<string | null>(\n null,\n )\n const [idCaptureVideoUrl, setIdCaptureVideoUrl] = useState<string | null>(\n null,\n )\n const [idCaptureVideoIdFrontImage, setIdCaptureVideoIdFrontImage] = useState<\n string | null\n >(null)\n const [idCaptureVideoIdBackImage, setIdCaptureVideoIdBackImage] = useState<\n string | null\n >(null)\n const [idCaptureVideoAudioUrl, setIdCaptureVideoAudioUrl] = useState<\n string | null\n >(null)\n const [idCaptureVideoAudioStartsAt, setIdCaptureVideoAudioStartsAt] =\n useState<number | null>(null)\n const [expectedAudioText, setExpectedAudioText] = useState<string | null>(\n null,\n )\n const [additionalDocuments, setAdditionalDocuments] = useState<\n UploadedDocument[] | null\n >(null)\n\n const [geolocationResult, setGeolocationResult] =\n useState<GeolocationPosition | null>(null)\n const [geolocationAttempts, setGeolocationAttempts] = useState(0)\n const [geolocationBlocked, setGeolocationBlocked] = useState(false)\n\n const [idFrontCaptureAttempts, setIdFrontCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n const [idBackCaptureAttempts, setIdBackCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n const [selfieCaptureAttempts, setSelfieCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n\n const logIdFrontCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setIdFrontCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n const logIdBackCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setIdBackCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n const logSelfieCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setSelfieCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n\n useEffect(() => {\n if (precapturedDocuments?.selfie) {\n setSelfieImage(dataUrlToBase64Sync(precapturedDocuments.selfie.imageData))\n }\n }, [precapturedDocuments?.selfie])\n\n const uploadDocument = useCallback(\n (src: Blob | string, metadata?: DocumentMetadata) =>\n new Promise<string>(async (resolve, reject) => {\n const blob = typeof src === 'string' ? convertBase64ToBlob(src) : src\n if (\n onBeforeDocumentUpload &&\n (await onBeforeDocumentUpload?.(blob, metadata)) === false\n )\n return resolve(blobToB64(blob))\n\n const upload = createUpload(blob, {\n endpoint: documentServiceUrl,\n retryDelays: [0, 1000, 1000, 1000, 3000, 5000, 10000, 20000],\n headers: { 'X-Session-Id': sessionId! },\n metadata: metadata || { filetype: blob.type },\n onProgress(bytesUploaded, bytesTotal) {\n onDocumentUploadProgress?.({\n bytesUploaded,\n bytesTotal,\n percentage: ((bytesUploaded / bytesTotal) * 100).toFixed(2) + '%',\n metadata,\n })\n },\n onSuccess() {\n const documentId =\n 'urn:documentsv1:' +\n upload.url!.split('/files/').pop()?.split('+').shift()\n\n onDocumentUploaded?.(documentId, metadata)\n resolve(documentId)\n },\n onError(error) {\n log('Failed because: ' + error)\n onDocumentUploadFailed?.(error, metadata)\n reject(error)\n },\n })\n\n // Check if there are any previous uploads to continue.\n upload.findPreviousUploads().then(function (previousUploads) {\n // Found previous uploads so we select the first one.\n if (previousUploads.length) {\n upload.resumeFromPreviousUpload(previousUploads[0])\n }\n\n // Start the upload\n upload.start()\n })\n }),\n [\n onBeforeDocumentUpload,\n documentServiceUrl,\n sessionId,\n onDocumentUploadProgress,\n onDocumentUploaded,\n onDocumentUploadFailed,\n ],\n )\n\n const buildSubmissionPayload = useCallback(async () => {\n async function uploadIfPossible(\n src: string,\n filename: string,\n filetype = 'image/jpeg',\n ) {\n if (!documentServiceUrl) return src\n if (!src.startsWith('data:')) src = `data:${filetype};base64,${src}`\n return await uploadDocument(src, { filename, filetype })\n }\n\n const documents: { [key: string]: string | null } = {\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n signatureVideo:\n signatureVideoUrl && (await videoDataUrlToB64(signatureVideoUrl)),\n idCaptureVideo:\n idCaptureVideoUrl && (await videoDataUrlToB64(idCaptureVideoUrl)),\n idCaptureVideoAudio:\n idCaptureVideoAudioUrl &&\n (await videoDataUrlToB64(idCaptureVideoAudioUrl)),\n idCaptureVideoIdFrontImage,\n idCaptureVideoIdBackImage,\n }\n if (signatureData) {\n documents.signatureImage = signatureData?.fileContent\n }\n if (documentServiceUrl) {\n await Promise.all(\n Object.keys(documents).map(async (k) => {\n if (documents[k]) {\n documents[k] = await uploadIfPossible(documents[k]!, k)\n }\n }),\n )\n }\n\n let submissionRequest: SubmissionRequest = {\n securityData: { userName: '', password: '', merchantId: 0 },\n customerData: {\n idData: { idType: 'NSP', idCountry: 'NSP', idState: '' },\n },\n additionalData: {\n uniqueRequestId: new Date().getTime().toString(),\n manualReviewRequired: manualReviewRequired ? 'Y' : 'N',\n bypassAgeValidation: bypassAgeValidation ? 'Y' : 'N',\n bypassNameMatching: bypassNameMatching ? 'Y' : 'N',\n postDataAPIRequired: webhooksEnabled ? 'Y' : 'N',\n postDataOnReviewRequired: webhooksFireOnReview ? 'Y' : 'N',\n sendInputImagesInPost: webhooksSendInputImages ? 'Y' : 'N',\n sendProcessedImagesInPost: webhooksSendProcessedImages ? 'Y' : 'N',\n needImmediateResponse: needImmediateResponse ? 'Y' : 'N',\n deDuplicationRequired: deduplicationEnabled ? 'Y' : 'N',\n deduplicationSynchronous: deduplicationSynchronous ? 'Y' : 'N',\n verifyDataWithHost: verifyIdWithExternalDatabases ? 'Y' : 'N',\n idBackImageRequired: idBackImageRequired ? 'Y' : 'N',\n stripSpecialCharacters: webhooksStripSpecialCharacters ? 'Y' : 'N',\n idImageResolutionCheck: idImageResolutionCheck ? 'Y' : 'N',\n },\n }\n\n if (clientRequestID) {\n submissionRequest.additionalData.clientRequestID = clientRequestID\n }\n if (documents.idFrontImage) {\n submissionRequest.customerData.idData.idImageFront =\n documents.idFrontImage\n }\n if (documents.idBackImage) {\n submissionRequest.customerData.idData.idImageBack = documents.idBackImage\n }\n if (documents.passportImage) {\n submissionRequest.customerData.idData.idImageFront =\n documents.passportImage\n }\n if (documents.selfieImage) {\n // if (action === SubmissionAction.IDENTIFY) {\n // // TODO: remove once API is fixed\n // submissionRequest.biometricData = { selfie: documents.selfieImage }\n // }\n submissionRequest.customerData.biometricData = {\n selfie: documents.selfieImage,\n }\n }\n if (companyId) {\n submissionRequest.employee = { companyId }\n }\n if (personalData) {\n submissionRequest.customerData.personalData = personalData\n }\n if (cardData) {\n submissionRequest.customerData.cardData = cardData\n }\n if (enrollmentId) {\n submissionRequest.customerData.personalData ||= {}\n submissionRequest.customerData.personalData.uniqueNumber = enrollmentId\n }\n if (webhooksClientTraceId) {\n submissionRequest.additionalData.clientTraceId = webhooksClientTraceId\n }\n if (signatureData) {\n submissionRequest.customerData.signatureData = {\n signatureImage: JSON.stringify(signatureData),\n }\n if (documents.signatureVideo) {\n submissionRequest.customerData.signatureData.signatureVideo =\n documents.signatureVideo\n }\n }\n if (additionalDocuments) {\n submissionRequest.customerData.additionalDocuments =\n additionalDocuments.map((d) => ({\n ...d,\n additionalDocument: JSON.stringify({\n ...(d.additionalDocument as Record<string, string>),\n uniqueId: submissionRequest.additionalData.uniqueRequestId,\n }),\n }))\n }\n if (documents.idCaptureVideo) {\n submissionRequest.customerData.biometricData ||= {}\n submissionRequest.customerData.biometricData.videoData =\n documents.idCaptureVideo\n }\n if (documents.idCaptureVideoAudio) {\n submissionRequest.customerData.biometricData ||= {}\n submissionRequest.customerData.biometricData.voiceData =\n documents.idCaptureVideoAudio\n submissionRequest.customerData.biometricData.voiceStartTime =\n idCaptureVideoAudioStartsAt ?? undefined\n submissionRequest.customerData.biometricData.expectedAudioText =\n expectedAudioText ?? undefined\n }\n if (documents.idCaptureVideoIdFrontImage) {\n submissionRequest.customerData.idData.videoIdImageFront =\n documents.idCaptureVideoIdFrontImage\n }\n if (documents.idCaptureVideoIdBackImage) {\n submissionRequest.customerData.idData.videoIdImageBack =\n documents.idCaptureVideoIdBackImage\n }\n\n attachMetadataToRequest(submissionRequest, {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n })\n\n if (onBeforeSubmit) {\n const onBeforeSubmitResult = await onBeforeSubmit(submissionRequest)\n if (onBeforeSubmitResult) submissionRequest = onBeforeSubmitResult\n }\n\n return submissionRequest\n }, [\n action,\n additionalDocuments,\n bypassAgeValidation,\n bypassNameMatching,\n cardData,\n companyId,\n deduplicationEnabled,\n deduplicationSynchronous,\n documentServiceUrl,\n enrollmentId,\n expectedAudioText,\n geolocationResult,\n idBackCaptureAttempts,\n idBackImage,\n idBackImageRequired,\n idCaptureVideoAudioStartsAt,\n idCaptureVideoAudioUrl,\n idCaptureVideoIdBackImage,\n idCaptureVideoIdFrontImage,\n idCaptureVideoUrl,\n idFrontCaptureAttempts,\n idFrontImage,\n idImageResolutionCheck,\n manualReviewRequired,\n needImmediateResponse,\n onBeforeSubmit,\n passportImage,\n personalData,\n selfieCaptureAttempts,\n selfieImage,\n signatureData,\n signatureVideoUrl,\n uploadDocument,\n verifyIdWithExternalDatabases,\n webhooksClientTraceId,\n webhooksEnabled,\n webhooksFireOnReview,\n webhooksSendInputImages,\n webhooksSendProcessedImages,\n webhooksStripSpecialCharacters,\n ])\n\n const defaultOnSubmit = useCallback(async () => {\n if (action === SubmissionAction.NONE) {\n const submissionResponse = {\n status: { statusCode: '000' },\n resultData: {},\n }\n setSubmissionStatus(SubmissionStatus.SUBMITTED)\n setSubmissionResponse(submissionResponse)\n return submissionResponse\n }\n\n setSubmissionStatus(SubmissionStatus.SUBMITTING)\n\n try {\n const payload = await buildSubmissionPayload()\n const host = submissionUrl || determineSubmissionHost(environment)\n const endpoint = determineSubmissionEndpoint(\n action,\n !!(idFrontImage || idBackImage || passportImage),\n !!selfieImage,\n )\n const response = await fetch(host + endpoint, {\n method: 'POST',\n headers: apiHeaders(sessionId, sendBase64DocumentsInSwaggerProxy),\n body: JSON.stringify(payload),\n }).catch((e) => {\n throw new NetworkError(e.message)\n })\n\n if (!response || !response.ok) {\n const statusMessage = await response?.text()\n\n if (!statusMessage || statusMessage === 'Load failed')\n throw new NetworkError(statusMessage)\n\n throw new SubmissionError({\n statusCode: response?.statusText ?? '???',\n statusMessage,\n })\n }\n\n const submissionResponse = await response.json()\n if (submissionResponse.status.statusCode !== '000') {\n throw new SubmissionError(submissionResponse.status)\n }\n\n setSubmissionRequest(payload)\n setSubmissionResponse(submissionResponse)\n setSubmissionStatus(SubmissionStatus.SUBMITTED)\n onResponseReceived?.(submissionResponse, payload)\n return submissionResponse\n } catch (e) {\n const err = e as Error\n setSubmissionStatus(SubmissionStatus.FAILED)\n setSubmissionError(\n e instanceof SubmissionError || e instanceof NetworkError\n ? e\n : err.message === 'Load failed'\n ? new NetworkError()\n : new SubmissionError({\n statusCode: '',\n statusMessage: err.message,\n }),\n )\n setRetrySubmission(() =>\n ['VERIFY', 'IDENTIFY'].includes(action) ? () => null : defaultOnSubmit,\n )\n onRequestFailure?.(err)\n throw err\n }\n }, [\n action,\n buildSubmissionPayload,\n submissionUrl,\n environment,\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n sessionId,\n sendBase64DocumentsInSwaggerProxy,\n onResponseReceived,\n onRequestFailure,\n ])\n\n const submit = useCallback(async () => {\n if (onSubmit) return onSubmit(await buildSubmissionPayload())\n return await defaultOnSubmit()\n }, [buildSubmissionPayload, defaultOnSubmit, onSubmit])\n\n const checkLiveness = useCallback(\n async (imageDataUrl: string) => {\n try {\n let request: LivenessCheckRequest = {\n securityData: { userName: '', password: '', merchantId: 0 },\n customerData: {\n biometricData: { selfie: await dataUrlToBase64(imageDataUrl) },\n },\n additionalData: {\n uniqueRequestId: new Date().getTime().toString(),\n stripSpecialCharacters: webhooksStripSpecialCharacters ? 'Y' : 'N',\n estimateAge: 'N',\n predictGender: 'N',\n },\n }\n\n if (clientRequestID) {\n request.additionalData.clientRequestID = clientRequestID\n }\n\n if (idCardForFaceMatch) {\n request.customerData.idData = { idImageFront: idCardForFaceMatch }\n // TODO: remove when fixed\n request.customerData.additionalData = {\n uniqueRequestId: request.additionalData.uniqueRequestId,\n }\n }\n\n attachMetadataToRequest(request, {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n })\n\n setLivenessCheckRequest(request)\n\n if (onBeforeLivenessCheck) {\n const onBeforeLivenessCheckResult =\n await onBeforeLivenessCheck(request)\n if (onBeforeLivenessCheckResult) request = onBeforeLivenessCheckResult\n }\n\n const host = submissionUrl || determineSubmissionHost(environment)\n const endpoint = liveCheckEndpoint(!!idCardForFaceMatch)\n const response = await fetch(host + endpoint, {\n method: 'POST',\n headers: apiHeaders(sessionId, sendBase64DocumentsInSwaggerProxy),\n body: JSON.stringify(request),\n }).catch((e) => {\n throw new NetworkError(e.message)\n })\n\n if (!response.ok) {\n const statusMessage = await response.text()\n\n if (!statusMessage || statusMessage === 'Load failed')\n throw new NetworkError(statusMessage)\n\n throw new SubmissionError({\n statusCode: response.statusText,\n statusMessage,\n })\n }\n\n const submissionResponse = await response.json()\n if (submissionResponse.status.statusCode !== '000') {\n throw new SubmissionError(submissionResponse.status)\n }\n\n setSubmissionResponse(submissionResponse)\n return submissionResponse\n } catch (e) {\n const err = e as Error\n setSubmissionStatus(SubmissionStatus.FAILED)\n setSubmissionError(\n e instanceof SubmissionError || e instanceof NetworkError\n ? e\n : err.message === 'Load failed'\n ? new NetworkError()\n : new SubmissionError({\n statusCode: '',\n statusMessage: err.message,\n }),\n )\n // the face liveness routine will call again, so don't repeat the call here.\n setRetrySubmission(() => () => null)\n onRequestFailure?.(err)\n throw err\n }\n },\n [\n webhooksStripSpecialCharacters,\n idCardForFaceMatch,\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n onBeforeLivenessCheck,\n submissionUrl,\n environment,\n sessionId,\n onRequestFailure,\n ],\n )\n\n const retryLocationAccess = useCallback(() => {\n setGeolocationAttempts((n) => n + 1)\n }, [])\n\n useEffect(() => {\n if (!geolocationEnabled) return\n\n log('making geolocation attempt', geolocationAttempts)\n navigator.geolocation.getCurrentPosition(\n (position) => {\n setGeolocationResult(position)\n setGeolocationBlocked(false)\n },\n (positionError) => {\n if (positionError.code === 1) {\n setGeolocationBlocked(true)\n } else {\n throw new Error(positionError.message)\n }\n },\n )\n }, [geolocationAttempts, geolocationEnabled, geolocationRequired])\n\n const onRetry = useCallback(() => {\n if (!retrySubmission) return\n setSubmissionError(null)\n setSubmissionStatus(SubmissionStatus.READY)\n retrySubmission()\n }, [retrySubmission])\n\n const value: SubmissionState = {\n submit,\n submissionStatus,\n submissionRequest,\n submissionResponse,\n submissionError,\n submissionEnvironment: environment,\n\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n signatureData,\n signatureVideoUrl,\n idCaptureVideoUrl,\n idCaptureVideoIdFrontImage,\n idCaptureVideoIdBackImage,\n idCaptureVideoAudioUrl,\n idCaptureVideoAudioStartsAt,\n additionalDocuments,\n\n setIdFrontImage,\n setIdBackImage,\n setPassportImage,\n setSelfieImage,\n setSignatureData,\n setSignatureVideoUrl,\n setIdCaptureVideoUrl,\n setIdCaptureVideoIdFrontImage,\n setIdCaptureVideoIdBackImage,\n setIdCaptureVideoAudioUrl,\n setIdCaptureVideoAudioStartsAt,\n setExpectedAudioText,\n setAdditionalDocuments,\n\n uploadDocument,\n\n logIdFrontCaptureAttempt,\n logIdBackCaptureAttempt,\n logSelfieCaptureAttempt,\n\n livenessCheckRequest,\n checkLiveness,\n retryLocationAccess,\n }\n\n return (\n <SubmissionContext.Provider value={value}>\n {geolocationRequired && geolocationBlocked ? (\n <GeolocationAccessDeniedOverlay />\n ) : (\n children\n )}\n\n {submissionError && (\n <SubmissionErrorOverlay error={submissionError} onRetry={onRetry} />\n )}\n </SubmissionContext.Provider>\n )\n}\n\nfunction createUpload(blob: Blob, options: UploadOptions): Upload {\n const UploadType =\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof window.tus !== 'undefined' ? window.tus.Upload : Upload\n\n return new UploadType(blob, options)\n}\n\nfunction convertBase64ToBlob(base64Image: string) {\n // Split into two parts\n const parts = base64Image.split(';base64,')\n\n // Hold the content type\n const imageType = parts[0].split(':')[1]\n\n // Decode Base64 string\n const decodedData = window.atob(parts[1])\n\n // Create UNIT8ARRAY of size same as row data length\n const uInt8Array = new Uint8Array(decodedData.length)\n\n // Insert all character code into uInt8Array\n for (let i = 0; i < decodedData.length; ++i) {\n uInt8Array[i] = decodedData.charCodeAt(i)\n }\n\n // Return BLOB image after conversion\n return new Blob([uInt8Array], { type: imageType })\n}\n","import { getNativeBarcodeReaderResult, PDF417DetectionResult } from './Native'\nimport { getZxingBarcodeReaderResult } from './ZXing'\nimport log from '../utils/logger'\nimport { DetectedObjectBox } from '../models/DocumentDetection'\n\nexport function supportsNativeBarcodeScanning(): boolean {\n return 'BarcodeDetector' in window\n}\n\nexport function scanBarcode(\n blob: Blob,\n box?: DetectedObjectBox,\n): Promise<PDF417DetectionResult | null> {\n return new Promise((resolve) => {\n const image = new Image()\n image.onload = async () => {\n if (supportsNativeBarcodeScanning()) {\n const result = await getNativeBarcodeReaderResult(image)\n log('native result', result, `${image.width}x${image.height}`)\n if (result.length > 0) {\n resolve({ ...result[0], Source: 'native' })\n } else {\n resolve(null)\n }\n } else {\n const shouldRotate = (box?.width ?? 0) < (box?.height ?? 0)\n const result = await getZxingBarcodeReaderResult(image, shouldRotate)\n log('zxing result', result)\n if (result.length > 0) {\n resolve({ ...result[0], Source: 'zxing' })\n } else {\n resolve(null)\n }\n }\n }\n image.src = URL.createObjectURL(blob)\n })\n}\n","export type Frame =\n | ImageBitmap\n | HTMLVideoElement\n | HTMLImageElement\n | HTMLCanvasElement\n\nexport function getFrameDimensions(frame: Frame): [number, number] {\n let frameWidth = frame.width,\n frameHeight = frame.height\n\n if (frame instanceof HTMLImageElement) {\n frameWidth = frame.naturalWidth\n frameHeight = frame.naturalHeight\n }\n\n if (frame instanceof HTMLVideoElement) {\n frameWidth = frame.videoWidth\n frameHeight = frame.videoHeight\n }\n\n return [frameWidth, frameHeight]\n}\n","import styled from 'styled-components'\nimport { Frame, getFrameDimensions } from '../../lib/utils/getFrameDimensions'\n\nexport const InvisibleCanvas = styled.canvas`\n display: none;\n`\n\nexport function drawToCanvas(\n canvas: HTMLCanvasElement | null,\n frame: Frame,\n width?: number,\n height?: number,\n): void {\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n if (!width || !height) {\n const [frameWidth, frameHeight] = getFrameDimensions(frame)\n width ||= frameWidth\n height ||= frameHeight\n }\n canvas.width = width\n canvas.height = height\n ctx.drawImage(frame, 0, 0, width, height)\n}\n\nexport function clearCanvas(canvas: HTMLCanvasElement | null) {\n canvas?.getContext('2d')?.clearRect(0, 0, canvas?.width, canvas?.height)\n}\n","import {\n MutableRefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { getPlatform } from '../utils/platform'\nimport { drawToCanvas } from '../../components/common/InvisibleCanvas'\nimport log, { error } from '../utils/logger'\n\nexport type Camera = {\n stream: MediaStream\n isRearFacing: boolean\n release: () => void\n label: string\n width: number\n height: number\n}\n\nexport type CameraResolution = 'LOW' | 'MID' | 'MAX'\n\nlet choosingCamera = false\n\nexport async function selectAndOpenCamera(\n resolution: CameraResolution = 'MID',\n): Promise<Camera> {\n if (choosingCamera) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (!choosingCamera) {\n clearInterval(interval)\n resolve(null)\n }\n }, 10)\n })\n }\n\n choosingCamera = true\n\n const video: MediaTrackConstraints = {\n facingMode: { ideal: 'environment' },\n focusMode: 'continuous',\n }\n if (resolution === 'LOW') {\n video.width = { ideal: 640 }\n } else if (resolution === 'MID') {\n video.width = { ideal: 1920 }\n }\n\n const stream = await navigator.mediaDevices.getUserMedia({ video })\n let mediaTrackSettings = stream.getVideoTracks()[0].getSettings()\n const camera: Camera = {\n // you only get the labels for each camera if you call getUserMedia first.\n stream,\n isRearFacing: false,\n release: () => {\n camera.stream.getTracks().forEach((track) => track.stop())\n },\n width: mediaTrackSettings.width ?? 0,\n height: mediaTrackSettings.height ?? 0,\n label: '',\n }\n\n let chosenLabel = ''\n let bestResDevice: [string, number, number] = ['', 0, 0]\n const videoDevices = (await navigator.mediaDevices.enumerateDevices()).filter(\n (deviceInfo) => deviceInfo.kind === 'videoinput',\n )\n\n await Promise.all(\n videoDevices.map(async (deviceInfo) => {\n log('checking out', deviceInfo.label, resolution)\n const { width: maxWidth, height: maxHeight } =\n await getVideoDeviceMaxDimensions(deviceInfo)\n log('device', deviceInfo.label, 'max dimensions', {\n maxWidth,\n maxHeight,\n })\n if (maxWidth > bestResDevice[1]) {\n bestResDevice = [deviceInfo.deviceId, maxWidth, maxHeight]\n }\n if (deviceInfo.label) {\n const label = deviceInfo.label.toLocaleLowerCase().split(' ').join('')\n if (\n labelMatches(label, rearLabels) &&\n !labelMatches(label, backUltraWideLabels)\n ) {\n camera.label = label\n camera.isRearFacing = true\n video.deviceId = deviceInfo.deviceId\n chosenLabel = label\n if (resolution === 'MAX') {\n log('going for max!', `${maxWidth}x${maxHeight}`)\n video.width = { exact: maxWidth }\n video.height = { exact: maxHeight }\n }\n }\n }\n }),\n )\n\n if (resolution === 'MAX' && chosenLabel === '') {\n chosenLabel = bestResDevice[0]\n video.deviceId = bestResDevice[0]\n video.width = { ideal: bestResDevice[1] }\n video.height = { ideal: bestResDevice[2] }\n }\n log('chose device', chosenLabel, resolution)\n\n camera.label = chosenLabel\n\n if (video.deviceId) {\n camera.release()\n camera.stream = await navigator.mediaDevices.getUserMedia({ video })\n mediaTrackSettings = camera.stream.getVideoTracks()[0].getSettings()\n camera.width = mediaTrackSettings.width ?? 0\n camera.height = mediaTrackSettings.height ?? 0\n }\n\n log('SETTINGS', camera.stream.getVideoTracks()[0].getSettings())\n\n choosingCamera = false\n return camera\n}\n\n// interface HasCapabilities {\n// getCapabilities?: () => {\n// width: { max: number }\n// height: { max: number }\n// }\n// }\nexport async function getVideoDeviceMaxDimensions(\n deviceInfo: MediaDeviceInfo,\n): Promise<{\n width: number\n height: number\n}> {\n const best = await bestAvailableResolution(deviceInfo)\n if (!best) return { width: 1, height: 1 }\n return { width: best.width, height: best.height }\n // try {\n // const {\n // width: { max: width },\n // height: { max: height },\n // } = (deviceInfo as HasCapabilities).getCapabilities?.() ?? {\n // width: { max: 1920 },\n // height: { max: 1080 },\n // }\n //\n // return { width, height }\n // } catch (e) {\n // error(e)\n // return { width: 1, height: 1 }\n // }\n}\n\ntype Resolution = {\n label: string\n width: number\n height: number\n ratio: string\n}\nexport const quickScan: Resolution[] = [\n // {\n // label: '4K(UHD)',\n // width: 3840,\n // height: 2160,\n // ratio: '16:9',\n // },\n {\n label: '1080p(FHD)',\n width: 1920,\n height: 1080,\n ratio: '16:9',\n },\n {\n label: 'UXGA',\n width: 1600,\n height: 1200,\n ratio: '4:3',\n },\n {\n label: '720p(HD)',\n width: 1280,\n height: 720,\n ratio: '16:9',\n },\n {\n label: 'SVGA',\n width: 800,\n height: 600,\n ratio: '4:3',\n },\n {\n label: 'VGA',\n width: 640,\n height: 480,\n ratio: '4:3',\n },\n {\n label: '360p(nHD)',\n width: 640,\n height: 360,\n ratio: '16:9',\n },\n {\n label: 'CIF',\n width: 352,\n height: 288,\n ratio: '4:3',\n },\n {\n label: 'QVGA',\n width: 320,\n height: 240,\n ratio: '4:3',\n },\n {\n label: 'QCIF',\n width: 176,\n height: 144,\n ratio: '4:3',\n },\n {\n label: 'QQVGA',\n width: 160,\n height: 120,\n ratio: '4:3',\n },\n]\n\nasync function bestAvailableResolution(\n deviceInfo: MediaDeviceInfo,\n): Promise<Resolution | null> {\n for (let i = 0; i !== quickScan.length; ++i) {\n if (await isResolutionAvailable(quickScan[i], deviceInfo)) {\n return quickScan[i]\n }\n }\n\n return null\n}\n\nfunction isResolutionAvailable(\n candidate: Resolution,\n deviceInfo: MediaDeviceInfo,\n): Promise<boolean> {\n return new Promise((resolve) => {\n // const devices = []\n // const deviceInfos = await navigator.mediaDevices.enumerateDevices()\n //\n // for (let i = 0; i !== deviceInfos.length; ++i) {\n // const deviceInfo = deviceInfos[i]\n // if (deviceInfo.kind === 'videoinput') {\n // devices.push(deviceInfo)\n // }\n // }\n\n const video = document.createElement('video')\n const windowWithStream = window as unknown as { stream: MediaStream }\n const existingStream = windowWithStream.stream\n if (existingStream) {\n existingStream.getTracks().forEach((track) => {\n track.stop()\n })\n }\n\n const constraints = {\n audio: false,\n video: {\n deviceId: deviceInfo.deviceId,\n // ? { exact: deviceInfo.deviceId }\n // : undefined,\n width: { exact: candidate.width }, //new syntax\n height: { exact: candidate.height }, //new syntax\n },\n }\n\n setTimeout(\n () => {\n navigator.mediaDevices\n .getUserMedia(constraints)\n .then(gotStream)\n .catch((error) => {\n log('getUserMedia error!', error, candidate)\n resolve(false)\n })\n },\n windowWithStream.stream ? 200 : 0,\n ) //official examples had this at 200\n\n function gotStream(mediaStream: MediaStream) {\n //change the video dimensions\n log(\n 'Display size for ' +\n candidate.label +\n ': ' +\n candidate.width +\n 'x' +\n candidate.height,\n )\n video.width = candidate.width\n video.height = candidate.height\n\n windowWithStream.stream = mediaStream // make globally available\n video.srcObject = mediaStream\n\n resolve(true)\n }\n })\n}\n\nexport type FacingMode = 'user' | 'environment' | 'left' | 'right'\n\nexport async function listAvailableCameras(\n facingMode?: FacingMode,\n requestMicAccess: boolean = false,\n): Promise<MediaDeviceInfo[]> {\n // The first thing we need to do is call getUserMedia() so that the subsequent call to enumerateDevices() works.\n let cameraEnumerationStream: MediaStream | null =\n await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { exact: facingMode } },\n audio: requestMicAccess,\n })\n\n // This lists all available cameras attached to the user's device.\n const videoDevices = (await navigator.mediaDevices.enumerateDevices()).filter(\n ({ kind }) => kind === 'videoinput',\n )\n\n // Release the access to the user's camera that we obtained for enumeration purposes.\n cameraEnumerationStream.getVideoTracks().forEach((track) => {\n track.enabled = false\n track.stop()\n })\n\n cameraEnumerationStream = null\n\n return videoDevices\n}\n\nconst frontLabels = [\n 'front',\n 'avant',\n 'anteriore',\n 'cameraaanvoorzijde',\n 'kamerapåframsidan',\n 'forsidekamera',\n 'kamerapåforsiden',\n 'aparatprzedni',\n 'etukamera',\n 'kameradepan',\n 'ÖnKamera',\n 'cameramặttrước',\n 'camerăfață',\n 'prednákamera',\n 'prednjakamera',\n 'előlapikamera',\n 'přednífotoaparát',\n 'μπροστινήκάμερα',\n 'переднякамера',\n 'передняякамера',\n 'преднакамера',\n 'алдыңғыкамера',\n 'מצלמה קדמית',\n 'الكاميرا الأمامية',\n 'फ़्रंटकैमरा',\n '前置相机',\n '前置鏡頭',\n '前面カメラ',\n '전면카메라',\n 'กล้องด้านหน้า',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\nconst rearLabels = [\n 'back',\n 'rear',\n 'posterior',\n 'trasera',\n 'traseira',\n 'arrière',\n 'rückkamera',\n 'fotocamera(posteriore)',\n 'cameraaanachterzijde',\n 'kamerapåbaksidan',\n 'kamerapåbaksiden',\n 'bagsidekamera',\n 'aparattylny',\n 'takakamera',\n 'arkakamera',\n 'kamerabelakang',\n 'cameramặtsau',\n 'camerăspate',\n 'stražnjakamera',\n 'zadnákamera',\n 'hátoldalikamera',\n 'zadnífotoaparát',\n 'πίσωκάμερα',\n 'заднякамера',\n 'Задняякамера',\n 'заднакамера',\n 'артқыкамера',\n 'מצלמה אחורית',\n 'الكاميرا الخلفية',\n 'बैककैमरा',\n '后置相机',\n '後置鏡頭',\n '背面カメラ',\n '후면카메라',\n 'กล้องด้านหลัง',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\nconst backUltraWideLabels = [\n 'backdualwidecamera',\n 'backultrawidecamera',\n 'ultraampliaposterior',\n 'ultra-angulartraseira',\n 'ultragrandeangulartraseira',\n 'ultragrandangle',\n 'ultragranangular',\n 'ultra-weitwinkelkamera',\n 'ultra-grandangolo',\n 'ultrabredecameraaanachterzijde',\n 'ultravidvinkelkamerapåbaksidan',\n 'ultravidvinkelkameraetpåbagsiden',\n 'ultravidvinkelkamerabak',\n 'ultragenişkameraarkayüzü',\n 'ultralaajakulmainentakakamera',\n 'tylnyaparatultraszerokokątny',\n 'cameracựcrộngmặtsau',\n 'camerăcuobiectivultra‑superangularspate',\n 'ultraszéleslátószögűkamera',\n 'kameraultralebarbelakang',\n 'stražnjaultraširokakamera',\n 'zadníultraširokoúhlýfotoaparát',\n 'ultraširokouhlá',\n 'πίσωυπερευρείακάμερα',\n 'заднянадширококутнакамера',\n 'Задняясверхширокоугольнаякамера',\n 'Задна свръх широкоъгълна камера',\n 'артқыультракеңбұрыштыкамера',\n 'מצלמה אולטרה רחבה אחורית',\n 'كاميرا خلفية عريضة جدًا',\n 'बैकअल्ट्रावाइडकैमरा',\n '后置超广角相机',\n '後置超廣角鏡頭相機',\n '背面超広角カメラ',\n '후면울트라와이드카메라',\n 'กล้องด้านหลังอัลตร้าไวด์',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\n\nconst labelMatches = (\n labelOrDevice: string | MediaDeviceInfo,\n labelSetOrLabel: string | string[],\n) => {\n const label =\n labelOrDevice instanceof MediaDeviceInfo\n ? getDeviceLabel(labelOrDevice)\n : labelOrDevice\n\n const labelSet =\n typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel\n\n return labelSet.some((l) => label.includes(l))\n}\n\nconst getDeviceLabel = (deviceInfo: MediaDeviceInfo) =>\n deviceInfo.label.toLocaleLowerCase().split(' ').join('')\n\nlet currentCamera: Camera | undefined\nlet currentAudioStream: MediaStream | undefined\n\nexport function obtainCameraAccess(\n stream: MediaStream,\n deviceLabel: string,\n video?: HTMLVideoElement | null,\n): Camera {\n releaseCameraAccess()\n\n log('obtaining camera access...')\n let { width, height } = stream.getVideoTracks()[0].getSettings()\n const label = deviceLabel.toLocaleLowerCase().split(' ').join('')\n const isRearFacing = labelMatches(label, [\n ...rearLabels,\n ...backUltraWideLabels,\n 'iphone',\n ])\n const release = () => {\n stream.getTracks().forEach((track) => {\n track.enabled = false\n track.stop()\n })\n if (video) {\n video.pause()\n video.srcObject = null\n video.src = ''\n }\n }\n\n width ||= 0\n height ||= 0\n\n currentCamera = {\n label: deviceLabel,\n stream,\n width,\n height,\n isRearFacing,\n release,\n }\n if (video) video.srcObject = stream\n\n return currentCamera\n}\n\nexport function releaseCameraAccess() {\n if (!currentCamera) return\n log('releasing camera access...')\n currentCamera.release()\n currentCamera = undefined\n}\n\nexport function releaseMicrophoneAccess() {\n if (!currentAudioStream) return\n log('releasing microphone access...')\n currentAudioStream.stop?.()\n currentAudioStream.getAudioTracks().forEach((t) => {\n t.stop?.()\n })\n currentAudioStream = undefined\n}\n\ntype UsePreferredCaptureDeviceParams = {\n requestAccessAutomatically?: boolean\n preferFrontFacingCamera?: boolean\n preferContinuityCamera?: boolean\n requireMicrophoneAccess?: boolean\n maxVideoWidth?: number\n maxFps?: number\n debugMode?: boolean\n}\n\nexport type CaptureDevice = {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n videoDevice: MediaDeviceInfo | null\n videoLoaded: boolean\n setVideoLoaded: (value: boolean) => void\n onVideoUnmounted: (videoElement: HTMLVideoElement) => void\n cameraRef: MutableRefObject<Camera | null>\n cameraReady: boolean\n cameraAccessDenied: boolean\n requestCameraAccess: () => void\n releaseCameraAccess: () => void\n iphoneContinuityCameraAvailable: boolean\n iphoneContinuityCameraAllowed: boolean\n setIphoneContinuityCameraAllowed: (value: boolean) => void\n takePhoto: () => Promise<Blob | null>\n audioStream: MediaStream | null\n microphoneReady: boolean\n microphoneAccessDenied: boolean\n requestMicrophoneAccess: () => void\n}\n\nexport function usePreferredCaptureDevice({\n requestAccessAutomatically = true,\n preferFrontFacingCamera = false,\n preferContinuityCamera = true,\n requireMicrophoneAccess = false,\n maxVideoWidth = 1920,\n maxFps,\n debugMode = false,\n}: UsePreferredCaptureDeviceParams = {}): CaptureDevice {\n const videoRef = useRef<HTMLVideoElement | null>(null)\n const videoRefStack = useRef<HTMLVideoElement[]>([])\n const cameraRef = useRef<Camera | null>(null)\n const [cameraReady, setCameraReady] = useState(false)\n const [microphoneReady, setMicrophoneReady] = useState(false)\n const [videoDevice, setVideoDevice] = useState<MediaDeviceInfo | null>(null)\n const [audioStream, setAudioStream] = useState<MediaStream | null>(null)\n const [videoLoaded, setVideoLoaded] = useState(false)\n const [iphoneContinuityCameraAvailable, setIphoneContinuityCameraAvailable] =\n useState(false)\n const [iphoneContinuityCameraAllowed, setIphoneContinuityCameraAllowed] =\n useState(preferContinuityCamera)\n const [iphoneContinuityCameraDenied, setIphoneContinuityCameraDenied] =\n useState(false)\n const [cameraAccessDenied, setCameraAccessDenied] = useState(false)\n const [microphoneAccessDenied, setMicrophoneAccessDenied] = useState(false)\n\n const videoRefElement = videoRef.current\n useEffect(\n function pushVideoRefToStackWhenChanged() {\n // proceed if the video element being mounted is not already at the top of the videoRefStack.\n const topOfStack = videoRefStack.current.slice(-1)[0]\n if (videoRefElement && videoRefElement !== topOfStack) {\n log('adding video to stack', videoRefElement)\n videoRefStack.current.push(videoRefElement)\n }\n },\n [videoRefElement],\n )\n\n const onVideoUnmounted = useCallback((videoElement: HTMLVideoElement) => {\n log('removing video from stack', videoElement)\n videoRefStack.current = videoRefStack.current.filter(\n (v) => v !== videoElement,\n )\n\n videoRef.current = videoRefStack.current.slice(-1)[0] // top of stack.\n log('new videoRef is', videoRef.current)\n }, [])\n\n useEffect(\n function resetCameraOnContinuityPreferenceChanged() {\n if (debugMode) {\n log(\n 'iphone continuity camera allowed changed',\n iphoneContinuityCameraAllowed,\n )\n }\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n },\n [debugMode, iphoneContinuityCameraAllowed],\n )\n\n // NOTE: the bound callback function here is called requestCameraAccess, because\n // it initiates the useEffect chain that results in camera access being requested\n // (requestCameraAccessAutomatically -> chooseFromAvailableCameras -> accessChosenCamera).\n //\n // We chose to title the inner function \"chooseFromAvailableCameras\" because\n // that's all it literally does -- the available cameras are enumerated, and then\n // the result is parsed to decide which one we like best, which is then passed to\n // setVideoDevice, which causes accessChosenCamera to trigger.\n //\n // I am not a huge fan of getUserMedia's design -- you need to call it twice in order\n // to select the \"best\" camera for your application's purposes.\n const requestCameraAccess = useCallback(\n async function chooseFromAvailableCameras() {\n setCameraReady(false)\n setCameraAccessDenied(false)\n\n try {\n let availableCameras = await listAvailableCameras()\n let selectedCamera: MediaDeviceInfo | undefined\n\n if (debugMode) {\n log('availableCameras', availableCameras)\n }\n\n const platform = getPlatform()\n if (debugMode) {\n log('platformDetails', platform)\n }\n if (\n !iphoneContinuityCameraDenied &&\n (!platform?.os || platform.os.family === 'OS X')\n ) {\n const iphoneContinuityCamera = availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'iphone'),\n )\n setIphoneContinuityCameraAvailable(!!iphoneContinuityCamera)\n if (iphoneContinuityCamera && iphoneContinuityCameraAllowed) {\n selectedCamera = iphoneContinuityCamera\n }\n } else if (\n platform?.os?.family === 'Android' ||\n availableCameras.every((c) => c.label.startsWith('camera2 '))\n ) {\n availableCameras = availableCameras.sort((a, b) =>\n a.label.toLowerCase().localeCompare(b.label.toLowerCase()),\n )\n if (debugMode) {\n log('cameras have been sorted', availableCameras)\n }\n }\n\n if (preferFrontFacingCamera) {\n selectedCamera = availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, frontLabels),\n )\n }\n\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'backtriplecamera'),\n )\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'backdualcamera'),\n )\n selectedCamera ||= availableCameras.find(\n (deviceInfo) =>\n labelMatches(deviceInfo, rearLabels) &&\n !labelMatches(deviceInfo, backUltraWideLabels),\n )\n\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, rearLabels),\n )\n\n // on iOS, the front facing camera always is at the first position in the list, so we skip it if all else fails.\n if (\n !preferFrontFacingCamera &&\n platform?.os?.family === 'iOS' &&\n availableCameras.length > 0\n ) {\n selectedCamera ||= availableCameras[1]\n }\n\n selectedCamera ||= availableCameras[0]\n\n if (debugMode) log('selectedCamera', selectedCamera)\n setVideoDevice(selectedCamera)\n } catch (e) {\n if ((e as { name: string }).name === 'NotAllowedError') {\n error('camera access has been blocked by the user', e)\n setCameraAccessDenied(true)\n } else {\n error('camera access encountered some other error', e)\n throw e\n }\n }\n },\n [\n debugMode,\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraDenied,\n preferFrontFacingCamera,\n ],\n )\n\n useEffect(\n function requestCameraAccessAutomatically() {\n if (requestAccessAutomatically && !cameraAccessDenied) {\n requestCameraAccess().catch(error)\n }\n },\n [cameraAccessDenied, requestAccessAutomatically, requestCameraAccess],\n )\n\n useEffect(\n function accessChosenCamera() {\n if (!videoDevice) return\n\n const cleanup = () => {\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n }\n\n if (!navigator.mediaDevices?.getUserMedia) return cleanup\n ;(async () => {\n const constraints: MediaStreamConstraints = {\n audio: false,\n video: {\n deviceId: { exact: videoDevice.deviceId },\n width: { ideal: maxVideoWidth },\n aspectRatio: 1.777777778,\n frameRate: {},\n } satisfies MediaTrackConstraints,\n }\n\n if (maxFps) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n constraints.video.frameRate = { max: maxFps }\n }\n\n let stream: MediaStream | null = null\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraints)\n } catch (e) {\n if ((e as { name: string }).name === 'NotAllowedError') {\n if (iphoneContinuityCameraAllowed) {\n setIphoneContinuityCameraAvailable(false)\n setIphoneContinuityCameraDenied(true)\n } else {\n setCameraAccessDenied(true)\n }\n return\n }\n }\n\n if (!stream) {\n try {\n stream = await navigator.mediaDevices.getUserMedia({\n audio: false,\n video: true,\n })\n\n log('opened stream with no width and height constraints')\n } catch (e) {\n log('cannot open stream at all')\n }\n }\n\n if (!stream) {\n throw new Error('failed to open camera')\n }\n\n const handleStreamEnded = () => {\n if (\n iphoneContinuityCameraAvailable &&\n iphoneContinuityCameraAllowed\n ) {\n log('someone unplugged the continuity camera')\n releaseCameraAccess()\n cameraRef.current = null\n setIphoneContinuityCameraAvailable(false)\n setIphoneContinuityCameraDenied(true)\n setVideoDevice(null)\n } else {\n log('someone unplugged the webcam')\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n setCameraAccessDenied(true)\n }\n }\n\n videoRef.current?.addEventListener('ended', handleStreamEnded)\n stream.getVideoTracks().forEach((track) => {\n track.onended = handleStreamEnded\n })\n\n cameraRef.current = obtainCameraAccess(\n stream,\n videoDevice.label,\n videoRef.current,\n )\n })()\n\n return cleanup\n },\n [\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraAvailable,\n maxFps,\n maxVideoWidth,\n videoDevice,\n ],\n )\n\n useEffect(\n function triggerCameraReady() {\n // TODO: in the future let's evaluate whether we can simplify this to just\n // setCameraReady(!!videoDevice && videoLoaded) -- we are wondering whether\n // we somehow depend on this being set twice.\n\n setCameraReady(false)\n\n if (videoDevice && videoLoaded) {\n setCameraReady(videoDevice && videoLoaded)\n }\n },\n [videoLoaded, videoDevice],\n )\n\n const requestMicrophoneAccess = useCallback(\n async function _requestMicrophoneAccess() {\n setMicrophoneReady(false)\n setMicrophoneAccessDenied(false)\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n video: false,\n })\n currentAudioStream = stream\n setAudioStream(stream)\n setMicrophoneReady(true)\n\n stream.getAudioTracks().forEach((track) => {\n track.onended = () => {\n setMicrophoneAccessDenied(true)\n }\n })\n } catch (e) {\n setMicrophoneAccessDenied(true)\n }\n },\n [],\n )\n\n useEffect(\n function requestMicrophoneAccessIfNeeded() {\n if (!requireMicrophoneAccess || microphoneAccessDenied) return\n\n requestMicrophoneAccess().catch(error)\n\n return () => {\n releaseMicrophoneAccess()\n setAudioStream(null)\n setMicrophoneReady(false)\n }\n },\n [microphoneAccessDenied, requestMicrophoneAccess, requireMicrophoneAccess],\n )\n\n const takePhoto = useCallback(\n async function _takePhoto(): Promise<Blob | null> {\n if (!cameraRef.current) return null\n if (typeof ImageCapture !== 'undefined') {\n return await new ImageCapture(\n cameraRef.current.stream.getTracks()[0],\n ).takePhoto()\n }\n\n if (!videoRef.current) return null\n const canvas = document.createElement('canvas')\n drawToCanvas(canvas, videoRef.current)\n return new Promise((resolve) => canvas.toBlob(resolve))\n },\n [],\n )\n\n return useMemo<CaptureDevice>(\n () => ({\n videoRef,\n videoDevice,\n videoLoaded,\n setVideoLoaded,\n onVideoUnmounted,\n cameraRef,\n cameraReady,\n cameraAccessDenied,\n requestCameraAccess,\n releaseCameraAccess,\n iphoneContinuityCameraAvailable,\n iphoneContinuityCameraAllowed,\n setIphoneContinuityCameraAllowed,\n takePhoto,\n audioStream,\n microphoneReady,\n microphoneAccessDenied,\n requestMicrophoneAccess,\n }),\n [\n audioStream,\n cameraAccessDenied,\n cameraReady,\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraAvailable,\n microphoneAccessDenied,\n microphoneReady,\n onVideoUnmounted,\n requestCameraAccess,\n requestMicrophoneAccess,\n takePhoto,\n videoDevice,\n videoLoaded,\n ],\n )\n}\n\nexport const useDualResCaptureDevice = () => {\n const {\n videoRef: maxVideoRef,\n videoDevice,\n videoLoaded: maxVideoLoaded,\n setVideoLoaded: setMaxVideoLoaded,\n cameraRef: maxCameraRef,\n cameraReady: maxCameraReady,\n takePhoto: takeFullResPhoto,\n } = usePreferredCaptureDevice()\n\n const minVideoRef = useRef<HTMLVideoElement | null>(null)\n const [minCamera, setMinCamera] = useState<Camera | null>(null)\n const [minVideoLoaded, setMinVideoLoaded] = useState(false)\n\n useEffect(() => {\n if (!videoDevice || !maxCameraRef.current) return\n\n let cam: Camera\n const cleanup = () => {\n cam?.release()\n setMinCamera(null)\n setMinVideoLoaded(false)\n }\n\n if (!minVideoRef.current) return cleanup\n if (!navigator.mediaDevices?.getUserMedia) return cleanup\n ;(async () => {\n if (!maxCameraRef.current) return\n\n let idealWidth = 448\n let idealHeight = 448\n\n if (maxCameraRef.current.width < maxCameraRef.current.height) {\n idealHeight =\n 448 * (maxCameraRef.current.height / maxCameraRef.current.width)\n } else {\n idealWidth =\n 448 * (maxCameraRef.current.width / maxCameraRef.current.height)\n }\n\n log('min dimensions', idealWidth, idealHeight)\n\n const constraints = {\n audio: false,\n video: {\n deviceId: { exact: videoDevice.deviceId },\n width: { ideal: idealWidth },\n height: { ideal: idealHeight },\n },\n }\n\n const stream = await navigator.mediaDevices.getUserMedia(constraints)\n cam = obtainCameraAccess(stream, videoDevice.label, minVideoRef.current)\n setMinCamera(cam)\n })()\n\n return cleanup\n }, [maxCameraRef, videoDevice])\n\n return {\n minVideoRef,\n maxVideoRef,\n minCamera,\n maxCamera: maxCameraRef.current,\n maxCameraReady,\n minVideoLoaded,\n maxVideoLoaded,\n setMinVideoLoaded,\n setMaxVideoLoaded,\n takeFullResPhoto,\n }\n}\n","import React, { createContext, ReactElement, useEffect } from 'react'\nimport {\n CaptureDevice,\n usePreferredCaptureDevice,\n} from '../../lib/camera/Camera'\n\nexport const CameraStateContext = createContext<CaptureDevice>({\n videoRef: { current: null },\n videoDevice: null,\n videoLoaded: false,\n cameraRef: { current: null },\n cameraReady: false,\n cameraAccessDenied: false,\n requestCameraAccess: () => null,\n releaseCameraAccess: () => null,\n iphoneContinuityCameraAvailable: false,\n iphoneContinuityCameraAllowed: true,\n setIphoneContinuityCameraAllowed: () => null,\n takePhoto: () => Promise.resolve(null),\n setVideoLoaded: () => null,\n onVideoUnmounted: () => null,\n audioStream: null,\n microphoneReady: false,\n microphoneAccessDenied: false,\n requestMicrophoneAccess: () => null,\n})\n\nexport type CameraProviderProps = {\n children: ReactElement\n requestAccessAutomatically?: boolean\n preferFrontFacingCamera?: boolean\n preferContinuityCamera?: boolean\n requireMicrophoneAccess?: boolean\n maxVideoWidth?: number\n maxFps?: number\n onCameraAccessDenied?: () => void\n onMicrophoneAccessDenied?: () => void\n debugMode?: boolean\n}\n\nexport const CameraProvider = ({\n children,\n requestAccessAutomatically = true,\n preferFrontFacingCamera = false,\n preferContinuityCamera = true,\n requireMicrophoneAccess = false,\n maxVideoWidth = 1920,\n maxFps,\n onCameraAccessDenied,\n onMicrophoneAccessDenied,\n debugMode = false,\n}: CameraProviderProps): ReactElement => {\n const captureDevice = usePreferredCaptureDevice({\n requestAccessAutomatically,\n preferFrontFacingCamera,\n preferContinuityCamera,\n requireMicrophoneAccess,\n maxVideoWidth,\n maxFps,\n debugMode,\n })\n\n useEffect(() => {\n if (captureDevice.cameraAccessDenied) onCameraAccessDenied?.()\n }, [captureDevice.cameraAccessDenied, onCameraAccessDenied])\n\n useEffect(() => {\n if (captureDevice.microphoneAccessDenied) onMicrophoneAccessDenied?.()\n }, [captureDevice.microphoneAccessDenied, onMicrophoneAccessDenied])\n\n const releaseCameraAccess = captureDevice.releaseCameraAccess\n\n useEffect(() => {\n return () => {\n releaseCameraAccess()\n }\n }, [releaseCameraAccess])\n\n return (\n <CameraStateContext.Provider value={captureDevice}>\n {children}\n </CameraStateContext.Provider>\n )\n}\n","import {\n preloadDependency,\n progressByUseCase,\n sumUpProgressForDependencies,\n} from './preloadModels'\n\nexport const visionTasksBasePath = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.7/wasm`\n\nlet visionRuntimePreloading = false\n\nexport async function preloadVisionRuntime(): Promise<void> {\n if (visionRuntimePreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!visionRuntimePreloading) resolve()\n }, 100)\n })\n\n visionRuntimePreloading = true\n\n const url = `${visionTasksBasePath}/vision_wasm_internal.wasm`\n\n function handleDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (detail.url !== url) return\n progressByUseCase.visionRuntime = sumUpProgressForDependencies([url])\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.visionRuntime', {\n detail: progressByUseCase.visionRuntime,\n }),\n )\n }\n\n document.addEventListener('idmission.preloadProgress', handleDownloadProgress)\n\n try {\n await preloadDependency(url)\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleDownloadProgress,\n )\n visionRuntimePreloading = false\n }\n}\n","function _isNavigatorDefined() {\n return typeof navigator !== 'undefined' && navigator != null\n}\n\nexport function isMobile(nav?: Navigator) {\n if (nav || _isNavigatorDefined()) {\n if (!nav) {\n nav = navigator\n }\n if (nav.product === 'ReactNative') {\n return true\n }\n const a =\n nav.userAgent ||\n nav.vendor ||\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (typeof window !== 'undefined' ? window.opera : '')\n if (!a) {\n const navAny = nav\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return navAny.userAgentData && navAny.userAgentData.mobile\n }\n return (\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n a,\n ) ||\n // tslint:disable-next-line:max-line-length\n /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n a.substr(0, 4),\n )\n )\n }\n return false\n}\n","import { Frame } from './getFrameDimensions'\nimport { clearCanvas } from '../../components/common/InvisibleCanvas'\nimport { isMobile } from './isMobile'\nimport { DetectedObjectBox } from '../models/DocumentDetection'\nimport { Face } from '../models/FaceDetection'\n\nexport function cropToShoulders(\n rawCanvas: HTMLCanvasElement | null,\n cropCanvas: HTMLCanvasElement | null,\n frame: ImageData,\n face: Face,\n): string {\n if (!rawCanvas || !cropCanvas) return ''\n\n const rawCtx = rawCanvas.getContext('2d')\n const cropCtx = cropCanvas.getContext('2d')\n if (!rawCtx || !cropCtx) throw new Error('could not get 2d context')\n\n rawCanvas.width = frame.width\n rawCanvas.height = frame.height\n rawCtx.putImageData(frame, 0, 0)\n\n const { xMin, width } = face.box\n const frameHeight = frame.height\n const xPadding = frameHeight * 0.6 - width\n const xPos = Math.max(0, xMin - xPadding / 2)\n if (isMobile()) {\n cropCanvas.width = frame.width\n cropCanvas.height = frame.height\n cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height)\n } else {\n cropCanvas.width = width + xPadding\n cropCanvas.height = frame.height\n cropCtx.drawImage(\n rawCanvas,\n xPos,\n 0,\n cropCanvas.width,\n cropCanvas.height,\n 0,\n 0,\n cropCanvas.width,\n cropCanvas.height,\n )\n }\n\n const dataURL = cropCanvas.toDataURL('image/jpeg', 0.92)\n\n clearCanvas(rawCanvas)\n clearCanvas(cropCanvas)\n\n return dataURL\n}\n\nexport function cropToDetectedObjectBox(\n frame: Frame,\n box: DetectedObjectBox,\n canvas?: HTMLCanvasElement,\n): HTMLCanvasElement {\n canvas ||= document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n if (!ctx) throw new Error('could not get 2d context')\n\n const { xMin, yMin, width, height } = box\n canvas.width = width\n canvas.height = height\n ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height)\n return canvas\n}\n","import { FilesetResolver, ImageSegmenter } from '@mediapipe/tasks-vision'\nimport { error, log, warn } from '../utils/logger'\nimport { preloadVisionRuntime, visionTasksBasePath } from './VisionRuntime'\nimport { preloadDependency } from './preloadModels'\n\ntype ProbeState = 'notProbed' | 'probing' | 'probed'\n\nexport type NetworkTier = 'untested' | 'unusable' | 'slow' | 'medium' | 'fast'\n\ntype ModelCapabilities = {\n probeState: ProbeState\n delegate: 'GPU' | 'CPU' | 'NONE' // if we haven't probed capabilities, optimistically try GPU.\n networkTier: NetworkTier\n networkSpeed: number // represented in bytes per second, but flawed due to small sample size.\n networkTestTime: number // represented in seconds.\n}\n\nexport const defaultImageSegmenterModelPath =\n 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite'\nconst imageSegmenterModelSizeInBytes = 256440.32\n\n// The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test\n// isn't fooled by cache times, but subsequent downloads of the vision runtime still do load from the cache.\nlet tinyModelCacheKey = new Date().getTime()\n\nconst initialModelCapabilities = {\n probeState: 'notProbed',\n delegate: 'GPU',\n networkTier: 'untested',\n networkSpeed: 0,\n networkTestTime: 0,\n} satisfies ModelCapabilities\n\nexport let modelCapabilities: ModelCapabilities = {\n ...initialModelCapabilities,\n}\n\nexport async function probeModelCapabilities(): Promise<void> {\n if (modelCapabilities.probeState === 'probed') return\n if (modelCapabilities.probeState === 'probing')\n return new Promise((resolve) => {\n setInterval(() => {\n if (modelCapabilities.probeState === 'probed') resolve()\n }, 100)\n })\n\n modelCapabilities.probeState = 'probing'\n await preloadVisionRuntime()\n try {\n log('Model Probing: testing GPU capabilities...')\n await loadTinyModel('GPU')\n log('Model Probing: GPU is capable.')\n } catch (error) {\n warn('Model Probing: GPU delegate could not be loaded', error)\n modelCapabilities.delegate = 'CPU'\n try {\n log('Model Probing: testing CPU capabilities...')\n await loadTinyModel('CPU')\n log('Model Probing: CPU is capable.')\n } catch (error) {\n warn('Model Probing: CPU delegate could not be loaded', error)\n modelCapabilities.delegate = 'NONE'\n }\n } finally {\n modelCapabilities.probeState = 'probed'\n }\n}\n\nasync function loadTinyModel(delegate: 'GPU' | 'CPU' = 'GPU', maxTime = 10000) {\n const modelAssetPath = `${defaultImageSegmenterModelPath}?_=${tinyModelCacheKey}`\n\n const startedAt = new Date()\n try {\n await Promise.race([\n preloadDependency(modelAssetPath),\n giveUpAfter(maxTime),\n ])\n } catch (e) {\n error('speed test failed', e)\n modelCapabilities.networkTier = 'unusable'\n return\n }\n\n const time = (new Date().getTime() - startedAt.getTime()) / 1000.0\n\n modelCapabilities.networkTestTime ||= time\n modelCapabilities.networkSpeed ||= imageSegmenterModelSizeInBytes / time\n modelCapabilities.networkTier =\n time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow'\n\n const speedMbps = modelCapabilities.networkSpeed / 1024 / 1024\n log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps')\n log('Model Probing: network test took', time)\n log('Model Probing: network tier', modelCapabilities.networkTier)\n\n const model = await ImageSegmenter.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n { baseOptions: { modelAssetPath, delegate } },\n )\n\n const emptyFrame = document.createElement('canvas')\n model.segment(emptyFrame)\n emptyFrame.remove()\n}\n\nfunction giveUpAfter(maxTime: number) {\n return new Promise((_resolve, reject) => {\n setTimeout(() => {\n reject(new Error('gave up after reaching maximum time allowed'))\n }, maxTime)\n })\n}\n\nexport function resetModelCapabilityProbe() {\n tinyModelCacheKey = new Date().getTime()\n modelCapabilities = { ...initialModelCapabilities }\n}\n","import { FilesetResolver, ImageClassifier } from '@mediapipe/tasks-vision'\nimport {\n preloadFocusModelDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { Frame } from '../utils/getFrameDimensions'\nimport { DetectedObjectBox } from './DocumentDetection'\nimport { cropToDetectedObjectBox } from '../utils/cropping'\nimport { useEffect, useRef, useState } from 'react'\nimport { modelCapabilities } from './CapabilityProbing'\n\nexport const defaultFocusModelPath = `https://websdk-cdn-dev.idmission.com/assets/models/focusmp20240523/model_float16.tflite`\nexport const defaultFocusModelLoadTimeoutMs = 45000\n\nexport type FocusPrediction = {\n score: number\n predictionTime: number\n}\n\nexport type FocusThresholds = {\n idCard?: {\n desktop?: number\n mobile?: number\n }\n passport?: {\n desktop?: number\n mobile?: number\n }\n}\n\nexport const defaultFocusThresholds: FocusThresholds = {\n idCard: {\n desktop: 0,\n mobile: 0.3,\n },\n passport: {\n desktop: 0,\n mobile: 0.3,\n },\n}\n\nconst models: { [id: string]: ImageClassifier } = {}\n\nexport async function loadFocusModel(\n modelAssetPath: string,\n): Promise<ImageClassifier> {\n const id = `${modelAssetPath}`\n if (models[id]) return models[id]\n\n await preloadFocusModelDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for focus detector.')\n }\n\n models[id] = await ImageClassifier.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: { modelAssetPath, delegate: modelCapabilities.delegate },\n runningMode: 'VIDEO',\n },\n )\n\n // const emptyFrame = document.createElement('canvas')\n // models[id].classifyForVideo(emptyFrame, performance.now())\n // emptyFrame.remove()\n\n return models[id]\n}\n\nexport function useLoadFocusModel({\n modelPath = defaultFocusModelPath,\n modelLoadTimeoutMs = defaultFocusModelLoadTimeoutMs,\n onModelError,\n}: {\n modelPath?: string\n modelLoadTimeoutMs?: number\n onModelError?: (error: Error) => void\n}) {\n const model = useRef<ImageClassifier | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.focus',\n handleDownloadProgress,\n )\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n loadFocusModel(modelPath)\n .then((loadedModel) => {\n model.current = loadedModel\n setModelDownloadProgress(100)\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.focus',\n handleDownloadProgress,\n )\n }\n },\n [modelPath, modelLoadTimeoutMs],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { model, ready, modelDownloadProgress, modelError }\n}\n\nexport function makeFocusModelPrediction(\n model: ImageClassifier,\n imageData: Frame,\n cropCanvas: HTMLCanvasElement,\n rotateCanvas: HTMLCanvasElement,\n box?: DetectedObjectBox,\n): FocusPrediction {\n const startedAt = new Date()\n const image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box)\n const result = model.classifyForVideo(image, performance.now())\n const score =\n result?.classifications?.[0]?.categories?.find(\n (c) => c.categoryName === 'focused',\n )?.score ?? 0\n const predictionTime = new Date().getTime() - startedAt.getTime()\n return { score, predictionTime }\n}\n\nfunction cropIfNecessary(\n imageData: Frame,\n cropCanvas: HTMLCanvasElement,\n rotateCanvas: HTMLCanvasElement,\n box?: DetectedObjectBox,\n): Frame {\n if (!box) return imageData\n\n const cropped = cropToDetectedObjectBox(imageData, box, cropCanvas)\n const [bw, bh] = [box.width, box.height]\n if (bh <= bw) return cropped\n\n const ctx = rotateCanvas.getContext('2d')\n if (!ctx) return cropped\n\n rotateCanvas.width = bh\n rotateCanvas.height = bw\n ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height)\n ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2)\n ctx.rotate(1.5708) // 90 deg in radians\n ctx.drawImage(cropped, -bw / 2, -bh / 2)\n return rotateCanvas\n}\n","(function(){/*\n\n Copyright The Closure Library Authors.\n SPDX-License-Identifier: Apache-2.0\n*/\n'use strict';var x;function aa(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}var ba=\"function\"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};\nfunction ca(a){a=[\"object\"==typeof globalThis&&globalThis,a,\"object\"==typeof window&&window,\"object\"==typeof self&&self,\"object\"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error(\"Cannot find global object\");}var y=ca(this);function B(a,b){if(b)a:{var c=y;a=a.split(\".\");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}}\nB(\"Symbol\",function(a){function b(g){if(this instanceof b)throw new TypeError(\"Symbol is not a constructor\");return new c(d+(g||\"\")+\"_\"+e++,g)}function c(g,f){this.g=g;ba(this,\"description\",{configurable:!0,writable:!0,value:f})}if(a)return a;c.prototype.toString=function(){return this.g};var d=\"jscomp_symbol_\"+(1E9*Math.random()>>>0)+\"_\",e=0;return b});\nB(\"Symbol.iterator\",function(a){if(a)return a;a=Symbol(\"Symbol.iterator\");for(var b=\"Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array\".split(\" \"),c=0;c<b.length;c++){var d=y[b[c]];\"function\"===typeof d&&\"function\"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return da(aa(this))}})}return a});function da(a){a={next:a};a[Symbol.iterator]=function(){return this};return a}\nfunction C(a){var b=\"undefined\"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}}function D(a){if(!(a instanceof Array)){a=C(a);for(var b,c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}var ea=\"function\"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},fa;\nif(\"function\"==typeof Object.setPrototypeOf)fa=Object.setPrototypeOf;else{var ha;a:{var ia={a:!0},ja={};try{ja.__proto__=ia;ha=ja.a;break a}catch(a){}ha=!1}fa=ha?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+\" is not extensible\");return a}:null}var ka=fa;\nfunction E(a,b){a.prototype=ea(b.prototype);a.prototype.constructor=a;if(ka)ka(a,b);else for(var c in b)if(\"prototype\"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.na=b.prototype}function la(){this.l=!1;this.i=null;this.h=void 0;this.g=1;this.u=this.o=0;this.j=null}function ma(a){if(a.l)throw new TypeError(\"Generator is already running\");a.l=!0}la.prototype.s=function(a){this.h=a};\nfunction na(a,b){a.j={da:b,ea:!0};a.g=a.o||a.u}la.prototype.return=function(a){this.j={return:a};this.g=this.u};function G(a,b,c){a.g=c;return{value:b}}function oa(a){this.g=new la;this.h=a}function pa(a,b){ma(a.g);var c=a.g.i;if(c)return qa(a,\"return\"in c?c[\"return\"]:function(d){return{value:d,done:!0}},b,a.g.return);a.g.return(b);return H(a)}\nfunction qa(a,b,c,d){try{var e=b.call(a.g.i,c);if(!(e instanceof Object))throw new TypeError(\"Iterator result \"+e+\" is not an object\");if(!e.done)return a.g.l=!1,e;var g=e.value}catch(f){return a.g.i=null,na(a.g,f),H(a)}a.g.i=null;d.call(a.g,g);return H(a)}function H(a){for(;a.g.g;)try{var b=a.h(a.g);if(b)return a.g.l=!1,{value:b.value,done:!1}}catch(c){a.g.h=void 0,na(a.g,c)}a.g.l=!1;if(a.g.j){b=a.g.j;a.g.j=null;if(b.ea)throw b.da;return{value:b.return,done:!0}}return{value:void 0,done:!0}}\nfunction ra(a){this.next=function(b){ma(a.g);a.g.i?b=qa(a,a.g.i.next,b,a.g.s):(a.g.s(b),b=H(a));return b};this.throw=function(b){ma(a.g);a.g.i?b=qa(a,a.g.i[\"throw\"],b,a.g.s):(na(a.g,b),b=H(a));return b};this.return=function(b){return pa(a,b)};this[Symbol.iterator]=function(){return this}}function sa(a){function b(d){return a.next(d)}function c(d){return a.throw(d)}return new Promise(function(d,e){function g(f){f.done?d(f.value):Promise.resolve(f.value).then(b,c).then(g,e)}g(a.next())})}\nfunction J(a){return sa(new ra(new oa(a)))}\nB(\"Promise\",function(a){function b(f){this.h=0;this.i=void 0;this.g=[];this.s=!1;var h=this.j();try{f(h.resolve,h.reject)}catch(k){h.reject(k)}}function c(){this.g=null}function d(f){return f instanceof b?f:new b(function(h){h(f)})}if(a)return a;c.prototype.h=function(f){if(null==this.g){this.g=[];var h=this;this.i(function(){h.l()})}this.g.push(f)};var e=y.setTimeout;c.prototype.i=function(f){e(f,0)};c.prototype.l=function(){for(;this.g&&this.g.length;){var f=this.g;this.g=[];for(var h=0;h<f.length;++h){var k=\nf[h];f[h]=null;try{k()}catch(l){this.j(l)}}}this.g=null};c.prototype.j=function(f){this.i(function(){throw f;})};b.prototype.j=function(){function f(l){return function(m){k||(k=!0,l.call(h,m))}}var h=this,k=!1;return{resolve:f(this.D),reject:f(this.l)}};b.prototype.D=function(f){if(f===this)this.l(new TypeError(\"A Promise cannot resolve to itself\"));else if(f instanceof b)this.H(f);else{a:switch(typeof f){case \"object\":var h=null!=f;break a;case \"function\":h=!0;break a;default:h=!1}h?this.A(f):this.o(f)}};\nb.prototype.A=function(f){var h=void 0;try{h=f.then}catch(k){this.l(k);return}\"function\"==typeof h?this.I(h,f):this.o(f)};b.prototype.l=function(f){this.u(2,f)};b.prototype.o=function(f){this.u(1,f)};b.prototype.u=function(f,h){if(0!=this.h)throw Error(\"Cannot settle(\"+f+\", \"+h+\"): Promise already settled in state\"+this.h);this.h=f;this.i=h;2===this.h&&this.G();this.B()};b.prototype.G=function(){var f=this;e(function(){if(f.C()){var h=y.console;\"undefined\"!==typeof h&&h.error(f.i)}},1)};b.prototype.C=\nfunction(){if(this.s)return!1;var f=y.CustomEvent,h=y.Event,k=y.dispatchEvent;if(\"undefined\"===typeof k)return!0;\"function\"===typeof f?f=new f(\"unhandledrejection\",{cancelable:!0}):\"function\"===typeof h?f=new h(\"unhandledrejection\",{cancelable:!0}):(f=y.document.createEvent(\"CustomEvent\"),f.initCustomEvent(\"unhandledrejection\",!1,!0,f));f.promise=this;f.reason=this.i;return k(f)};b.prototype.B=function(){if(null!=this.g){for(var f=0;f<this.g.length;++f)g.h(this.g[f]);this.g=null}};var g=new c;b.prototype.H=\nfunction(f){var h=this.j();f.M(h.resolve,h.reject)};b.prototype.I=function(f,h){var k=this.j();try{f.call(h,k.resolve,k.reject)}catch(l){k.reject(l)}};b.prototype.then=function(f,h){function k(p,n){return\"function\"==typeof p?function(r){try{l(p(r))}catch(t){m(t)}}:n}var l,m,q=new b(function(p,n){l=p;m=n});this.M(k(f,l),k(h,m));return q};b.prototype.catch=function(f){return this.then(void 0,f)};b.prototype.M=function(f,h){function k(){switch(l.h){case 1:f(l.i);break;case 2:h(l.i);break;default:throw Error(\"Unexpected state: \"+\nl.h);}}var l=this;null==this.g?g.h(k):this.g.push(k);this.s=!0};b.resolve=d;b.reject=function(f){return new b(function(h,k){k(f)})};b.race=function(f){return new b(function(h,k){for(var l=C(f),m=l.next();!m.done;m=l.next())d(m.value).M(h,k)})};b.all=function(f){var h=C(f),k=h.next();return k.done?d([]):new b(function(l,m){function q(r){return function(t){p[r]=t;n--;0==n&&l(p)}}var p=[],n=0;do p.push(void 0),n++,d(k.value).M(q(p.length-1),m),k=h.next();while(!k.done)})};return b});\nfunction ta(a,b){a instanceof String&&(a+=\"\");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e}var ua=\"function\"==typeof Object.assign?Object.assign:function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(a[e]=d[e])}return a};B(\"Object.assign\",function(a){return a||ua});\nB(\"Object.is\",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});B(\"Array.prototype.includes\",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var g=d[c];if(g===b||Object.is(g,b))return!0}return!1}});\nB(\"String.prototype.includes\",function(a){return a?a:function(b,c){if(null==this)throw new TypeError(\"The 'this' value for String.prototype.includes must not be null or undefined\");if(b instanceof RegExp)throw new TypeError(\"First argument to String.prototype.includes must not be a regular expression\");return-1!==this.indexOf(b,c||0)}});B(\"Array.prototype.keys\",function(a){return a?a:function(){return ta(this,function(b){return b})}});var va=this||self;\nfunction K(a,b){a=a.split(\".\");var c=va;a[0]in c||\"undefined\"==typeof c.execScript||c.execScript(\"var \"+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c[d]&&c[d]!==Object.prototype[d]?c=c[d]:c=c[d]={}:c[d]=b};function L(){throw Error(\"Invalid UTF8\");}function wa(a,b){b=String.fromCharCode.apply(null,b);return null==a?b:a+b}var xa,ya=\"undefined\"!==typeof TextDecoder,za,Aa=\"undefined\"!==typeof TextEncoder;var Ba={},M=null;function Ca(a){var b;void 0===b&&(b=0);Da();b=Ba[b];for(var c=Array(Math.floor(a.length/3)),d=b[64]||\"\",e=0,g=0;e<a.length-2;e+=3){var f=a[e],h=a[e+1],k=a[e+2],l=b[f>>2];f=b[(f&3)<<4|h>>4];h=b[(h&15)<<2|k>>6];k=b[k&63];c[g++]=l+f+h+k}l=0;k=d;switch(a.length-e){case 2:l=a[e+1],k=b[(l&15)<<2]||d;case 1:a=a[e],c[g]=b[a>>2]+b[(a&3)<<4|l>>4]+k+d}return c.join(\"\")}\nfunction Ea(a){var b=a.length,c=3*b/4;c%3?c=Math.floor(c):-1!=\"=.\".indexOf(a[b-1])&&(c=-1!=\"=.\".indexOf(a[b-2])?c-2:c-1);var d=new Uint8Array(c),e=0;Fa(a,function(g){d[e++]=g});return e!==c?d.subarray(0,e):d}\nfunction Fa(a,b){function c(k){for(;d<a.length;){var l=a.charAt(d++),m=M[l];if(null!=m)return m;if(!/^[\\s\\xa0]*$/.test(l))throw Error(\"Unknown base64 encoding at char: \"+l);}return k}Da();for(var d=0;;){var e=c(-1),g=c(0),f=c(64),h=c(64);if(64===h&&-1===e)break;b(e<<2|g>>4);64!=f&&(b(g<<4&240|f>>2),64!=h&&b(f<<6&192|h))}}\nfunction Da(){if(!M){M={};for(var a=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\".split(\"\"),b=[\"+/=\",\"+/\",\"-_=\",\"-_.\",\"-_\"],c=0;5>c;c++){var d=a.concat(b[c].split(\"\"));Ba[c]=d;for(var e=0;e<d.length;e++){var g=d[e];void 0===M[g]&&(M[g]=e)}}}};var Ga=\"function\"===typeof Uint8Array;function Ha(a){return Ga&&null!=a&&a instanceof Uint8Array}var Ia;function Ja(a){this.L=a;if(null!==a&&0===a.length)throw Error(\"ByteString should be constructed with non-empty values\");};var Ka=\"function\"===typeof Uint8Array.prototype.slice,N=0,O=0;\nfunction La(a,b){if(a.constructor===Uint8Array)return a;if(a.constructor===ArrayBuffer)return new Uint8Array(a);if(a.constructor===Array)return new Uint8Array(a);if(a.constructor===String)return Ea(a);if(a.constructor===Ja){if(!b&&(b=a.L)&&b.constructor===Uint8Array)return b;b=a.L;b=null==b||Ha(b)?b:\"string\"===typeof b?Ea(b):null;return(a=a.L=b)?new Uint8Array(a):Ia||(Ia=new Uint8Array(0))}if(a instanceof Uint8Array)return new Uint8Array(a.buffer,a.byteOffset,a.byteLength);throw Error(\"Type not convertible to a Uint8Array, expected a Uint8Array, an ArrayBuffer, a base64 encoded string, or Array of numbers\");\n};function Ma(a,b){return Error(\"Invalid wire type: \"+a+\" (at position \"+b+\")\")}function Na(){return Error(\"Failed to read varint, encoding is invalid.\")};function Oa(a,b){b=void 0===b?{}:b;b=void 0===b.v?!1:b.v;this.h=null;this.g=this.i=this.j=0;this.v=b;a&&Pa(this,a)}function Pa(a,b){a.h=La(b,a.v);a.j=0;a.i=a.h.length;a.g=a.j}Oa.prototype.reset=function(){this.g=this.j};function P(a){if(a.g>a.i)throw Error(\"Tried to read past the end of the data \"+a.g+\" > \"+a.i);}\nfunction Q(a){var b=a.h,c=b[a.g],d=c&127;if(128>c)return a.g+=1,P(a),d;c=b[a.g+1];d|=(c&127)<<7;if(128>c)return a.g+=2,P(a),d;c=b[a.g+2];d|=(c&127)<<14;if(128>c)return a.g+=3,P(a),d;c=b[a.g+3];d|=(c&127)<<21;if(128>c)return a.g+=4,P(a),d;c=b[a.g+4];a.g+=5;d|=(c&15)<<28;if(128>c)return P(a),d;if(128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++])throw Na();P(a);return d}var Qa=[];function Ra(){this.g=[]}Ra.prototype.length=function(){return this.g.length};Ra.prototype.end=function(){var a=this.g;this.g=[];return a};function S(a,b){for(;127<b;)a.g.push(b&127|128),b>>>=7;a.g.push(b)};function Sa(a){var b={},c=void 0===b.W?!1:b.W;this.l={v:void 0===b.v?!1:b.v};this.W=c;b=this.l;Qa.length?(c=Qa.pop(),b&&(c.v=b.v),a&&Pa(c,a),a=c):a=new Oa(a,b);this.g=a;this.j=this.g.g;this.h=this.i=-1}Sa.prototype.reset=function(){this.g.reset();this.j=this.g.g;this.h=this.i=-1};function Ta(a){var b=a.g;if(b.g==b.i)return!1;a.j=a.g.g;var c=Q(a.g)>>>0;b=c>>>3;c&=7;if(!(0<=c&&5>=c))throw Ma(c,a.j);if(1>b)throw Error(\"Invalid field number: \"+b+\" (at position \"+a.j+\")\");a.i=b;a.h=c;return!0}\nfunction Ua(a){switch(a.h){case 0:if(0!=a.h)Ua(a);else a:{a=a.g;for(var b=a.g,c=b+10;b<c;)if(0===(a.h[b++]&128)){a.g=b;P(a);break a}throw Na();}break;case 1:a=a.g;a.g+=8;P(a);break;case 2:2!=a.h?Ua(a):(b=Q(a.g)>>>0,a=a.g,a.g+=b,P(a));break;case 5:a=a.g;a.g+=4;P(a);break;case 3:b=a.i;do{if(!Ta(a))throw Error(\"Unmatched start-group tag: stream EOF\");if(4==a.h){if(a.i!=b)throw Error(\"Unmatched end-group tag\");break}Ua(a)}while(1);break;default:throw Ma(a.h,a.j);}}var Va=[];function Wa(){this.i=[];this.h=0;this.g=new Ra}function T(a,b){0!==b.length&&(a.i.push(b),a.h+=b.length)}function Xa(a,b){if(b=b.ba){T(a,a.g.end());for(var c=0;c<b.length;c++)T(a,b[c])}};var U=\"function\"===typeof Symbol&&\"symbol\"===typeof Symbol()?Symbol(void 0):void 0;function Ya(a,b){Object.isFrozen(a)||(U?a[U]|=b:void 0!==a.N?a.N|=b:Object.defineProperties(a,{N:{value:b,configurable:!0,writable:!0,enumerable:!1}}))}function Za(a){var b;U?b=a[U]:b=a.N;return null==b?0:b}function $a(a){Ya(a,1);return a}function ab(a){return Array.isArray(a)?!!(Za(a)&2):!1}function bb(a){if(!Array.isArray(a))throw Error(\"cannot mark non-array as immutable\");Ya(a,2)};function cb(a){return null!==a&&\"object\"===typeof a&&!Array.isArray(a)&&a.constructor===Object}var db=Object.freeze($a([]));function eb(a){if(ab(a.m))throw Error(\"Cannot mutate an immutable Message\");}var fb=\"undefined\"!=typeof Symbol&&\"undefined\"!=typeof Symbol.hasInstance;function gb(a){return{value:a,configurable:!1,writable:!1,enumerable:!1}};function V(a,b,c){return-1===b?null:b>=a.i?a.g?a.g[b]:void 0:(void 0===c?0:c)&&a.g&&(c=a.g[b],null!=c)?c:a.m[b+a.h]}function W(a,b,c,d){d=void 0===d?!1:d;eb(a);b<a.i&&!d?a.m[b+a.h]=c:(a.g||(a.g=a.m[a.i+a.h]={}))[b]=c}function hb(a,b,c,d){c=void 0===c?!0:c;d=void 0===d?!1:d;var e=V(a,b,d);null==e&&(e=db);if(ab(a.m))c&&(bb(e),Object.freeze(e));else if(e===db||ab(e))e=$a(e.slice()),W(a,b,e,d);return e}function X(a,b,c){a=V(a,b);a=null==a?a:+a;return null==a?void 0===c?0:c:a}\nfunction ib(a,b,c,d){a.j||(a.j={});var e=ab(a.m),g=a.j[c];if(!g){d=hb(a,c,!0,void 0===d?!1:d);g=[];e=e||ab(d);for(var f=0;f<d.length;f++)g[f]=new b(d[f]),e&&bb(g[f].m);e&&(bb(g),Object.freeze(g));a.j[c]=g}return g}function jb(a,b,c,d,e){var g=void 0===g?!1:g;eb(a);g=ib(a,c,b,g);c=d?d:new c;a=hb(a,b);void 0!=e?(g.splice(e,0,c),a.splice(e,0,c.m)):(g.push(c),a.push(c.m));return c}function kb(a,b){a=V(a,b);return null==a?0:a}function lb(a,b){a=V(a,b);return null==a?\"\":a};function mb(a){switch(typeof a){case \"number\":return isFinite(a)?a:String(a);case \"object\":if(a&&!Array.isArray(a)){if(Ha(a))return Ca(a);if(a instanceof Ja){var b=a.L;b=null==b||\"string\"===typeof b?b:Ga&&b instanceof Uint8Array?Ca(b):null;return(a.L=b)||\"\"}}}return a};function nb(a){var b=ob;b=void 0===b?pb:b;return qb(a,b)}function rb(a,b){if(null!=a){if(Array.isArray(a))a=qb(a,b);else if(cb(a)){var c={},d;for(d in a)c[d]=rb(a[d],b);a=c}else a=b(a);return a}}function qb(a,b){for(var c=a.slice(),d=0;d<c.length;d++)c[d]=rb(c[d],b);Array.isArray(a)&&Za(a)&1&&$a(c);return c}function ob(a){if(a&&\"object\"==typeof a&&a.toJSON)return a.toJSON();a=mb(a);return Array.isArray(a)?nb(a):a}function pb(a){return Ha(a)?new Uint8Array(a):a};function sb(a,b,c){a||(a=tb);tb=null;var d=this.constructor.h;a||(a=d?[d]:[]);this.h=(d?0:-1)-(this.constructor.g||0);this.j=void 0;this.m=a;a:{d=this.m.length;a=d-1;if(d&&(d=this.m[a],cb(d))){this.i=a-this.h;this.g=d;break a}void 0!==b&&-1<b?(this.i=Math.max(b,a+1-this.h),this.g=void 0):this.i=Number.MAX_VALUE}if(c)for(b=0;b<c.length;b++)if(a=c[b],a<this.i)a+=this.h,(d=this.m[a])?Array.isArray(d)&&$a(d):this.m[a]=db;else{d=this.g||(this.g=this.m[this.i+this.h]={});var e=d[a];e?Array.isArray(e)&&\n$a(e):d[a]=db}}sb.prototype.toJSON=function(){return nb(this.m)};sb.prototype.toString=function(){return this.m.toString()};var tb;function ub(){sb.apply(this,arguments)}E(ub,sb);if(fb){var vb={};Object.defineProperties(ub,(vb[Symbol.hasInstance]=gb(function(){throw Error(\"Cannot perform instanceof checks for MutableMessage\");}),vb))};function wb(a,b,c){if(c){var d={},e;for(e in c){var g=c[e],f=g.ha;f||(d.F=g.la||g.fa.P,g.aa?(d.U=xb(g.aa),f=function(h){return function(k,l,m){return h.F(k,l,m,h.U)}}(d)):g.ca?(d.T=yb(g.X.g,g.ca),f=function(h){return function(k,l,m){return h.F(k,l,m,h.T)}}(d)):f=d.F,g.ha=f);f(b,a,g.X);d={F:d.F,U:d.U,T:d.T}}}Xa(b,a)}var zb=Symbol();function Ab(a,b,c){return a[zb]||(a[zb]=function(d,e){return b(d,e,c)})}\nfunction Bb(a){var b=a[zb];if(!b){var c=Cb(a);b=function(d,e){return Db(d,e,c)};a[zb]=b}return b}function Eb(a){var b=a.aa;if(b)return Bb(b);if(b=a.ka)return Ab(a.X.g,b,a.ca)}function Fb(a){var b=Eb(a),c=a.X,d=a.fa.O;return b?function(e,g){return d(e,g,c,b)}:function(e,g){return d(e,g,c)}}\nfunction Gb(a,b,c,d,e,g){a=a();var f=0;a.length&&\"number\"!==typeof a[0]&&(c(b,a[0]),f++);for(;f<a.length;){c=a[f++];for(var h=f+1;h<a.length&&\"number\"!==typeof a[h];)h++;var k=a[f++];h-=f;switch(h){case 0:d(b,c,k);break;case 1:d(b,c,k,a[f++]);break;case 2:e(b,c,k,a[f++],a[f++]);break;case 3:h=a[f++];var l=a[f++],m=a[f++];Array.isArray(m)?e(b,c,k,h,l,m):g(b,c,k,h,l,m);break;case 4:g(b,c,k,a[f++],a[f++],a[f++],a[f++]);break;default:throw Error(\"unexpected number of binary field arguments: \"+h);}}return b}\nvar Hb=Symbol();function xb(a){var b=a[Hb];if(!b){var c=Ib(a);b=function(d,e){return Jb(d,e,c)};a[Hb]=b}return b}function yb(a,b){var c=a[Hb];c||(c=function(d,e){return wb(d,e,b)},a[Hb]=c);return c}var Kb=Symbol();function Lb(a,b){a.push(b)}function Mb(a,b,c){a.push(b,c.P)}function Nb(a,b,c,d,e){var g=xb(e),f=c.P;a.push(b,function(h,k,l){return f(h,k,l,d,g)})}function Ob(a,b,c,d,e,g){var f=yb(d,g),h=c.P;a.push(b,function(k,l,m){return h(k,l,m,d,f)})}\nfunction Ib(a){var b=a[Kb];return b?b:Gb(a,a[Kb]=[],Lb,Mb,Nb,Ob)}var Pb=Symbol();function Qb(a,b){a[0]=b}function Rb(a,b,c,d){var e=c.O;a[b]=d?function(g,f,h){return e(g,f,h,d)}:e}function Sb(a,b,c,d,e,g){var f=c.O,h=Bb(e);a[b]=function(k,l,m){return f(k,l,m,d,h,g)}}function Tb(a,b,c,d,e,g,f){var h=c.O,k=Ab(d,e,g);a[b]=function(l,m,q){return h(l,m,q,d,k,f)}}function Cb(a){var b=a[Pb];return b?b:Gb(a,a[Pb]={},Qb,Rb,Sb,Tb)}\nfunction Db(a,b,c){for(;Ta(b)&&4!=b.h;){var d=b.i,e=c[d];if(!e){var g=c[0];g&&(g=g[d])&&(e=c[d]=Fb(g))}if(!e||!e(b,a,d))if(e=b,d=a,g=e.j,Ua(e),!e.W){var f=e.g.h;e=e.g.g;e=g===e?Ia||(Ia=new Uint8Array(0)):Ka?f.slice(g,e):new Uint8Array(f.subarray(g,e));(g=d.ba)?g.push(e):d.ba=[e]}}return a}\nfunction Ub(a,b,c){if(Va.length){var d=Va.pop();a&&(Pa(d.g,a),d.i=-1,d.h=-1);a=d}else a=new Sa(a);try{return Db(new b,a,Cb(c))}finally{b=a.g,b.h=null,b.j=0,b.i=0,b.g=0,b.v=!1,a.i=-1,a.h=-1,100>Va.length&&Va.push(a)}}function Jb(a,b,c){for(var d=c.length,e=1==d%2,g=e?1:0;g<d;g+=2)(0,c[g+1])(b,a,c[g]);wb(a,b,e?c[0]:void 0)}function Vb(a,b){var c=new Wa;Jb(a,c,Ib(b));T(c,c.g.end());a=new Uint8Array(c.h);b=c.i;for(var d=b.length,e=0,g=0;g<d;g++){var f=b[g];a.set(f,e);e+=f.length}c.i=[a];return a}\nfunction Wb(a,b){return{O:a,P:b}}\nvar Y=Wb(function(a,b,c){if(5!==a.h)return!1;a=a.g;var d=a.h[a.g];var e=a.h[a.g+1];var g=a.h[a.g+2],f=a.h[a.g+3];a.g+=4;P(a);e=(d<<0|e<<8|g<<16|f<<24)>>>0;a=2*(e>>31)+1;d=e>>>23&255;e&=8388607;W(b,c,255==d?e?NaN:Infinity*a:0==d?a*Math.pow(2,-149)*e:a*Math.pow(2,d-150)*(e+Math.pow(2,23)));return!0},function(a,b,c){b=V(b,c);if(null!=b){S(a.g,8*c+5);a=a.g;var d=b;d=(c=0>d?1:0)?-d:d;0===d?0<1/d?N=O=0:(O=0,N=2147483648):isNaN(d)?(O=0,N=2147483647):3.4028234663852886E38<d?(O=0,N=(c<<31|2139095040)>>>0):\n1.1754943508222875E-38>d?(d=Math.round(d/Math.pow(2,-149)),O=0,N=(c<<31|d)>>>0):(b=Math.floor(Math.log(d)/Math.LN2),d*=Math.pow(2,-b),d=Math.round(8388608*d),16777216<=d&&++b,O=0,N=(c<<31|b+127<<23|d&8388607)>>>0);c=N;a.g.push(c>>>0&255);a.g.push(c>>>8&255);a.g.push(c>>>16&255);a.g.push(c>>>24&255)}}),Xb=Wb(function(a,b,c){if(0!==a.h)return!1;for(var d=a.g,e=128,g=0,f=a=0;4>f&&128<=e;f++)e=d.h[d.g++],P(d),g|=(e&127)<<7*f;128<=e&&(e=d.h[d.g++],P(d),g|=(e&127)<<28,a|=(e&127)>>4);if(128<=e)for(f=0;5>\nf&&128<=e;f++)e=d.h[d.g++],P(d),a|=(e&127)<<7*f+3;if(128>e){d=g>>>0;e=a>>>0;if(a=e&2147483648)d=~d+1>>>0,e=~e>>>0,0==d&&(e=e+1>>>0);d=4294967296*e+(d>>>0)}else throw Na();W(b,c,a?-d:d);return!0},function(a,b,c){b=V(b,c);if(null!=b&&null!=b){S(a.g,8*c);a=a.g;var d=b;c=0>d;d=Math.abs(d);b=d>>>0;d=Math.floor((d-b)/4294967296);d>>>=0;c&&(d=~d>>>0,b=(~b>>>0)+1,4294967295<b&&(b=0,d++,4294967295<d&&(d=0)));N=b;O=d;c=N;for(b=O;0<b||127<c;)a.g.push(c&127|128),c=(c>>>7|b<<25)>>>0,b>>>=7;a.g.push(c)}}),Yb=Wb(function(a,\nb,c){if(0!==a.h)return!1;W(b,c,Q(a.g));return!0},function(a,b,c){b=V(b,c);if(null!=b&&null!=b)if(S(a.g,8*c),a=a.g,c=b,0<=c)S(a,c);else{for(b=0;9>b;b++)a.g.push(c&127|128),c>>=7;a.g.push(1)}}),Zb=Wb(function(a,b,c){if(2!==a.h)return!1;var d=Q(a.g)>>>0;a=a.g;var e=a.g;a.g+=d;P(a);a=a.h;var g;if(ya)(g=xa)||(g=xa=new TextDecoder(\"utf-8\",{fatal:!0})),g=g.decode(a.subarray(e,e+d));else{d=e+d;for(var f=[],h=null,k,l,m;e<d;)k=a[e++],128>k?f.push(k):224>k?e>=d?L():(l=a[e++],194>k||128!==(l&192)?(e--,L()):\nf.push((k&31)<<6|l&63)):240>k?e>=d-1?L():(l=a[e++],128!==(l&192)||224===k&&160>l||237===k&&160<=l||128!==((g=a[e++])&192)?(e--,L()):f.push((k&15)<<12|(l&63)<<6|g&63)):244>=k?e>=d-2?L():(l=a[e++],128!==(l&192)||0!==(k<<28)+(l-144)>>30||128!==((g=a[e++])&192)||128!==((m=a[e++])&192)?(e--,L()):(k=(k&7)<<18|(l&63)<<12|(g&63)<<6|m&63,k-=65536,f.push((k>>10&1023)+55296,(k&1023)+56320))):L(),8192<=f.length&&(h=wa(h,f),f.length=0);g=wa(h,f)}W(b,c,g);return!0},function(a,b,c){b=V(b,c);if(null!=b){var d=!1;\nd=void 0===d?!1:d;if(Aa){if(d&&/(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])/.test(b))throw Error(\"Found an unpaired surrogate\");b=(za||(za=new TextEncoder)).encode(b)}else{for(var e=0,g=new Uint8Array(3*b.length),f=0;f<b.length;f++){var h=b.charCodeAt(f);if(128>h)g[e++]=h;else{if(2048>h)g[e++]=h>>6|192;else{if(55296<=h&&57343>=h){if(56319>=h&&f<b.length){var k=b.charCodeAt(++f);if(56320<=k&&57343>=k){h=1024*(h-55296)+k-56320+65536;g[e++]=h>>18|240;g[e++]=h>>12&63|128;\ng[e++]=h>>6&63|128;g[e++]=h&63|128;continue}else f--}if(d)throw Error(\"Found an unpaired surrogate\");h=65533}g[e++]=h>>12|224;g[e++]=h>>6&63|128}g[e++]=h&63|128}}b=g.subarray(0,e)}S(a.g,8*c+2);S(a.g,b.length);T(a,a.g.end());T(a,b)}}),$b=Wb(function(a,b,c,d,e){if(2!==a.h)return!1;b=jb(b,c,d);c=a.g.i;d=Q(a.g)>>>0;var g=a.g.g+d,f=g-c;0>=f&&(a.g.i=g,e(b,a),f=g-a.g.g);if(f)throw Error(\"Message parsing ended unexpectedly. Expected to read \"+(d+\" bytes, instead read \"+(d-f)+\" bytes, either the data ended unexpectedly or the message misreported its own length\"));\na.g.g=g;a.g.i=c;return!0},function(a,b,c,d,e){b=ib(b,d,c);if(null!=b)for(d=0;d<b.length;d++){var g=a;S(g.g,8*c+2);var f=g.g.end();T(g,f);f.push(g.h);g=f;e(b[d],a);f=a;var h=g.pop();for(h=f.h+f.g.length()-h;127<h;)g.push(h&127|128),h>>>=7,f.h++;g.push(h);f.h++}});function Z(){ub.apply(this,arguments)}E(Z,ub);if(fb){var ac={};Object.defineProperties(Z,(ac[Symbol.hasInstance]=gb(Object[Symbol.hasInstance]),ac))};function bc(a){Z.call(this,a)}E(bc,Z);function cc(){return[1,Yb,2,Y,3,Zb,4,Zb]};function dc(a){Z.call(this,a,-1,ec)}E(dc,Z);dc.prototype.addClassification=function(a,b){jb(this,1,bc,a,b);return this};function fc(){return[1,$b,bc,cc]}var ec=[1];function gc(a){Z.call(this,a)}E(gc,Z);function hc(){return[1,Y,2,Y,3,Y,4,Y,5,Y]};function ic(a){Z.call(this,a,-1,jc)}E(ic,Z);function kc(){return[1,$b,gc,hc]}var jc=[1];function lc(a){Z.call(this,a)}E(lc,Z);function mc(){return[1,Y,2,Y,3,Y,4,Y,5,Y,6,Xb]};var nc=[[61,146],[146,91],[91,181],[181,84],[84,17],[17,314],[314,405],[405,321],[321,375],[375,291],[61,185],[185,40],[40,39],[39,37],[37,0],[0,267],[267,269],[269,270],[270,409],[409,291],[78,95],[95,88],[88,178],[178,87],[87,14],[14,317],[317,402],[402,318],[318,324],[324,308],[78,191],[191,80],[80,81],[81,82],[82,13],[13,312],[312,311],[311,310],[310,415],[415,308]],oc=[[263,249],[249,390],[390,373],[373,374],[374,380],[380,381],[381,382],[382,362],[263,466],[466,388],[388,387],[387,386],[386,\n385],[385,384],[384,398],[398,362]],pc=[[276,283],[283,282],[282,295],[295,285],[300,293],[293,334],[334,296],[296,336]],qc=[[33,7],[7,163],[163,144],[144,145],[145,153],[153,154],[154,155],[155,133],[33,246],[246,161],[161,160],[160,159],[159,158],[158,157],[157,173],[173,133]],rc=[[46,53],[53,52],[52,65],[65,55],[70,63],[63,105],[105,66],[66,107]],sc=[[10,338],[338,297],[297,332],[332,284],[284,251],[251,389],[389,356],[356,454],[454,323],[323,361],[361,288],[288,397],[397,365],[365,379],[379,378],\n[378,400],[400,377],[377,152],[152,148],[148,176],[176,149],[149,150],[150,136],[136,172],[172,58],[58,132],[132,93],[93,234],[234,127],[127,162],[162,21],[21,54],[54,103],[103,67],[67,109],[109,10]],tc=[].concat(D(nc),D(oc),D(pc),D(qc),D(rc),D(sc));function uc(a,b,c){c=a.createShader(0===c?a.VERTEX_SHADER:a.FRAGMENT_SHADER);a.shaderSource(c,b);a.compileShader(c);if(!a.getShaderParameter(c,a.COMPILE_STATUS))throw Error(\"Could not compile WebGL shader.\\n\\n\"+a.getShaderInfoLog(c));return c};function vc(a){return ib(a,bc,1).map(function(b){return{index:kb(b,1),ga:X(b,2),label:null!=V(b,3)?lb(b,3):void 0,displayName:null!=V(b,4)?lb(b,4):void 0}})};function wc(a){return{x:X(a,1),y:X(a,2),z:X(a,3),visibility:null!=V(a,4)?X(a,4):void 0}};function xc(a,b){this.h=a;this.g=b;this.l=0}\nfunction yc(a,b,c){zc(a,b);if(\"function\"===typeof a.g.canvas.transferToImageBitmap)return Promise.resolve(a.g.canvas.transferToImageBitmap());if(c)return Promise.resolve(a.g.canvas);if(\"function\"===typeof createImageBitmap)return createImageBitmap(a.g.canvas);void 0===a.i&&(a.i=document.createElement(\"canvas\"));return new Promise(function(d){a.i.height=a.g.canvas.height;a.i.width=a.g.canvas.width;a.i.getContext(\"2d\",{}).drawImage(a.g.canvas,0,0,a.g.canvas.width,a.g.canvas.height);d(a.i)})}\nfunction zc(a,b){var c=a.g;if(void 0===a.o){var d=uc(c,\"\\n attribute vec2 aVertex;\\n attribute vec2 aTex;\\n varying vec2 vTex;\\n void main(void) {\\n gl_Position = vec4(aVertex, 0.0, 1.0);\\n vTex = aTex;\\n }\",0),e=uc(c,\"\\n precision mediump float;\\n varying vec2 vTex;\\n uniform sampler2D sampler0;\\n void main(){\\n gl_FragColor = texture2D(sampler0, vTex);\\n }\",1),g=c.createProgram();c.attachShader(g,d);c.attachShader(g,e);c.linkProgram(g);if(!c.getProgramParameter(g,c.LINK_STATUS))throw Error(\"Could not compile WebGL program.\\n\\n\"+\nc.getProgramInfoLog(g));d=a.o=g;c.useProgram(d);e=c.getUniformLocation(d,\"sampler0\");a.j={K:c.getAttribLocation(d,\"aVertex\"),J:c.getAttribLocation(d,\"aTex\"),ma:e};a.u=c.createBuffer();c.bindBuffer(c.ARRAY_BUFFER,a.u);c.enableVertexAttribArray(a.j.K);c.vertexAttribPointer(a.j.K,2,c.FLOAT,!1,0,0);c.bufferData(c.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),c.STATIC_DRAW);c.bindBuffer(c.ARRAY_BUFFER,null);a.s=c.createBuffer();c.bindBuffer(c.ARRAY_BUFFER,a.s);c.enableVertexAttribArray(a.j.J);c.vertexAttribPointer(a.j.J,\n2,c.FLOAT,!1,0,0);c.bufferData(c.ARRAY_BUFFER,new Float32Array([0,1,0,0,1,0,1,1]),c.STATIC_DRAW);c.bindBuffer(c.ARRAY_BUFFER,null);c.uniform1i(e,0)}d=a.j;c.useProgram(a.o);c.canvas.width=b.width;c.canvas.height=b.height;c.viewport(0,0,b.width,b.height);c.activeTexture(c.TEXTURE0);a.h.bindTexture2d(b.glName);c.enableVertexAttribArray(d.K);c.bindBuffer(c.ARRAY_BUFFER,a.u);c.vertexAttribPointer(d.K,2,c.FLOAT,!1,0,0);c.enableVertexAttribArray(d.J);c.bindBuffer(c.ARRAY_BUFFER,a.s);c.vertexAttribPointer(d.J,\n2,c.FLOAT,!1,0,0);c.bindFramebuffer(c.DRAW_FRAMEBUFFER?c.DRAW_FRAMEBUFFER:c.FRAMEBUFFER,null);c.clearColor(0,0,0,0);c.clear(c.COLOR_BUFFER_BIT);c.colorMask(!0,!0,!0,!0);c.drawArrays(c.TRIANGLE_FAN,0,4);c.disableVertexAttribArray(d.K);c.disableVertexAttribArray(d.J);c.bindBuffer(c.ARRAY_BUFFER,null);a.h.bindTexture2d(0)}function Ac(a){this.g=a};var Bc=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11]);function Cc(a,b){return b+a}function Dc(a,b){window[a]=b}function Ec(a){var b=document.createElement(\"script\");b.setAttribute(\"src\",a);b.setAttribute(\"crossorigin\",\"anonymous\");return new Promise(function(c){b.addEventListener(\"load\",function(){c()},!1);b.addEventListener(\"error\",function(){c()},!1);document.body.appendChild(b)})}\nfunction Fc(){return J(function(a){switch(a.g){case 1:return a.o=2,G(a,WebAssembly.instantiate(Bc),4);case 4:a.g=3;a.o=0;break;case 2:return a.o=0,a.j=null,a.return(!1);case 3:return a.return(!0)}})}\nfunction Gc(a){this.g=a;this.listeners={};this.j={};this.H={};this.o={};this.u={};this.I=this.s=this.Z=!0;this.D=Promise.resolve();this.Y=\"\";this.C={};this.locateFile=a&&a.locateFile||Cc;if(\"object\"===typeof window)var b=window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf(\"/\"))+\"/\";else if(\"undefined\"!==typeof location)b=location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf(\"/\"))+\"/\";else throw Error(\"solutions can only be loaded on a web page or in a web worker\");\nthis.$=b;if(a.options){b=C(Object.keys(a.options));for(var c=b.next();!c.done;c=b.next()){c=c.value;var d=a.options[c].default;void 0!==d&&(this.j[c]=\"function\"===typeof d?d():d)}}}x=Gc.prototype;x.close=function(){this.i&&this.i.delete();return Promise.resolve()};\nfunction Hc(a){var b,c,d,e,g,f,h,k,l,m,q;return J(function(p){switch(p.g){case 1:if(!a.Z)return p.return();b=void 0===a.g.files?[]:\"function\"===typeof a.g.files?a.g.files(a.j):a.g.files;return G(p,Fc(),2);case 2:c=p.h;if(\"object\"===typeof window)return Dc(\"createMediapipeSolutionsWasm\",{locateFile:a.locateFile}),Dc(\"createMediapipeSolutionsPackedAssets\",{locateFile:a.locateFile}),f=b.filter(function(n){return void 0!==n.data}),h=b.filter(function(n){return void 0===n.data}),k=Promise.all(f.map(function(n){var r=\nIc(a,n.url);if(void 0!==n.path){var t=n.path;r=r.then(function(w){a.overrideFile(t,w);return Promise.resolve(w)})}return r})),l=Promise.all(h.map(function(n){return void 0===n.simd||n.simd&&c||!n.simd&&!c?Ec(a.locateFile(n.url,a.$)):Promise.resolve()})).then(function(){var n,r,t;return J(function(w){if(1==w.g)return n=window.createMediapipeSolutionsWasm,r=window.createMediapipeSolutionsPackedAssets,t=a,G(w,n(r),2);t.h=w.h;w.g=0})}),m=function(){return J(function(n){a.g.graph&&a.g.graph.url?n=G(n,\nIc(a,a.g.graph.url),0):(n.g=0,n=void 0);return n})}(),G(p,Promise.all([l,k,m]),7);if(\"function\"!==typeof importScripts)throw Error(\"solutions can only be loaded on a web page or in a web worker\");d=b.filter(function(n){return void 0===n.simd||n.simd&&c||!n.simd&&!c}).map(function(n){return a.locateFile(n.url,a.$)});importScripts.apply(null,D(d));e=a;return G(p,createMediapipeSolutionsWasm(Module),6);case 6:e.h=p.h;a.l=new OffscreenCanvas(1,1);a.h.canvas=a.l;g=a.h.GL.createContext(a.l,{antialias:!1,\nalpha:!1,ja:\"undefined\"!==typeof WebGL2RenderingContext?2:1});a.h.GL.makeContextCurrent(g);p.g=4;break;case 7:a.l=document.createElement(\"canvas\");q=a.l.getContext(\"webgl2\",{});if(!q&&(q=a.l.getContext(\"webgl\",{}),!q))return alert(\"Failed to create WebGL canvas context when passing video frame.\"),p.return();a.G=q;a.h.canvas=a.l;a.h.createContext(a.l,!0,!0,{});case 4:a.i=new a.h.SolutionWasm,a.Z=!1,p.g=0}})}\nfunction Jc(a){var b,c,d,e,g,f,h,k;return J(function(l){if(1==l.g){if(a.g.graph&&a.g.graph.url&&a.Y===a.g.graph.url)return l.return();a.s=!0;if(!a.g.graph||!a.g.graph.url){l.g=2;return}a.Y=a.g.graph.url;return G(l,Ic(a,a.g.graph.url),3)}2!=l.g&&(b=l.h,a.i.loadGraph(b));c=C(Object.keys(a.C));for(d=c.next();!d.done;d=c.next())e=d.value,a.i.overrideFile(e,a.C[e]);a.C={};if(a.g.listeners)for(g=C(a.g.listeners),f=g.next();!f.done;f=g.next())h=f.value,Kc(a,h);k=a.j;a.j={};a.setOptions(k);l.g=0})}\nx.reset=function(){var a=this;return J(function(b){a.i&&(a.i.reset(),a.o={},a.u={});b.g=0})};\nx.setOptions=function(a,b){var c=this;if(b=b||this.g.options){for(var d=[],e=[],g={},f=C(Object.keys(a)),h=f.next();!h.done;g={R:g.R,S:g.S},h=f.next()){var k=h.value;k in this.j&&this.j[k]===a[k]||(this.j[k]=a[k],h=b[k],void 0!==h&&(h.onChange&&(g.R=h.onChange,g.S=a[k],d.push(function(l){return function(){var m;return J(function(q){if(1==q.g)return G(q,l.R(l.S),2);m=q.h;!0===m&&(c.s=!0);q.g=0})}}(g))),h.graphOptionXref&&(k={valueNumber:1===h.type?a[k]:0,valueBoolean:0===h.type?a[k]:!1,valueString:2===\nh.type?a[k]:\"\"},h=Object.assign(Object.assign(Object.assign({},{calculatorName:\"\",calculatorIndex:0}),h.graphOptionXref),k),e.push(h))))}if(0!==d.length||0!==e.length)this.s=!0,this.B=(void 0===this.B?[]:this.B).concat(e),this.A=(void 0===this.A?[]:this.A).concat(d)}};\nfunction Lc(a){var b,c,d,e,g,f,h;return J(function(k){switch(k.g){case 1:if(!a.s)return k.return();if(!a.A){k.g=2;break}b=C(a.A);c=b.next();case 3:if(c.done){k.g=5;break}d=c.value;return G(k,d(),4);case 4:c=b.next();k.g=3;break;case 5:a.A=void 0;case 2:if(a.B){e=new a.h.GraphOptionChangeRequestList;g=C(a.B);for(f=g.next();!f.done;f=g.next())h=f.value,e.push_back(h);a.i.changeOptions(e);e.delete();a.B=void 0}a.s=!1;k.g=0}})}\nx.initialize=function(){var a=this;return J(function(b){return 1==b.g?G(b,Hc(a),2):3!=b.g?G(b,Jc(a),3):G(b,Lc(a),0)})};function Ic(a,b){var c,d;return J(function(e){if(b in a.H)return e.return(a.H[b]);c=a.locateFile(b,\"\");d=fetch(c).then(function(g){return g.arrayBuffer()});a.H[b]=d;return e.return(d)})}x.overrideFile=function(a,b){this.i?this.i.overrideFile(a,b):this.C[a]=b};x.clearOverriddenFiles=function(){this.C={};this.i&&this.i.clearOverriddenFiles()};\nx.send=function(a,b){var c=this,d,e,g,f,h,k,l,m,q;return J(function(p){switch(p.g){case 1:if(!c.g.inputs)return p.return();d=1E3*(void 0===b||null===b?performance.now():b);return G(p,c.D,2);case 2:return G(p,c.initialize(),3);case 3:e=new c.h.PacketDataList;g=C(Object.keys(a));for(f=g.next();!f.done;f=g.next())if(h=f.value,k=c.g.inputs[h]){a:{var n=a[h];switch(k.type){case \"video\":var r=c.o[k.stream];r||(r=new xc(c.h,c.G),c.o[k.stream]=r);0===r.l&&(r.l=r.h.createTexture());if(\"undefined\"!==typeof HTMLVideoElement&&\nn instanceof HTMLVideoElement){var t=n.videoWidth;var w=n.videoHeight}else\"undefined\"!==typeof HTMLImageElement&&n instanceof HTMLImageElement?(t=n.naturalWidth,w=n.naturalHeight):(t=n.width,w=n.height);w={glName:r.l,width:t,height:w};t=r.g;t.canvas.width=w.width;t.canvas.height=w.height;t.activeTexture(t.TEXTURE0);r.h.bindTexture2d(r.l);t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n);r.h.bindTexture2d(0);r=w;break a;case \"detections\":r=c.o[k.stream];r||(r=new Ac(c.h),c.o[k.stream]=r);\nr.data||(r.data=new r.g.DetectionListData);r.data.reset(n.length);for(w=0;w<n.length;++w){t=n[w];var v=r.data,A=v.setBoundingBox,I=w;var F=t.boundingBox;var u=new lc;W(u,1,F.xCenter);W(u,2,F.yCenter);W(u,3,F.height);W(u,4,F.width);W(u,5,F.rotation);W(u,6,F.rectId);F=Vb(u,mc);A.call(v,I,F);if(t.landmarks)for(v=0;v<t.landmarks.length;++v){u=t.landmarks[v];var z=u.visibility?!0:!1;A=r.data;I=A.addNormalizedLandmark;F=w;u=Object.assign(Object.assign({},u),{visibility:z?u.visibility:0});z=new gc;W(z,1,\nu.x);W(z,2,u.y);W(z,3,u.z);u.visibility&&W(z,4,u.visibility);u=Vb(z,hc);I.call(A,F,u)}if(t.V)for(v=0;v<t.V.length;++v)A=r.data,I=A.addClassification,F=w,u=t.V[v],z=new bc,W(z,2,u.ga),u.index&&W(z,1,u.index),u.label&&W(z,3,u.label),u.displayName&&W(z,4,u.displayName),u=Vb(z,cc),I.call(A,F,u)}r=r.data;break a;default:r={}}}l=r;m=k.stream;switch(k.type){case \"video\":e.pushTexture2d(Object.assign(Object.assign({},l),{stream:m,timestamp:d}));break;case \"detections\":q=l;q.stream=m;q.timestamp=d;e.pushDetectionList(q);\nbreak;default:throw Error(\"Unknown input config type: '\"+k.type+\"'\");}}c.i.send(e);return G(p,c.D,4);case 4:e.delete(),p.g=0}})};\nfunction Mc(a,b,c){var d,e,g,f,h,k,l,m,q,p,n,r,t,w;return J(function(v){switch(v.g){case 1:if(!c)return v.return(b);d={};e=0;g=C(Object.keys(c));for(f=g.next();!f.done;f=g.next())h=f.value,k=c[h],\"string\"!==typeof k&&\"texture\"===k.type&&void 0!==b[k.stream]&&++e;1<e&&(a.I=!1);l=C(Object.keys(c));f=l.next();case 2:if(f.done){v.g=4;break}m=f.value;q=c[m];if(\"string\"===typeof q)return t=d,w=m,G(v,Nc(a,m,b[q]),14);p=b[q.stream];if(\"detection_list\"===q.type){if(p){var A=p.getRectList();for(var I=p.getLandmarksList(),\nF=p.getClassificationsList(),u=[],z=0;z<A.size();++z){var R=Ub(A.get(z),lc,mc);R={boundingBox:{xCenter:X(R,1),yCenter:X(R,2),height:X(R,3),width:X(R,4),rotation:X(R,5,0),rectId:kb(R,6)},landmarks:ib(Ub(I.get(z),ic,kc),gc,1).map(wc),V:vc(Ub(F.get(z),dc,fc))};u.push(R)}A=u}else A=[];d[m]=A;v.g=7;break}if(\"proto_list\"===q.type){if(p){A=Array(p.size());for(I=0;I<p.size();I++)A[I]=p.get(I);p.delete()}else A=[];d[m]=A;v.g=7;break}if(void 0===p){v.g=3;break}if(\"float_list\"===q.type){d[m]=p;v.g=7;break}if(\"proto\"===\nq.type){d[m]=p;v.g=7;break}if(\"texture\"!==q.type)throw Error(\"Unknown output config type: '\"+q.type+\"'\");n=a.u[m];n||(n=new xc(a.h,a.G),a.u[m]=n);return G(v,yc(n,p,a.I),13);case 13:r=v.h,d[m]=r;case 7:q.transform&&d[m]&&(d[m]=q.transform(d[m]));v.g=3;break;case 14:t[w]=v.h;case 3:f=l.next();v.g=2;break;case 4:return v.return(d)}})}\nfunction Nc(a,b,c){var d;return J(function(e){return\"number\"===typeof c||c instanceof Uint8Array||c instanceof a.h.Uint8BlobList?e.return(c):c instanceof a.h.Texture2dDataOut?(d=a.u[b],d||(d=new xc(a.h,a.G),a.u[b]=d),e.return(yc(d,c,a.I))):e.return(void 0)})}\nfunction Kc(a,b){for(var c=b.name||\"$\",d=[].concat(D(b.wants)),e=new a.h.StringList,g=C(b.wants),f=g.next();!f.done;f=g.next())e.push_back(f.value);g=a.h.PacketListener.implement({onResults:function(h){for(var k={},l=0;l<b.wants.length;++l)k[d[l]]=h.get(l);var m=a.listeners[c];m&&(a.D=Mc(a,k,b.outs).then(function(q){q=m(q);for(var p=0;p<b.wants.length;++p){var n=k[d[p]];\"object\"===typeof n&&n.hasOwnProperty&&n.hasOwnProperty(\"delete\")&&n.delete()}q&&(a.D=q)}))}});a.i.attachMultiListener(e,g);e.delete()}\nx.onResults=function(a,b){this.listeners[b||\"$\"]=a};K(\"Solution\",Gc);K(\"OptionType\",{BOOL:0,NUMBER:1,ia:2,0:\"BOOL\",1:\"NUMBER\",2:\"STRING\"});function Oc(a){var b=this;a=a||{};var c={url:\"face_detection_short.binarypb\"},d={type:1,graphOptionXref:{calculatorType:\"TensorsToDetectionsCalculator\",calculatorName:\"facedetectionshortrangegpu__facedetectionshortrangecommon__TensorsToDetectionsCalculator\",fieldName:\"min_score_thresh\"}};this.g=new Gc({locateFile:a.locateFile,files:[{data:!0,url:\"face_detection_short.binarypb\"},{data:!0,url:\"face_detection_short_range.tflite\"},{simd:!0,url:\"face_detection_solution_simd_wasm_bin.js\"},{simd:!1,url:\"face_detection_solution_wasm_bin.js\"}],\ngraph:c,listeners:[{wants:[\"detections\",\"image_transformed\"],outs:{image:\"image_transformed\",detections:{type:\"detection_list\",stream:\"detections\"}}}],inputs:{image:{type:\"video\",stream:\"input_frames_gpu\"}},options:{useCpuInference:{type:0,graphOptionXref:{calculatorType:\"InferenceCalculator\",fieldName:\"use_cpu_inference\"},default:\"object\"!==typeof window||void 0===window.navigator?!1:\"iPad Simulator;iPhone Simulator;iPod Simulator;iPad;iPhone;iPod\".split(\";\").includes(navigator.platform)||navigator.userAgent.includes(\"Mac\")&&\n\"ontouchend\"in document},selfieMode:{type:0,graphOptionXref:{calculatorType:\"GlScalerCalculator\",calculatorIndex:1,fieldName:\"flip_horizontal\"}},model:{type:0,onChange:function(e){var g,f,h,k,l,m;return J(function(q){switch(q.g){case 1:g=\"short\"===e?[\"face_detection_short_range.tflite\"]:[\"face_detection_full_range_sparse.tflite\"],f=C(g),h=f.next();case 2:if(h.done){q.g=4;break}k=h.value;l=\"third_party/mediapipe/modules/face_detection/\"+k;return G(q,Ic(b.g,k),5);case 5:m=q.h;b.g.overrideFile(l,m);\nh=f.next();q.g=2;break;case 4:return c.url=\"short\"===e?\"face_detection_short.binarypb\":\"face_detection_full.binarypb\",d.graphOptionXref.calculatorName=\"short\"===e?\"facedetectionshortrangegpu__facedetectionshortrangecommon__TensorsToDetectionsCalculator\":\"facedetectionfullrangegpu__facedetectionfullrangecommon__TensorsToDetectionsCalculator\",q.return(!0)}})}},minDetectionConfidence:d}})}x=Oc.prototype;x.close=function(){this.g.close();return Promise.resolve()};x.onResults=function(a){this.g.onResults(a)};\nx.initialize=function(){var a=this;return J(function(b){return G(b,a.g.initialize(),0)})};x.reset=function(){this.g.reset()};x.send=function(a){var b=this;return J(function(c){return G(c,b.g.send(a),0)})};x.setOptions=function(a){this.g.setOptions(a)};K(\"FaceDetection\",Oc);K(\"FACEDETECTION_LIPS\",nc);K(\"FACEDETECTION_LEFT_EYE\",oc);K(\"FACEDETECTION_LEFT_EYEBROW\",pc);K(\"FACEDETECTION_RIGHT_EYE\",qc);K(\"FACEDETECTION_RIGHT_EYEBROW\",rc);K(\"FACEDETECTION_FACE_OVAL\",sc);K(\"FACEDETECTION_CONTOURS\",tc);\nK(\"FACEDETECTION_TESSELATION\",[[127,34],[34,139],[139,127],[11,0],[0,37],[37,11],[232,231],[231,120],[120,232],[72,37],[37,39],[39,72],[128,121],[121,47],[47,128],[232,121],[121,128],[128,232],[104,69],[69,67],[67,104],[175,171],[171,148],[148,175],[118,50],[50,101],[101,118],[73,39],[39,40],[40,73],[9,151],[151,108],[108,9],[48,115],[115,131],[131,48],[194,204],[204,211],[211,194],[74,40],[40,185],[185,74],[80,42],[42,183],[183,80],[40,92],[92,186],[186,40],[230,229],[229,118],[118,230],[202,212],\n[212,214],[214,202],[83,18],[18,17],[17,83],[76,61],[61,146],[146,76],[160,29],[29,30],[30,160],[56,157],[157,173],[173,56],[106,204],[204,194],[194,106],[135,214],[214,192],[192,135],[203,165],[165,98],[98,203],[21,71],[71,68],[68,21],[51,45],[45,4],[4,51],[144,24],[24,23],[23,144],[77,146],[146,91],[91,77],[205,50],[50,187],[187,205],[201,200],[200,18],[18,201],[91,106],[106,182],[182,91],[90,91],[91,181],[181,90],[85,84],[84,17],[17,85],[206,203],[203,36],[36,206],[148,171],[171,140],[140,148],\n[92,40],[40,39],[39,92],[193,189],[189,244],[244,193],[159,158],[158,28],[28,159],[247,246],[246,161],[161,247],[236,3],[3,196],[196,236],[54,68],[68,104],[104,54],[193,168],[168,8],[8,193],[117,228],[228,31],[31,117],[189,193],[193,55],[55,189],[98,97],[97,99],[99,98],[126,47],[47,100],[100,126],[166,79],[79,218],[218,166],[155,154],[154,26],[26,155],[209,49],[49,131],[131,209],[135,136],[136,150],[150,135],[47,126],[126,217],[217,47],[223,52],[52,53],[53,223],[45,51],[51,134],[134,45],[211,170],\n[170,140],[140,211],[67,69],[69,108],[108,67],[43,106],[106,91],[91,43],[230,119],[119,120],[120,230],[226,130],[130,247],[247,226],[63,53],[53,52],[52,63],[238,20],[20,242],[242,238],[46,70],[70,156],[156,46],[78,62],[62,96],[96,78],[46,53],[53,63],[63,46],[143,34],[34,227],[227,143],[123,117],[117,111],[111,123],[44,125],[125,19],[19,44],[236,134],[134,51],[51,236],[216,206],[206,205],[205,216],[154,153],[153,22],[22,154],[39,37],[37,167],[167,39],[200,201],[201,208],[208,200],[36,142],[142,100],\n[100,36],[57,212],[212,202],[202,57],[20,60],[60,99],[99,20],[28,158],[158,157],[157,28],[35,226],[226,113],[113,35],[160,159],[159,27],[27,160],[204,202],[202,210],[210,204],[113,225],[225,46],[46,113],[43,202],[202,204],[204,43],[62,76],[76,77],[77,62],[137,123],[123,116],[116,137],[41,38],[38,72],[72,41],[203,129],[129,142],[142,203],[64,98],[98,240],[240,64],[49,102],[102,64],[64,49],[41,73],[73,74],[74,41],[212,216],[216,207],[207,212],[42,74],[74,184],[184,42],[169,170],[170,211],[211,169],\n[170,149],[149,176],[176,170],[105,66],[66,69],[69,105],[122,6],[6,168],[168,122],[123,147],[147,187],[187,123],[96,77],[77,90],[90,96],[65,55],[55,107],[107,65],[89,90],[90,180],[180,89],[101,100],[100,120],[120,101],[63,105],[105,104],[104,63],[93,137],[137,227],[227,93],[15,86],[86,85],[85,15],[129,102],[102,49],[49,129],[14,87],[87,86],[86,14],[55,8],[8,9],[9,55],[100,47],[47,121],[121,100],[145,23],[23,22],[22,145],[88,89],[89,179],[179,88],[6,122],[122,196],[196,6],[88,95],[95,96],[96,88],[138,\n172],[172,136],[136,138],[215,58],[58,172],[172,215],[115,48],[48,219],[219,115],[42,80],[80,81],[81,42],[195,3],[3,51],[51,195],[43,146],[146,61],[61,43],[171,175],[175,199],[199,171],[81,82],[82,38],[38,81],[53,46],[46,225],[225,53],[144,163],[163,110],[110,144],[52,65],[65,66],[66,52],[229,228],[228,117],[117,229],[34,127],[127,234],[234,34],[107,108],[108,69],[69,107],[109,108],[108,151],[151,109],[48,64],[64,235],[235,48],[62,78],[78,191],[191,62],[129,209],[209,126],[126,129],[111,35],[35,143],\n[143,111],[117,123],[123,50],[50,117],[222,65],[65,52],[52,222],[19,125],[125,141],[141,19],[221,55],[55,65],[65,221],[3,195],[195,197],[197,3],[25,7],[7,33],[33,25],[220,237],[237,44],[44,220],[70,71],[71,139],[139,70],[122,193],[193,245],[245,122],[247,130],[130,33],[33,247],[71,21],[21,162],[162,71],[170,169],[169,150],[150,170],[188,174],[174,196],[196,188],[216,186],[186,92],[92,216],[2,97],[97,167],[167,2],[141,125],[125,241],[241,141],[164,167],[167,37],[37,164],[72,38],[38,12],[12,72],[38,\n82],[82,13],[13,38],[63,68],[68,71],[71,63],[226,35],[35,111],[111,226],[101,50],[50,205],[205,101],[206,92],[92,165],[165,206],[209,198],[198,217],[217,209],[165,167],[167,97],[97,165],[220,115],[115,218],[218,220],[133,112],[112,243],[243,133],[239,238],[238,241],[241,239],[214,135],[135,169],[169,214],[190,173],[173,133],[133,190],[171,208],[208,32],[32,171],[125,44],[44,237],[237,125],[86,87],[87,178],[178,86],[85,86],[86,179],[179,85],[84,85],[85,180],[180,84],[83,84],[84,181],[181,83],[201,\n83],[83,182],[182,201],[137,93],[93,132],[132,137],[76,62],[62,183],[183,76],[61,76],[76,184],[184,61],[57,61],[61,185],[185,57],[212,57],[57,186],[186,212],[214,207],[207,187],[187,214],[34,143],[143,156],[156,34],[79,239],[239,237],[237,79],[123,137],[137,177],[177,123],[44,1],[1,4],[4,44],[201,194],[194,32],[32,201],[64,102],[102,129],[129,64],[213,215],[215,138],[138,213],[59,166],[166,219],[219,59],[242,99],[99,97],[97,242],[2,94],[94,141],[141,2],[75,59],[59,235],[235,75],[24,110],[110,228],\n[228,24],[25,130],[130,226],[226,25],[23,24],[24,229],[229,23],[22,23],[23,230],[230,22],[26,22],[22,231],[231,26],[112,26],[26,232],[232,112],[189,190],[190,243],[243,189],[221,56],[56,190],[190,221],[28,56],[56,221],[221,28],[27,28],[28,222],[222,27],[29,27],[27,223],[223,29],[30,29],[29,224],[224,30],[247,30],[30,225],[225,247],[238,79],[79,20],[20,238],[166,59],[59,75],[75,166],[60,75],[75,240],[240,60],[147,177],[177,215],[215,147],[20,79],[79,166],[166,20],[187,147],[147,213],[213,187],[112,\n233],[233,244],[244,112],[233,128],[128,245],[245,233],[128,114],[114,188],[188,128],[114,217],[217,174],[174,114],[131,115],[115,220],[220,131],[217,198],[198,236],[236,217],[198,131],[131,134],[134,198],[177,132],[132,58],[58,177],[143,35],[35,124],[124,143],[110,163],[163,7],[7,110],[228,110],[110,25],[25,228],[356,389],[389,368],[368,356],[11,302],[302,267],[267,11],[452,350],[350,349],[349,452],[302,303],[303,269],[269,302],[357,343],[343,277],[277,357],[452,453],[453,357],[357,452],[333,332],\n[332,297],[297,333],[175,152],[152,377],[377,175],[347,348],[348,330],[330,347],[303,304],[304,270],[270,303],[9,336],[336,337],[337,9],[278,279],[279,360],[360,278],[418,262],[262,431],[431,418],[304,408],[408,409],[409,304],[310,415],[415,407],[407,310],[270,409],[409,410],[410,270],[450,348],[348,347],[347,450],[422,430],[430,434],[434,422],[313,314],[314,17],[17,313],[306,307],[307,375],[375,306],[387,388],[388,260],[260,387],[286,414],[414,398],[398,286],[335,406],[406,418],[418,335],[364,367],\n[367,416],[416,364],[423,358],[358,327],[327,423],[251,284],[284,298],[298,251],[281,5],[5,4],[4,281],[373,374],[374,253],[253,373],[307,320],[320,321],[321,307],[425,427],[427,411],[411,425],[421,313],[313,18],[18,421],[321,405],[405,406],[406,321],[320,404],[404,405],[405,320],[315,16],[16,17],[17,315],[426,425],[425,266],[266,426],[377,400],[400,369],[369,377],[322,391],[391,269],[269,322],[417,465],[465,464],[464,417],[386,257],[257,258],[258,386],[466,260],[260,388],[388,466],[456,399],[399,\n419],[419,456],[284,332],[332,333],[333,284],[417,285],[285,8],[8,417],[346,340],[340,261],[261,346],[413,441],[441,285],[285,413],[327,460],[460,328],[328,327],[355,371],[371,329],[329,355],[392,439],[439,438],[438,392],[382,341],[341,256],[256,382],[429,420],[420,360],[360,429],[364,394],[394,379],[379,364],[277,343],[343,437],[437,277],[443,444],[444,283],[283,443],[275,440],[440,363],[363,275],[431,262],[262,369],[369,431],[297,338],[338,337],[337,297],[273,375],[375,321],[321,273],[450,451],\n[451,349],[349,450],[446,342],[342,467],[467,446],[293,334],[334,282],[282,293],[458,461],[461,462],[462,458],[276,353],[353,383],[383,276],[308,324],[324,325],[325,308],[276,300],[300,293],[293,276],[372,345],[345,447],[447,372],[352,345],[345,340],[340,352],[274,1],[1,19],[19,274],[456,248],[248,281],[281,456],[436,427],[427,425],[425,436],[381,256],[256,252],[252,381],[269,391],[391,393],[393,269],[200,199],[199,428],[428,200],[266,330],[330,329],[329,266],[287,273],[273,422],[422,287],[250,462],\n[462,328],[328,250],[258,286],[286,384],[384,258],[265,353],[353,342],[342,265],[387,259],[259,257],[257,387],[424,431],[431,430],[430,424],[342,353],[353,276],[276,342],[273,335],[335,424],[424,273],[292,325],[325,307],[307,292],[366,447],[447,345],[345,366],[271,303],[303,302],[302,271],[423,266],[266,371],[371,423],[294,455],[455,460],[460,294],[279,278],[278,294],[294,279],[271,272],[272,304],[304,271],[432,434],[434,427],[427,432],[272,407],[407,408],[408,272],[394,430],[430,431],[431,394],[395,\n369],[369,400],[400,395],[334,333],[333,299],[299,334],[351,417],[417,168],[168,351],[352,280],[280,411],[411,352],[325,319],[319,320],[320,325],[295,296],[296,336],[336,295],[319,403],[403,404],[404,319],[330,348],[348,349],[349,330],[293,298],[298,333],[333,293],[323,454],[454,447],[447,323],[15,16],[16,315],[315,15],[358,429],[429,279],[279,358],[14,15],[15,316],[316,14],[285,336],[336,9],[9,285],[329,349],[349,350],[350,329],[374,380],[380,252],[252,374],[318,402],[402,403],[403,318],[6,197],\n[197,419],[419,6],[318,319],[319,325],[325,318],[367,364],[364,365],[365,367],[435,367],[367,397],[397,435],[344,438],[438,439],[439,344],[272,271],[271,311],[311,272],[195,5],[5,281],[281,195],[273,287],[287,291],[291,273],[396,428],[428,199],[199,396],[311,271],[271,268],[268,311],[283,444],[444,445],[445,283],[373,254],[254,339],[339,373],[282,334],[334,296],[296,282],[449,347],[347,346],[346,449],[264,447],[447,454],[454,264],[336,296],[296,299],[299,336],[338,10],[10,151],[151,338],[278,439],\n[439,455],[455,278],[292,407],[407,415],[415,292],[358,371],[371,355],[355,358],[340,345],[345,372],[372,340],[346,347],[347,280],[280,346],[442,443],[443,282],[282,442],[19,94],[94,370],[370,19],[441,442],[442,295],[295,441],[248,419],[419,197],[197,248],[263,255],[255,359],[359,263],[440,275],[275,274],[274,440],[300,383],[383,368],[368,300],[351,412],[412,465],[465,351],[263,467],[467,466],[466,263],[301,368],[368,389],[389,301],[395,378],[378,379],[379,395],[412,351],[351,419],[419,412],[436,\n426],[426,322],[322,436],[2,164],[164,393],[393,2],[370,462],[462,461],[461,370],[164,0],[0,267],[267,164],[302,11],[11,12],[12,302],[268,12],[12,13],[13,268],[293,300],[300,301],[301,293],[446,261],[261,340],[340,446],[330,266],[266,425],[425,330],[426,423],[423,391],[391,426],[429,355],[355,437],[437,429],[391,327],[327,326],[326,391],[440,457],[457,438],[438,440],[341,382],[382,362],[362,341],[459,457],[457,461],[461,459],[434,430],[430,394],[394,434],[414,463],[463,362],[362,414],[396,369],[369,\n262],[262,396],[354,461],[461,457],[457,354],[316,403],[403,402],[402,316],[315,404],[404,403],[403,315],[314,405],[405,404],[404,314],[313,406],[406,405],[405,313],[421,418],[418,406],[406,421],[366,401],[401,361],[361,366],[306,408],[408,407],[407,306],[291,409],[409,408],[408,291],[287,410],[410,409],[409,287],[432,436],[436,410],[410,432],[434,416],[416,411],[411,434],[264,368],[368,383],[383,264],[309,438],[438,457],[457,309],[352,376],[376,401],[401,352],[274,275],[275,4],[4,274],[421,428],\n[428,262],[262,421],[294,327],[327,358],[358,294],[433,416],[416,367],[367,433],[289,455],[455,439],[439,289],[462,370],[370,326],[326,462],[2,326],[326,370],[370,2],[305,460],[460,455],[455,305],[254,449],[449,448],[448,254],[255,261],[261,446],[446,255],[253,450],[450,449],[449,253],[252,451],[451,450],[450,252],[256,452],[452,451],[451,256],[341,453],[453,452],[452,341],[413,464],[464,463],[463,413],[441,413],[413,414],[414,441],[258,442],[442,441],[441,258],[257,443],[443,442],[442,257],[259,\n444],[444,443],[443,259],[260,445],[445,444],[444,260],[467,342],[342,445],[445,467],[459,458],[458,250],[250,459],[289,392],[392,290],[290,289],[290,328],[328,460],[460,290],[376,433],[433,435],[435,376],[250,290],[290,392],[392,250],[411,416],[416,433],[433,411],[341,463],[463,464],[464,341],[453,464],[464,465],[465,453],[357,465],[465,412],[412,357],[343,412],[412,399],[399,343],[360,363],[363,440],[440,360],[437,399],[399,456],[456,437],[420,456],[456,363],[363,420],[401,435],[435,288],[288,401],\n[372,383],[383,353],[353,372],[339,255],[255,249],[249,339],[448,261],[261,255],[255,448],[133,243],[243,190],[190,133],[133,155],[155,112],[112,133],[33,246],[246,247],[247,33],[33,130],[130,25],[25,33],[398,384],[384,286],[286,398],[362,398],[398,414],[414,362],[362,463],[463,341],[341,362],[263,359],[359,467],[467,263],[263,249],[249,255],[255,263],[466,467],[467,260],[260,466],[75,60],[60,166],[166,75],[238,239],[239,79],[79,238],[162,127],[127,139],[139,162],[72,11],[11,37],[37,72],[121,232],\n[232,120],[120,121],[73,72],[72,39],[39,73],[114,128],[128,47],[47,114],[233,232],[232,128],[128,233],[103,104],[104,67],[67,103],[152,175],[175,148],[148,152],[119,118],[118,101],[101,119],[74,73],[73,40],[40,74],[107,9],[9,108],[108,107],[49,48],[48,131],[131,49],[32,194],[194,211],[211,32],[184,74],[74,185],[185,184],[191,80],[80,183],[183,191],[185,40],[40,186],[186,185],[119,230],[230,118],[118,119],[210,202],[202,214],[214,210],[84,83],[83,17],[17,84],[77,76],[76,146],[146,77],[161,160],[160,\n30],[30,161],[190,56],[56,173],[173,190],[182,106],[106,194],[194,182],[138,135],[135,192],[192,138],[129,203],[203,98],[98,129],[54,21],[21,68],[68,54],[5,51],[51,4],[4,5],[145,144],[144,23],[23,145],[90,77],[77,91],[91,90],[207,205],[205,187],[187,207],[83,201],[201,18],[18,83],[181,91],[91,182],[182,181],[180,90],[90,181],[181,180],[16,85],[85,17],[17,16],[205,206],[206,36],[36,205],[176,148],[148,140],[140,176],[165,92],[92,39],[39,165],[245,193],[193,244],[244,245],[27,159],[159,28],[28,27],\n[30,247],[247,161],[161,30],[174,236],[236,196],[196,174],[103,54],[54,104],[104,103],[55,193],[193,8],[8,55],[111,117],[117,31],[31,111],[221,189],[189,55],[55,221],[240,98],[98,99],[99,240],[142,126],[126,100],[100,142],[219,166],[166,218],[218,219],[112,155],[155,26],[26,112],[198,209],[209,131],[131,198],[169,135],[135,150],[150,169],[114,47],[47,217],[217,114],[224,223],[223,53],[53,224],[220,45],[45,134],[134,220],[32,211],[211,140],[140,32],[109,67],[67,108],[108,109],[146,43],[43,91],[91,\n146],[231,230],[230,120],[120,231],[113,226],[226,247],[247,113],[105,63],[63,52],[52,105],[241,238],[238,242],[242,241],[124,46],[46,156],[156,124],[95,78],[78,96],[96,95],[70,46],[46,63],[63,70],[116,143],[143,227],[227,116],[116,123],[123,111],[111,116],[1,44],[44,19],[19,1],[3,236],[236,51],[51,3],[207,216],[216,205],[205,207],[26,154],[154,22],[22,26],[165,39],[39,167],[167,165],[199,200],[200,208],[208,199],[101,36],[36,100],[100,101],[43,57],[57,202],[202,43],[242,20],[20,99],[99,242],[56,\n28],[28,157],[157,56],[124,35],[35,113],[113,124],[29,160],[160,27],[27,29],[211,204],[204,210],[210,211],[124,113],[113,46],[46,124],[106,43],[43,204],[204,106],[96,62],[62,77],[77,96],[227,137],[137,116],[116,227],[73,41],[41,72],[72,73],[36,203],[203,142],[142,36],[235,64],[64,240],[240,235],[48,49],[49,64],[64,48],[42,41],[41,74],[74,42],[214,212],[212,207],[207,214],[183,42],[42,184],[184,183],[210,169],[169,211],[211,210],[140,170],[170,176],[176,140],[104,105],[105,69],[69,104],[193,122],[122,\n168],[168,193],[50,123],[123,187],[187,50],[89,96],[96,90],[90,89],[66,65],[65,107],[107,66],[179,89],[89,180],[180,179],[119,101],[101,120],[120,119],[68,63],[63,104],[104,68],[234,93],[93,227],[227,234],[16,15],[15,85],[85,16],[209,129],[129,49],[49,209],[15,14],[14,86],[86,15],[107,55],[55,9],[9,107],[120,100],[100,121],[121,120],[153,145],[145,22],[22,153],[178,88],[88,179],[179,178],[197,6],[6,196],[196,197],[89,88],[88,96],[96,89],[135,138],[138,136],[136,135],[138,215],[215,172],[172,138],\n[218,115],[115,219],[219,218],[41,42],[42,81],[81,41],[5,195],[195,51],[51,5],[57,43],[43,61],[61,57],[208,171],[171,199],[199,208],[41,81],[81,38],[38,41],[224,53],[53,225],[225,224],[24,144],[144,110],[110,24],[105,52],[52,66],[66,105],[118,229],[229,117],[117,118],[227,34],[34,234],[234,227],[66,107],[107,69],[69,66],[10,109],[109,151],[151,10],[219,48],[48,235],[235,219],[183,62],[62,191],[191,183],[142,129],[129,126],[126,142],[116,111],[111,143],[143,116],[118,117],[117,50],[50,118],[223,222],\n[222,52],[52,223],[94,19],[19,141],[141,94],[222,221],[221,65],[65,222],[196,3],[3,197],[197,196],[45,220],[220,44],[44,45],[156,70],[70,139],[139,156],[188,122],[122,245],[245,188],[139,71],[71,162],[162,139],[149,170],[170,150],[150,149],[122,188],[188,196],[196,122],[206,216],[216,92],[92,206],[164,2],[2,167],[167,164],[242,141],[141,241],[241,242],[0,164],[164,37],[37,0],[11,72],[72,12],[12,11],[12,38],[38,13],[13,12],[70,63],[63,71],[71,70],[31,226],[226,111],[111,31],[36,101],[101,205],[205,\n36],[203,206],[206,165],[165,203],[126,209],[209,217],[217,126],[98,165],[165,97],[97,98],[237,220],[220,218],[218,237],[237,239],[239,241],[241,237],[210,214],[214,169],[169,210],[140,171],[171,32],[32,140],[241,125],[125,237],[237,241],[179,86],[86,178],[178,179],[180,85],[85,179],[179,180],[181,84],[84,180],[180,181],[182,83],[83,181],[181,182],[194,201],[201,182],[182,194],[177,137],[137,132],[132,177],[184,76],[76,183],[183,184],[185,61],[61,184],[184,185],[186,57],[57,185],[185,186],[216,212],\n[212,186],[186,216],[192,214],[214,187],[187,192],[139,34],[34,156],[156,139],[218,79],[79,237],[237,218],[147,123],[123,177],[177,147],[45,44],[44,4],[4,45],[208,201],[201,32],[32,208],[98,64],[64,129],[129,98],[192,213],[213,138],[138,192],[235,59],[59,219],[219,235],[141,242],[242,97],[97,141],[97,2],[2,141],[141,97],[240,75],[75,235],[235,240],[229,24],[24,228],[228,229],[31,25],[25,226],[226,31],[230,23],[23,229],[229,230],[231,22],[22,230],[230,231],[232,26],[26,231],[231,232],[233,112],[112,\n232],[232,233],[244,189],[189,243],[243,244],[189,221],[221,190],[190,189],[222,28],[28,221],[221,222],[223,27],[27,222],[222,223],[224,29],[29,223],[223,224],[225,30],[30,224],[224,225],[113,247],[247,225],[225,113],[99,60],[60,240],[240,99],[213,147],[147,215],[215,213],[60,20],[20,166],[166,60],[192,187],[187,213],[213,192],[243,112],[112,244],[244,243],[244,233],[233,245],[245,244],[245,128],[128,188],[188,245],[188,114],[114,174],[174,188],[134,131],[131,220],[220,134],[174,217],[217,236],[236,\n174],[236,198],[198,134],[134,236],[215,177],[177,58],[58,215],[156,143],[143,124],[124,156],[25,110],[110,7],[7,25],[31,228],[228,25],[25,31],[264,356],[356,368],[368,264],[0,11],[11,267],[267,0],[451,452],[452,349],[349,451],[267,302],[302,269],[269,267],[350,357],[357,277],[277,350],[350,452],[452,357],[357,350],[299,333],[333,297],[297,299],[396,175],[175,377],[377,396],[280,347],[347,330],[330,280],[269,303],[303,270],[270,269],[151,9],[9,337],[337,151],[344,278],[278,360],[360,344],[424,418],\n[418,431],[431,424],[270,304],[304,409],[409,270],[272,310],[310,407],[407,272],[322,270],[270,410],[410,322],[449,450],[450,347],[347,449],[432,422],[422,434],[434,432],[18,313],[313,17],[17,18],[291,306],[306,375],[375,291],[259,387],[387,260],[260,259],[424,335],[335,418],[418,424],[434,364],[364,416],[416,434],[391,423],[423,327],[327,391],[301,251],[251,298],[298,301],[275,281],[281,4],[4,275],[254,373],[373,253],[253,254],[375,307],[307,321],[321,375],[280,425],[425,411],[411,280],[200,421],\n[421,18],[18,200],[335,321],[321,406],[406,335],[321,320],[320,405],[405,321],[314,315],[315,17],[17,314],[423,426],[426,266],[266,423],[396,377],[377,369],[369,396],[270,322],[322,269],[269,270],[413,417],[417,464],[464,413],[385,386],[386,258],[258,385],[248,456],[456,419],[419,248],[298,284],[284,333],[333,298],[168,417],[417,8],[8,168],[448,346],[346,261],[261,448],[417,413],[413,285],[285,417],[326,327],[327,328],[328,326],[277,355],[355,329],[329,277],[309,392],[392,438],[438,309],[381,382],\n[382,256],[256,381],[279,429],[429,360],[360,279],[365,364],[364,379],[379,365],[355,277],[277,437],[437,355],[282,443],[443,283],[283,282],[281,275],[275,363],[363,281],[395,431],[431,369],[369,395],[299,297],[297,337],[337,299],[335,273],[273,321],[321,335],[348,450],[450,349],[349,348],[359,446],[446,467],[467,359],[283,293],[293,282],[282,283],[250,458],[458,462],[462,250],[300,276],[276,383],[383,300],[292,308],[308,325],[325,292],[283,276],[276,293],[293,283],[264,372],[372,447],[447,264],[346,\n352],[352,340],[340,346],[354,274],[274,19],[19,354],[363,456],[456,281],[281,363],[426,436],[436,425],[425,426],[380,381],[381,252],[252,380],[267,269],[269,393],[393,267],[421,200],[200,428],[428,421],[371,266],[266,329],[329,371],[432,287],[287,422],[422,432],[290,250],[250,328],[328,290],[385,258],[258,384],[384,385],[446,265],[265,342],[342,446],[386,387],[387,257],[257,386],[422,424],[424,430],[430,422],[445,342],[342,276],[276,445],[422,273],[273,424],[424,422],[306,292],[292,307],[307,306],\n[352,366],[366,345],[345,352],[268,271],[271,302],[302,268],[358,423],[423,371],[371,358],[327,294],[294,460],[460,327],[331,279],[279,294],[294,331],[303,271],[271,304],[304,303],[436,432],[432,427],[427,436],[304,272],[272,408],[408,304],[395,394],[394,431],[431,395],[378,395],[395,400],[400,378],[296,334],[334,299],[299,296],[6,351],[351,168],[168,6],[376,352],[352,411],[411,376],[307,325],[325,320],[320,307],[285,295],[295,336],[336,285],[320,319],[319,404],[404,320],[329,330],[330,349],[349,\n329],[334,293],[293,333],[333,334],[366,323],[323,447],[447,366],[316,15],[15,315],[315,316],[331,358],[358,279],[279,331],[317,14],[14,316],[316,317],[8,285],[285,9],[9,8],[277,329],[329,350],[350,277],[253,374],[374,252],[252,253],[319,318],[318,403],[403,319],[351,6],[6,419],[419,351],[324,318],[318,325],[325,324],[397,367],[367,365],[365,397],[288,435],[435,397],[397,288],[278,344],[344,439],[439,278],[310,272],[272,311],[311,310],[248,195],[195,281],[281,248],[375,273],[273,291],[291,375],[175,\n396],[396,199],[199,175],[312,311],[311,268],[268,312],[276,283],[283,445],[445,276],[390,373],[373,339],[339,390],[295,282],[282,296],[296,295],[448,449],[449,346],[346,448],[356,264],[264,454],[454,356],[337,336],[336,299],[299,337],[337,338],[338,151],[151,337],[294,278],[278,455],[455,294],[308,292],[292,415],[415,308],[429,358],[358,355],[355,429],[265,340],[340,372],[372,265],[352,346],[346,280],[280,352],[295,442],[442,282],[282,295],[354,19],[19,370],[370,354],[285,441],[441,295],[295,285],\n[195,248],[248,197],[197,195],[457,440],[440,274],[274,457],[301,300],[300,368],[368,301],[417,351],[351,465],[465,417],[251,301],[301,389],[389,251],[394,395],[395,379],[379,394],[399,412],[412,419],[419,399],[410,436],[436,322],[322,410],[326,2],[2,393],[393,326],[354,370],[370,461],[461,354],[393,164],[164,267],[267,393],[268,302],[302,12],[12,268],[312,268],[268,13],[13,312],[298,293],[293,301],[301,298],[265,446],[446,340],[340,265],[280,330],[330,425],[425,280],[322,426],[426,391],[391,322],\n[420,429],[429,437],[437,420],[393,391],[391,326],[326,393],[344,440],[440,438],[438,344],[458,459],[459,461],[461,458],[364,434],[434,394],[394,364],[428,396],[396,262],[262,428],[274,354],[354,457],[457,274],[317,316],[316,402],[402,317],[316,315],[315,403],[403,316],[315,314],[314,404],[404,315],[314,313],[313,405],[405,314],[313,421],[421,406],[406,313],[323,366],[366,361],[361,323],[292,306],[306,407],[407,292],[306,291],[291,408],[408,306],[291,287],[287,409],[409,291],[287,432],[432,410],[410,\n287],[427,434],[434,411],[411,427],[372,264],[264,383],[383,372],[459,309],[309,457],[457,459],[366,352],[352,401],[401,366],[1,274],[274,4],[4,1],[418,421],[421,262],[262,418],[331,294],[294,358],[358,331],[435,433],[433,367],[367,435],[392,289],[289,439],[439,392],[328,462],[462,326],[326,328],[94,2],[2,370],[370,94],[289,305],[305,455],[455,289],[339,254],[254,448],[448,339],[359,255],[255,446],[446,359],[254,253],[253,449],[449,254],[253,252],[252,450],[450,253],[252,256],[256,451],[451,252],\n[256,341],[341,452],[452,256],[414,413],[413,463],[463,414],[286,441],[441,414],[414,286],[286,258],[258,441],[441,286],[258,257],[257,442],[442,258],[257,259],[259,443],[443,257],[259,260],[260,444],[444,259],[260,467],[467,445],[445,260],[309,459],[459,250],[250,309],[305,289],[289,290],[290,305],[305,290],[290,460],[460,305],[401,376],[376,435],[435,401],[309,250],[250,392],[392,309],[376,411],[411,433],[433,376],[453,341],[341,464],[464,453],[357,453],[453,465],[465,357],[343,357],[357,412],[412,\n343],[437,343],[343,399],[399,437],[344,360],[360,440],[440,344],[420,437],[437,456],[456,420],[360,420],[420,363],[363,360],[361,401],[401,288],[288,361],[265,372],[372,353],[353,265],[390,339],[339,249],[249,390],[339,448],[448,255],[255,339]]);K(\"VERSION\",\"0.4.1646425229\");}).call(this);\n","import { BoundingBox } from '@mediapipe/tasks-vision'\n\nexport function convertBoundingBox(box?: BoundingBox) {\n return {\n xMin: box?.originX ?? 0,\n xMax: (box?.originX ?? 0) + (box?.width ?? 0),\n yMin: box?.originY ?? 0,\n yMax: (box?.originY ?? 0) + (box?.height ?? 0),\n width: box?.width ?? 0,\n height: box?.height ?? 0,\n }\n}\n","import '@mediapipe/face_detection'\nimport {\n FaceDetector,\n FaceDetectorResult,\n FilesetResolver,\n} from '@mediapipe/tasks-vision'\nimport {\n preloadFaceDetectorDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { modelCapabilities } from './CapabilityProbing'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { useEffect, useRef, useState } from 'react'\nimport { Frame } from '../utils/getFrameDimensions'\nimport { convertBoundingBox } from './helpers'\n\nexport const defaultFaceDetectorModelPath =\n 'https://websdk-cdn-dev.idmission.com/assets/models/blazeface20240207/blaze_face_short_range.tflite'\nexport const defaultSelfieCaptureModelLoadTimeoutMs = 45000\n\nexport type FaceKeypoint = { x: number; y: number; name: string }\nexport type Face = {\n keypoints: FaceKeypoint[]\n box: {\n xMin: number\n xMax: number\n yMin: number\n yMax: number\n width: number\n height: number\n }\n}\n\nlet detector: FaceDetector\n\nexport async function loadFaceDetector(): Promise<FaceDetector> {\n if (detector) return detector\n\n await preloadFaceDetectorDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for face detector.')\n }\n\n detector = await FaceDetector.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: {\n modelAssetPath: defaultFaceDetectorModelPath,\n delegate: modelCapabilities.delegate,\n },\n runningMode: 'VIDEO',\n },\n )\n\n // const emptyFrame = document.createElement('canvas')\n // detector.detectForVideo(emptyFrame, performance.now())\n // emptyFrame.remove()\n\n return detector\n}\n\nexport function useLoadFaceDetector({\n onModelError,\n modelLoadTimeoutMs = defaultSelfieCaptureModelLoadTimeoutMs,\n}: {\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}) {\n const detector = useRef<FaceDetector | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.faceDetection',\n handleDownloadProgress,\n )\n\n loadFaceDetector()\n .then((model) => {\n detector.current = model\n setModelDownloadProgress(100)\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.faceDetection',\n handleDownloadProgress,\n )\n }\n },\n [modelLoadTimeoutMs],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { detector, ready, modelDownloadProgress, modelError }\n}\n\nexport function makeFaceDetectorPrediction(\n model: FaceDetector,\n imageData: Frame,\n): FaceDetectorResult & { faces: Face[] } {\n const prediction = model.detectForVideo(imageData, performance.now())\n\n const faces = prediction.detections.map<Face>((d) => ({\n box: convertBoundingBox(d.boundingBox),\n keypoints: d.keypoints.map((k) => ({\n ...k,\n x: k.x * imageData.width,\n y: k.y * imageData.height,\n name: k.label ?? '',\n })),\n }))\n\n return { ...prediction, faces }\n}\n","import { defaultDocumentDetectorModelPath } from './DocumentDetection'\nimport { defaultFocusModelPath } from './Focus'\nimport { defaultFaceDetectorModelPath } from './FaceDetection'\nimport { modelCapabilities, probeModelCapabilities } from './CapabilityProbing'\n\nexport const preloadModels = async ({\n documentDetectionModel = true,\n focusModel = true,\n faceDetectionModel = true,\n}: {\n documentDetectionModel?: string | boolean\n focusModel?: string | boolean\n faceDetectionModel?: boolean\n}): Promise<void> => {\n await probeModelCapabilities()\n\n const preloadTasks = []\n\n if (documentDetectionModel) {\n preloadTasks.push(preloadDocumentDetectorDependencies)\n }\n\n if (focusModel) {\n preloadTasks.push(preloadFocusModelDependencies)\n }\n\n if (faceDetectionModel) {\n preloadTasks.push(preloadFaceDetectorDependencies)\n }\n\n await Promise.all(preloadTasks)\n}\n\nexport type PreloadProgress = {\n loaded: number\n total: number\n}\n\nconst progressByUrl: { [url: string]: PreloadProgress } = {}\nexport const progressByUseCase: {\n visionRuntime: PreloadProgress\n documentDetection: PreloadProgress\n focus: PreloadProgress\n faceDetection: PreloadProgress\n} = {\n visionRuntime: { loaded: 0, total: 0 },\n documentDetection: { loaded: 0, total: 0 },\n focus: { loaded: 0, total: 0 },\n faceDetection: { loaded: 0, total: 0 },\n}\n\nexport async function preloadDependency(url: string) {\n const xhr = new XMLHttpRequest()\n return new Promise((resolve) => {\n xhr.addEventListener('progress', (event) => {\n if (!event.lengthComputable) return\n\n progressByUrl[url] = event\n\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress', {\n detail: { url, loaded: event.loaded, total: event.total },\n }),\n )\n })\n\n xhr.addEventListener('loadend', () => {\n resolve(xhr.readyState === 4 && xhr.status === 200)\n })\n xhr.open('GET', url, true)\n xhr.send()\n })\n}\n\nlet documentDetectorPreloading = false,\n focusModelPreloading = false,\n faceDetectorPreloading = false\n\nexport async function preloadDocumentDetectorDependencies(): Promise<void> {\n if (documentDetectorPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!documentDetectorPreloading) resolve()\n }, 100)\n })\n\n documentDetectorPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultDocumentDetectorModelPath]\n\n function handleDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.documentDetection =\n sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.documentDetection', {\n detail: progressByUseCase.documentDetection,\n }),\n )\n }\n\n document.addEventListener('idmission.preloadProgress', handleDownloadProgress)\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleDownloadProgress,\n )\n documentDetectorPreloading = false\n }\n}\n\nexport async function preloadFocusModelDependencies(): Promise<void> {\n if (focusModelPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!focusModelPreloading) resolve()\n }, 100)\n })\n\n focusModelPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultFocusModelPath]\n\n function handleModelDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.focus = sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.focus', {\n detail: progressByUseCase.focus,\n }),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n focusModelPreloading = false\n }\n}\n\nexport async function preloadFaceDetectorDependencies(): Promise<void> {\n if (faceDetectorPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!faceDetectorPreloading) resolve()\n }, 100)\n })\n\n faceDetectorPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultFaceDetectorModelPath]\n\n function handleModelDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.faceDetection', {\n detail: progressByUseCase.faceDetection,\n }),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n faceDetectorPreloading = false\n }\n}\n\nexport function progressToPercentage(progress: PreloadProgress) {\n return progress.total > 0\n ? Math.round((100.0 * progress.loaded) / progress.total)\n : 0\n}\n\nexport function sumUpProgressForDependencies(\n dependencies: string[],\n): PreloadProgress {\n return dependencies.reduce(\n (result, dependency) => {\n const dependencyProgress = progressByUrl[dependency]\n if (!dependencyProgress) return result\n result.loaded += dependencyProgress.loaded\n result.total += dependencyProgress.total\n return result\n },\n { loaded: 0, total: 0 },\n )\n}\n","import {\n FilesetResolver,\n ObjectDetector,\n ObjectDetectorResult,\n} from '@mediapipe/tasks-vision'\nimport {\n preloadDocumentDetectorDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { modelCapabilities } from './CapabilityProbing'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { error as logError } from '../utils/logger'\nimport { convertBoundingBox } from './helpers'\nimport { useEffect, useRef, useState } from 'react'\n\nexport const defaultDocumentDetectorModelPath = `https://websdk-cdn-dev.idmission.com/assets/models/docdetectmp20240611/model_fp16.tflite`\nexport const defaultDocumentDetectionScoreThreshold = 0.1\nexport const defaultDocumentDetectionModelLoadTimeoutMs = 45000\nexport const defaultDocumentDetectionThresholds: DocumentDetectionThresholds = {\n idCard: 0.8,\n passport: 0.5,\n mrz: 0.5,\n pdf417: 0.15,\n}\n\nexport type DocumentType = 'none' | 'idCard' | 'passport'\n\nexport type Label =\n | 'Document'\n | 'MRZ'\n | 'PDF417'\n | 'Primary face'\n | 'Secondary face'\n | 'Glare'\n | 'Punch Hole'\n | 'Passport page'\n\nexport type DetectedObjectBox = {\n xMin: number\n xMax: number\n yMin: number\n yMax: number\n width: number\n height: number\n}\n\nexport type DetectedObject = {\n box: DetectedObjectBox\n label: Label\n score: number\n}\n\nexport type DocumentDetectionThresholds = {\n idCard?: number\n passport?: number\n mrz?: number\n pdf417?: number\n}\n\nconst detectors: { [id: string]: ObjectDetector } = {}\n\nexport async function loadDocumentDetector(\n modelAssetPath = defaultDocumentDetectorModelPath,\n scoreThreshold = defaultDocumentDetectionScoreThreshold,\n): Promise<ObjectDetector> {\n const id = `${modelAssetPath}:${scoreThreshold}`\n if (detectors[id]) return detectors[id]\n\n await preloadDocumentDetectorDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n detectors[id] = await ObjectDetector.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: { modelAssetPath, delegate: modelCapabilities.delegate },\n scoreThreshold,\n runningMode: 'VIDEO',\n },\n )\n\n // const emptyFrame = document.createElement('canvas')\n // detectors[id].detectForVideo(emptyFrame, performance.now())\n // emptyFrame.remove()\n\n return detectors[id]\n}\n\nexport function useLoadDocumentDetector({\n modelPath = defaultDocumentDetectorModelPath,\n modelLoadTimeoutMs = defaultDocumentDetectionModelLoadTimeoutMs,\n scoreThreshold = defaultDocumentDetectionScoreThreshold,\n onModelError,\n}: {\n modelPath?: string\n modelLoadTimeoutMs?: number\n scoreThreshold?: number\n onModelError?: (error: Error) => void\n}) {\n const detector = useRef<ObjectDetector | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.documentDetection',\n handleDownloadProgress,\n )\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n loadDocumentDetector(modelPath, scoreThreshold)\n .then((model) => {\n detector.current = model\n setModelDownloadProgress(100)\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.documentDetection',\n handleDownloadProgress,\n )\n }\n },\n [modelLoadTimeoutMs, modelPath, scoreThreshold],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { detector, ready, modelDownloadProgress, modelError, setModelError }\n}\n\nexport type DocumentDetectionPrediction = {\n detectedObjects: DetectedObject[]\n detectionTime: number\n detectionScore: number\n detectionThresholdMet: boolean\n detectedDocumentType: DocumentType\n\n passportDetectionScore: number\n passportDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentInBounds: boolean\n documentTooClose: boolean\n\n frameWidth: number\n frameHeight: number\n\n allZero: boolean\n frameId?: number\n}\n\nexport type ObjectDetectorPrediction = ObjectDetectorResult & {\n time: number\n frameWidth: number\n frameHeight: number\n}\n\nexport async function makeDocumentDetectorPrediction(\n detector: ObjectDetector,\n frame: HTMLCanvasElement,\n): Promise<ObjectDetectorPrediction | null> {\n const startedAt = new Date()\n let prediction: ObjectDetectorResult | null\n\n // Detectors can throw errors, for example when using custom URLs that\n // contain a model that doesn't provide the expected output.\n try {\n prediction = detector.detectForVideo(frame, performance.now())\n const time = new Date().getTime() - startedAt.getTime()\n const frameWidth = frame.width\n const frameHeight = frame.height\n return { ...prediction, time, frameWidth, frameHeight }\n } catch (e) {\n logError('caught object detection error', e)\n }\n\n return null\n}\n\nexport function processDocumentDetectorPrediction(\n prediction: ObjectDetectorPrediction,\n thresholds: DocumentDetectionThresholds,\n): DocumentDetectionPrediction {\n const { detections, frameWidth, frameHeight, time } = prediction\n const detectedObjects = applyNonMaxSuppression(\n detections.map<DetectedObject>((d) => {\n const category = d.categories?.[0]\n\n return {\n label: category?.categoryName as Label,\n score: category?.score,\n box: convertBoundingBox(d.boundingBox),\n }\n }),\n )\n\n const allZero =\n detections.length > 0 &&\n !detections.some(({ boundingBox }) =>\n Object.values(boundingBox ?? {}).some((n) => n > 0),\n )\n\n const bestIdCard = detectedObjects.find((obj) => obj.label === 'Document')\n const bestPassportPage = detectedObjects.find(\n (obj) => obj.label === 'Passport page',\n )\n const passportDetectionScore = bestPassportPage?.score ?? 0\n const passportDetectionThresholdMet =\n passportDetectionScore >= (thresholds.passport ?? 0)\n const bestDocument = passportDetectionThresholdMet\n ? bestPassportPage\n : bestIdCard\n const detectionScore = bestDocument?.score ?? 0\n const detectionThreshold = passportDetectionThresholdMet\n ? thresholds.passport\n : thresholds.idCard\n const detectionThresholdMet = detectionScore >= (detectionThreshold ?? 0)\n\n let detectedDocumentType: DocumentType = 'none'\n if (passportDetectionThresholdMet) {\n detectedDocumentType = 'passport'\n } else if (detectionThresholdMet) {\n detectedDocumentType = 'idCard'\n }\n\n const bestMrz = detectedObjects.find((obj) => obj.label === 'MRZ')\n const mrzDetectionScore = bestMrz?.score ?? 0\n const mrzDetectionThresholdMet = mrzDetectionScore >= (thresholds.mrz ?? 0)\n\n const bestPdf417 = detectedObjects.find((obj) => obj.label === 'PDF417')\n const pdf417DetectionScore = bestPdf417?.score ?? 0\n const pdf417DetectionThresholdMet =\n pdf417DetectionScore >= (thresholds.pdf417 ?? 0)\n\n let documentInBounds = false\n if (bestDocument) {\n const boundaryPx = 20\n const {\n xMin: boundaryX,\n yMin: boundaryY,\n width: boundaryWidth,\n height: boundaryHeight,\n } = bestDocument.box\n\n documentInBounds =\n boundaryY > boundaryPx && // Is it valid top edge of ID detected?\n boundaryY + boundaryHeight + boundaryPx < frameHeight && // Is it valid bottom edge less than max video height\n (boundaryX > boundaryPx ||\n (boundaryX < boundaryPx &&\n boundaryX + boundaryWidth > frameWidth * 0.8)) && // If either the left side visible or if not, right edge of ID should be more than 80% of width.\n boundaryX + boundaryWidth + boundaryPx < frameWidth // Valid right edge if it's less than video width.\n }\n\n let documentTooClose = false\n if (bestDocument) {\n const [docWidth, docHeight] = [\n bestDocument.box.width / frameWidth,\n bestDocument.box.height / frameHeight,\n ]\n documentTooClose = docWidth > 0.85 || docHeight > 0.85\n }\n\n return {\n detectedObjects,\n detectionScore,\n detectionTime: time,\n detectionThresholdMet,\n detectedDocumentType,\n passportDetectionScore,\n passportDetectionThresholdMet,\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n bestDocument,\n bestMrz,\n bestPdf417,\n documentInBounds,\n documentTooClose,\n frameWidth,\n frameHeight,\n allZero,\n }\n}\n\nfunction applyNonMaxSuppression(\n detectedObjects: DetectedObject[],\n): DetectedObject[] {\n const maxes: { [label: string]: [number, number] } = {}\n detectedObjects.forEach((obj, i) => {\n if (obj) {\n if (!maxes[obj.label]) maxes[obj.label] = [0, -1]\n if (obj.score > maxes[obj.label][0]) maxes[obj.label] = [obj.score, i]\n }\n })\n return Object.keys(maxes)\n .map((label) => detectedObjects[maxes[label][1]])\n .filter((obj) => !!obj)\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nexport function useFrameLoop(\n fn: (frameId: number) => Promise<void>,\n { throttleMs = 0, autoStart = false },\n) {\n const [running, setRunning] = useState(false)\n const loopId = useRef(0)\n const frameId = useRef(0)\n\n useEffect(\n function runFrameLoop() {\n if (!running) return\n\n let timer: NodeJS.Timeout\n const currentLoopId = loopId.current\n\n async function renderPrediction() {\n if (currentLoopId !== loopId.current) return\n await fn(frameId.current)\n timer = setTimeout(() => {\n frameId.current = requestAnimationFrame(renderPrediction)\n }, throttleMs ?? 0)\n }\n\n renderPrediction().then()\n\n return () => {\n loopId.current += 1\n frameId.current && cancelAnimationFrame(frameId.current)\n timer && clearTimeout(timer)\n }\n },\n [fn, running, throttleMs],\n )\n\n const start = useCallback(() => {\n setRunning(true)\n }, [])\n\n const stop = useCallback(() => {\n loopId.current += 1 // force the loop to stop immediately.\n setRunning(false)\n }, [])\n\n useEffect(\n function startAutomatically() {\n if (autoStart) start()\n return () => {\n stop()\n }\n },\n [autoStart, start, stop],\n )\n\n return { start, stop }\n}\n","import * as React from 'react'\nimport {\n createContext,\n MutableRefObject,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { log } from '../../lib/utils/logger'\nimport {\n defaultDocumentDetectionModelLoadTimeoutMs,\n defaultDocumentDetectionScoreThreshold,\n defaultDocumentDetectorModelPath,\n DocumentDetectionPrediction,\n DocumentDetectionThresholds,\n makeDocumentDetectorPrediction,\n processDocumentDetectorPrediction,\n useLoadDocumentDetector,\n} from '../../lib/models/DocumentDetection'\nimport { useFrameLoop } from '../../lib/models/FrameLoop'\n\ntype PredictionHandler = (\n prediction: DocumentDetectionPrediction,\n) => Promise<void>\n\ntype DocumentDetectionModelState = {\n startDocumentDetection: () => void\n stopDocumentDetection: () => void\n\n documentDetectionModelReady: boolean\n documentDetectionModelDownloadProgress: number\n documentDetectionModelError: Error | null\n\n onDocumentDetected: (handler: PredictionHandler) => void\n detectionTime: number\n\n documentDetectionThresholds: DocumentDetectionThresholds\n setDocumentDetectionThresholds: (value: DocumentDetectionThresholds) => void\n\n documentDetectionLastPredictionCanvas: MutableRefObject<HTMLCanvasElement | null>\n clearDocumentDetectionLastPredictionCanvas: () => void\n}\n\nexport const DocumentDetectionModelContext =\n createContext<DocumentDetectionModelState>({\n startDocumentDetection: () => null,\n stopDocumentDetection: () => null,\n\n documentDetectionModelReady: false,\n documentDetectionModelDownloadProgress: 0,\n documentDetectionModelError: null,\n\n onDocumentDetected: () => null,\n detectionTime: 0,\n\n documentDetectionThresholds: {},\n setDocumentDetectionThresholds: () => null,\n\n documentDetectionLastPredictionCanvas: { current: null },\n clearDocumentDetectionLastPredictionCanvas: () => null,\n })\n\nexport type DocumentDetectionModelProviderProps = {\n autoStart?: boolean\n children: ReactNode\n throttleMs?: number\n documentDetectionModelPath?: string\n documentDetectionModelScoreThreshold?: number\n documentDetectionModelLoadTimeoutMs?: number\n onDocumentDetectionModelError?: (error: Error) => void\n}\n\nexport function DocumentDetectionModelProvider({\n autoStart = true,\n children,\n throttleMs,\n documentDetectionModelPath = defaultDocumentDetectorModelPath,\n documentDetectionModelScoreThreshold = defaultDocumentDetectionScoreThreshold,\n documentDetectionModelLoadTimeoutMs = defaultDocumentDetectionModelLoadTimeoutMs,\n onDocumentDetectionModelError,\n}: DocumentDetectionModelProviderProps): ReactElement {\n const { videoRef, videoLoaded, cameraReady } = useContext(CameraStateContext)\n const lastPredictionCanvas = useRef<HTMLCanvasElement>(null)\n const onPredictionHandler = useRef<PredictionHandler>()\n const [documentDetectionThresholds, setDocumentDetectionThresholds] =\n useState<DocumentDetectionThresholds>({})\n const [detectionTime, setDetectionTime] = useState<number>(0)\n const [timesAllZero, setTimesAllZero] = useState(0)\n const [canvasKey, setCanvasKey] = useState(0)\n const stopDetection = useRef(0)\n\n const { detector, ready, modelDownloadProgress, modelError, setModelError } =\n useLoadDocumentDetector({\n modelPath: documentDetectionModelPath,\n modelLoadTimeoutMs: documentDetectionModelLoadTimeoutMs,\n scoreThreshold: documentDetectionModelScoreThreshold,\n onModelError: onDocumentDetectionModelError,\n })\n\n const { start, stop } = useFrameLoop(\n useCallback(\n async (frameId: number) => {\n if (\n !videoLoaded ||\n !cameraReady ||\n !ready ||\n !videoRef.current ||\n !detector.current ||\n !lastPredictionCanvas.current\n )\n return\n\n const stopDetectionAtStart = stopDetection.current\n const vw = videoRef.current.videoWidth\n const vh = videoRef.current.videoHeight\n lastPredictionCanvas.current.width = vw\n lastPredictionCanvas.current.height = vh\n\n const ctx = lastPredictionCanvas.current.getContext('2d')\n if (ctx && videoRef.current.readyState === 4) {\n if (stopDetectionAtStart !== stopDetection.current) return\n ctx.drawImage(videoRef.current, 0, 0, vw, vh)\n\n const prediction = await makeDocumentDetectorPrediction(\n detector.current,\n lastPredictionCanvas.current,\n )\n if (prediction) {\n const processedPrediction = processDocumentDetectorPrediction(\n prediction,\n documentDetectionThresholds,\n )\n processedPrediction.frameId = frameId\n setDetectionTime(prediction.time)\n log(processedPrediction)\n if (processedPrediction.allZero) setTimesAllZero((n) => n + 1)\n if (stopDetectionAtStart !== stopDetection.current) return\n await onPredictionHandler.current?.(processedPrediction)\n }\n }\n },\n [\n cameraReady,\n detector,\n documentDetectionThresholds,\n ready,\n videoLoaded,\n videoRef,\n ],\n ),\n { throttleMs, autoStart },\n )\n\n useEffect(\n function setErrorIfAllZero() {\n if (timesAllZero >= 2) {\n setModelError(new Error('model is returning all zeroes'))\n }\n },\n [setModelError, timesAllZero],\n )\n\n const onDocumentDetected = useCallback((handler: PredictionHandler) => {\n onPredictionHandler.current = handler\n }, [])\n\n const clearDocumentDetectionLastPredictionCanvas = useCallback(() => {\n stopDetection.current += 1\n setCanvasKey((n) => n + 1)\n }, [])\n\n const value = useMemo<DocumentDetectionModelState>(\n () => ({\n startDocumentDetection: start,\n stopDocumentDetection: stop,\n documentDetectionModelReady: ready,\n documentDetectionModelError: modelError,\n documentDetectionModelDownloadProgress: modelDownloadProgress,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n setDocumentDetectionThresholds,\n documentDetectionLastPredictionCanvas: lastPredictionCanvas,\n clearDocumentDetectionLastPredictionCanvas,\n }),\n [\n start,\n stop,\n ready,\n modelError,\n modelDownloadProgress,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n clearDocumentDetectionLastPredictionCanvas,\n ],\n )\n\n return (\n <DocumentDetectionModelContext.Provider value={value}>\n <InvisibleCanvas key={canvasKey} ref={lastPredictionCanvas} />\n {children}\n </DocumentDetectionModelContext.Provider>\n )\n}\n","import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n DetectedObject,\n DetectedObjectBox,\n DocumentDetectionThresholds,\n DocumentType,\n} from '../../lib/models/DocumentDetection'\nimport { drawToCanvas, InvisibleCanvas } from '../common/InvisibleCanvas'\nimport {\n DocumentDetectionModelContext,\n DocumentDetectionModelProvider,\n DocumentDetectionModelProviderProps,\n} from './DocumentDetectionModelProvider'\nimport {\n FocusModelContext,\n FocusModelProvider,\n FocusModelProviderProps,\n} from './FocusModelProvider'\nimport { isMobile } from '../../lib/utils/isMobile'\nimport { FocusThresholds } from '../../lib/models/Focus'\n\nconst onMobile = isMobile()\n\nexport type IdCapturePrediction = {\n detectedObjects: DetectedObject[]\n detectionTime: number\n detectionScore: number\n detectionThresholdMet: boolean\n detectedDocumentType: DocumentType\n\n passportDetectionScore: number\n passportDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentInBounds: boolean\n documentTooClose: boolean\n\n focusScore: number\n focusThresholdMet: boolean\n focusPredictionTime: number\n\n frameWidth: number\n frameHeight: number\n\n allZero: boolean\n}\n\nexport type IdCaptureThresholds = DocumentDetectionThresholds & {\n focus?: FocusThresholds\n}\n\nexport type BestFrameDetails = {\n boundingBox?: DetectedObjectBox\n documentType: DocumentType\n detectionScore: number\n focusScore: number\n}\n\nexport type BestFrame = BestFrameDetails & {\n canvas: HTMLCanvasElement\n}\n\nexport type IdCaptureModelsState = {\n ready: boolean\n start: () => void\n stop: () => void\n\n modelDownloadProgress: number\n modelError: Error | null\n\n thresholds: IdCaptureThresholds\n setThresholds: (value: IdCaptureThresholds) => void\n\n onPredictionMade: (handler: (prediction: IdCapturePrediction) => void) => void\n\n detectionTime: number\n focusPredictionTime: number\n\n bestFrameDetails: BestFrameDetails | null\n getBestFrame: () => BestFrame | null\n resetBestFrame: () => void\n}\n\nexport const IdCaptureModelsContext = createContext<IdCaptureModelsState>({\n ready: false,\n start: () => null,\n stop: () => null,\n\n modelDownloadProgress: 0,\n modelError: null,\n\n thresholds: {},\n setThresholds: () => null,\n\n onPredictionMade: () => null,\n\n detectionTime: 0,\n focusPredictionTime: 0,\n\n bestFrameDetails: null,\n getBestFrame: () => null,\n resetBestFrame: () => null,\n})\n\nexport type IdCaptureModelsProviderProps = {\n children: ReactNode\n documentDetectionModelUrl?: string | undefined\n focusModelUrl?: string | undefined\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}\n\nexport function IdCaptureModelsProviderInner({\n children,\n onModelError,\n}: IdCaptureModelsProviderProps): ReactElement {\n const {\n documentDetectionModelReady,\n documentDetectionModelDownloadProgress,\n startDocumentDetection,\n stopDocumentDetection,\n documentDetectionLastPredictionCanvas: lastPredictionCanvas,\n clearDocumentDetectionLastPredictionCanvas,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n setDocumentDetectionThresholds,\n documentDetectionModelError,\n } = useContext(DocumentDetectionModelContext)\n const {\n focusModelReady,\n focusModelDownloadProgress,\n makeFocusPrediction,\n focusThresholds,\n setFocusThresholds,\n focusPredictionTime,\n focusModelError,\n } = useContext(FocusModelContext)\n const onPredictionHandler =\n useRef<(prediction: IdCapturePrediction) => void>()\n const [bestFrameDetails, setBestFrameDetails] =\n useState<BestFrameDetails | null>(null)\n const bestPredictionCanvas = useRef<HTMLCanvasElement | null>(null)\n const bestFocusScore = useRef<number>(0)\n const stopDetection = useRef(0)\n\n const thresholds = useMemo(\n () => ({ ...documentDetectionThresholds, focus: focusThresholds }),\n [documentDetectionThresholds, focusThresholds],\n )\n const setThresholds = useCallback(\n (thresholds: IdCaptureThresholds) => {\n setDocumentDetectionThresholds(thresholds)\n if (thresholds.focus) setFocusThresholds(thresholds.focus)\n },\n [setDocumentDetectionThresholds, setFocusThresholds],\n )\n\n useEffect(\n function handleDetections() {\n onDocumentDetected(async (prediction) => {\n if (!lastPredictionCanvas.current) return\n\n const stopDetectionAtStart = stopDetection.current\n let focusPredictionTime = 0,\n focusScore = 0,\n focusThresholdMet = false\n\n if (\n prediction.detectedDocumentType !== 'none' &&\n prediction.detectionThresholdMet &&\n prediction.documentInBounds &&\n !prediction.documentTooClose\n ) {\n const focusPrediction = makeFocusPrediction(\n lastPredictionCanvas.current,\n prediction.bestDocument?.box,\n )\n if (focusPrediction) {\n focusScore = focusPrediction.score\n focusPredictionTime = focusPrediction.predictionTime\n }\n\n const focusThresholdSet =\n thresholds.focus?.[prediction.detectedDocumentType]\n const focusThreshold =\n (onMobile\n ? focusThresholdSet?.mobile\n : focusThresholdSet?.desktop) ?? 0\n focusThresholdMet = focusScore >= focusThreshold\n\n if (\n bestFocusScore.current <= focusScore &&\n stopDetectionAtStart === stopDetection.current\n ) {\n bestFocusScore.current = focusScore\n drawToCanvas(\n bestPredictionCanvas.current,\n lastPredictionCanvas.current,\n )\n setBestFrameDetails({\n boundingBox: prediction.bestDocument?.box,\n documentType: prediction.detectedDocumentType,\n detectionScore: prediction.detectionScore,\n focusScore,\n })\n }\n }\n\n onPredictionHandler.current?.({\n ...prediction,\n focusScore,\n focusPredictionTime,\n focusThresholdMet,\n })\n })\n },\n [\n lastPredictionCanvas,\n makeFocusPrediction,\n onDocumentDetected,\n thresholds.focus,\n ],\n )\n\n const modelError = documentDetectionModelError ?? focusModelError\n useEffect(\n function handleModelErrors() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n const onPredictionMade = useCallback(\n (handler: (prediction: IdCapturePrediction) => void) => {\n onPredictionHandler.current = handler\n },\n [],\n )\n\n const getBestFrame = useCallback((): BestFrame | null => {\n if (!bestFrameDetails || !bestPredictionCanvas.current) return null\n return { ...bestFrameDetails, canvas: bestPredictionCanvas.current }\n }, [bestFrameDetails])\n\n const [canvasKey, setCanvasKey] = useState(0)\n const resetBestFrame = useCallback(() => {\n stopDetection.current += 1\n setCanvasKey((n) => n + 1)\n clearDocumentDetectionLastPredictionCanvas()\n setBestFrameDetails(null)\n bestFocusScore.current = 0\n }, [clearDocumentDetectionLastPredictionCanvas])\n\n const value = useMemo<IdCaptureModelsState>(\n () => ({\n ready: documentDetectionModelReady && focusModelReady,\n modelDownloadProgress:\n (documentDetectionModelDownloadProgress + focusModelDownloadProgress) /\n 2,\n modelError,\n start: startDocumentDetection,\n stop: stopDocumentDetection,\n thresholds,\n setThresholds,\n onPredictionMade,\n detectionTime,\n focusPredictionTime,\n getBestFrame,\n resetBestFrame,\n bestFrameDetails,\n }),\n [\n bestFrameDetails,\n detectionTime,\n documentDetectionModelDownloadProgress,\n documentDetectionModelReady,\n focusModelDownloadProgress,\n focusModelReady,\n focusPredictionTime,\n getBestFrame,\n modelError,\n onPredictionMade,\n resetBestFrame,\n setThresholds,\n startDocumentDetection,\n stopDocumentDetection,\n thresholds,\n ],\n )\n\n return (\n <IdCaptureModelsContext.Provider value={value}>\n <InvisibleCanvas key={canvasKey} ref={bestPredictionCanvas} />\n {children}\n </IdCaptureModelsContext.Provider>\n )\n}\n\nexport function IdCaptureModelsProvider({\n children,\n ...props\n}: IdCaptureModelsProviderProps &\n DocumentDetectionModelProviderProps &\n FocusModelProviderProps) {\n return (\n <DocumentDetectionModelProvider {...props}>\n <FocusModelProvider {...props}>\n <IdCaptureModelsProviderInner {...props}>\n {children}\n </IdCaptureModelsProviderInner>\n </FocusModelProvider>\n </DocumentDetectionModelProvider>\n )\n}\n","import { DetectedObjectBox } from '../../lib/models/DocumentDetection'\n\nexport const CapturedDocumentTypeValues = [\n 'idCardFront',\n 'idCardBack',\n 'passport',\n 'selfie',\n] as const\n\nexport type CapturedDocumentType = (typeof CapturedDocumentTypeValues)[number]\n\nexport type CapturedDocument = {\n imageData: string\n width: number\n height: number\n boundingBox?: DetectedObjectBox\n documentType: CapturedDocumentType\n}\n\nexport type CapturedDocuments = {\n [k in CapturedDocumentType]?: CapturedDocument\n}\n","import { CapturedDocumentType } from './CapturedDocuments'\n\nexport type IdCaptureRequirementOption =\n | 'idCardFront'\n | 'idCardBack'\n | 'passport'\n | 'idCard'\n | 'idCardOrPassport'\n | 'idCardAndPassport'\n\nexport const requiredDocumentsForOption: {\n [key in IdCaptureRequirementOption]: Array<CapturedDocumentType>\n} = {\n idCardFront: ['idCardFront'],\n idCardBack: ['idCardBack'],\n passport: ['passport'],\n idCard: ['idCardFront', 'idCardBack'],\n idCardAndPassport: ['idCardFront', 'idCardBack', 'passport'],\n idCardOrPassport: ['idCardFront', 'idCardBack', 'passport'], // this one is so weird\n}\n\nexport function requiredImageCountForOption(\n idCaptureRequirement: IdCaptureRequirementOption,\n) {\n if (idCaptureRequirement === 'idCardOrPassport') return 1\n return requiredDocumentsForOption[idCaptureRequirement].length\n}\n\nexport function allowedImageCountForOption(\n idCaptureRequirement: IdCaptureRequirementOption,\n) {\n if (idCaptureRequirement === 'idCardOrPassport') return 2\n return requiredImageCountForOption(idCaptureRequirement)\n}\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useContext,\n useLayoutEffect,\n useReducer,\n} from 'react'\nimport { useDebouncedCallback } from 'use-debounce'\nimport {\n CapturedDocument,\n CapturedDocuments,\n CapturedDocumentType,\n CapturedDocumentTypeValues,\n} from './CapturedDocuments'\nimport { IdCapturePrediction } from './IdCaptureModelsProvider'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport {\n DetectedObject,\n DocumentType,\n} from '../../lib/models/DocumentDetection'\nimport {\n IdCaptureRequirementOption,\n requiredDocumentsForOption,\n} from './IdCaptureRequirementOption'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type CaptureState = 'capturing' | 'complete' | 'requestingFlip'\n\nexport type IdCaptureState = {\n initialDrawComplete: boolean\n redrawing: boolean\n\n guideRectX: number\n guideRectY: number\n guideRectWidth: number\n guideRectHeight: number\n guideRectOffsetTop: number\n guideImageWidth: number\n guideImageHeight: number\n\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n\n detectedObjects: DetectedObject[]\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentType: DocumentType\n requiredDocumentType?: CapturedDocumentType\n documentInBounds: boolean\n documentTooClose: boolean\n documentDetectionScore: number\n documentDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n passportPageDetectionScore: number\n passportPageDetectionThresholdMet: boolean\n\n focusScore: number\n focusThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n barcodeScanningEnabled: boolean\n barcodeResult: PDF417DetectionResult | null\n waitingForBarcodeScan: boolean\n shouldScanBarcode: boolean\n autoCaptureBarcodeRequired: boolean | 'mobile'\n barcodeScanFailedAttempts: number\n maxBarcodeScanAttempts: number\n\n isGoodFrame: boolean\n goodFramesCount: number\n goodFramesThreshold: number\n goodFramesThresholdMet: boolean\n\n lastFrameCapturedAt: Date | null\n frameCaptureRate: number\n\n capturing: boolean\n captureFailed: boolean\n\n imageUrl: string | null\n\n captureState: CaptureState\n capturedDocuments: CapturedDocuments\n captureRequirement: IdCaptureRequirementOption\n requestedDocumentType: CapturedDocumentType\n detectedDocumentType: DocumentType\n differentDocumentTypeDetections: number\n\n operationStartedAt: Date | null\n captureStartedAt: Date | null\n}\n\nconst initialState = {\n initialDrawComplete: false,\n redrawing: false,\n\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n guideImageWidth: 0,\n guideImageHeight: 0,\n\n pageWidth: 0,\n pageHeight: 0,\n videoWidth: 0,\n videoHeight: 0,\n\n detectedObjects: [],\n bestDocument: undefined,\n bestMrz: undefined,\n bestPdf417: undefined,\n\n documentType: 'none',\n documentInBounds: false,\n documentTooClose: false,\n\n documentDetectionScore: 0,\n documentDetectionThresholdMet: false,\n passportPageDetectionScore: 0,\n passportPageDetectionThresholdMet: false,\n mrzDetectionScore: 0,\n mrzDetectionThresholdMet: false,\n pdf417DetectionScore: 0,\n pdf417DetectionThresholdMet: false,\n focusScore: 0,\n focusThresholdMet: false,\n\n barcodeScanningEnabled: false,\n barcodeResult: null,\n waitingForBarcodeScan: false,\n shouldScanBarcode: false,\n autoCaptureBarcodeRequired: 'mobile',\n barcodeScanFailedAttempts: 0,\n maxBarcodeScanAttempts: 10,\n\n isGoodFrame: false,\n goodFramesCount: 0,\n goodFramesThreshold: 3,\n goodFramesThresholdMet: false,\n\n lastFrameCapturedAt: null,\n frameCaptureRate: 0,\n\n capturing: false,\n captureFailed: false,\n\n imageUrl: null,\n\n captureState: 'capturing',\n capturedDocuments: {},\n captureRequirement: 'idCardOrPassport',\n requestedDocumentType: 'idCardFront',\n detectedDocumentType: 'none',\n differentDocumentTypeDetections: 0,\n\n operationStartedAt: null,\n captureStartedAt: null,\n} satisfies IdCaptureState\n\nexport type IdCaptureAction =\n | {\n type: 'configureWizard'\n payload: {\n captureRequirement: IdCaptureRequirementOption\n precapturedDocuments?: CapturedDocuments\n }\n }\n | {\n type: 'configureCapture'\n payload: {\n autoCaptureBarcodeRequired: boolean | 'mobile'\n barcodeScanningEnabled: boolean\n maxBarcodeScanAttempts: number\n }\n }\n | { type: 'setRequiredDocumentType'; payload: CapturedDocumentType }\n | { type: 'redrawRequested' }\n | { type: 'redrawInProgress' }\n | {\n type: 'redrawCompleted'\n payload: {\n guideRectX: number\n guideRectY: number\n guideRectWidth: number\n guideRectHeight: number\n guideRectOffsetTop: number\n }\n }\n | { type: 'pageRendered'; payload: { pageWidth: number; pageHeight: number } }\n | { type: 'guideImageLoaded'; payload: { width: number; height: number } }\n | { type: 'captureStarted' }\n | { type: 'capturing' }\n | { type: 'captured' }\n | { type: 'captureFailed' }\n | { type: 'frameCaptured'; payload: { imageUrl: string } }\n | {\n type: 'objectsDetected'\n payload: { prediction: IdCapturePrediction }\n }\n | {\n type: 'barcodeScanned'\n payload: { result: PDF417DetectionResult }\n }\n | { type: 'barcodeScanFailed' }\n | { type: 'predictionMade'; payload: IdCapturePrediction }\n | { type: 'documentCaptured'; payload: CapturedDocument }\n | { type: 'documentCapturedManually'; payload: { imageData: string } }\n | { type: 'flipRequestCompleted' }\n | { type: 'resetWizard' }\n\nexport type IdCaptureDispatch = Dispatch<IdCaptureAction>\n\nexport const IdCaptureStateContext = createContext<IdCaptureState>(initialState)\nexport const IdCaptureDispatchContext = createContext<IdCaptureDispatch>(\n () => {},\n)\n\nconst reducer = (\n state: IdCaptureState,\n action: IdCaptureAction,\n): IdCaptureState => {\n switch (action.type) {\n case 'configureWizard': {\n const { captureRequirement, precapturedDocuments } = action.payload\n let newState = { ...state, captureRequirement }\n\n if (captureRequirement === 'idCardBack')\n newState.requestedDocumentType = 'idCardBack'\n if (captureRequirement === 'passport')\n newState.requestedDocumentType = 'passport'\n\n if (precapturedDocuments) {\n for (const k of CapturedDocumentTypeValues) {\n const payload = precapturedDocuments[k]\n if (payload) {\n newState.requestedDocumentType = k\n newState = reducer(newState, { type: 'documentCaptured', payload })\n }\n }\n }\n\n newState.operationStartedAt = new Date()\n\n return newState\n }\n\n case 'configureCapture':\n return {\n ...state,\n ...action.payload,\n capturing: false,\n captureFailed: false,\n }\n\n case 'setRequiredDocumentType':\n return { ...state, requiredDocumentType: action.payload }\n\n case 'redrawRequested':\n return {\n ...state,\n redrawing: true,\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n }\n\n case 'redrawInProgress':\n return {\n ...state,\n redrawing: false,\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n }\n\n case 'redrawCompleted':\n return { ...state, ...action.payload, initialDrawComplete: true }\n\n case 'pageRendered':\n return { ...state, ...action.payload }\n\n case 'guideImageLoaded':\n return {\n ...state,\n guideImageWidth: action.payload.width,\n guideImageHeight: action.payload.height,\n }\n\n case 'objectsDetected':\n const {\n prediction: {\n detectedObjects,\n detectionScore,\n detectionThresholdMet,\n detectedDocumentType,\n passportDetectionScore,\n passportDetectionThresholdMet,\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n bestDocument,\n bestMrz,\n bestPdf417,\n documentInBounds,\n documentTooClose,\n focusScore,\n focusThresholdMet,\n frameWidth,\n frameHeight,\n },\n } = action.payload\n\n const frameCapturedAt = new Date()\n let frameCaptureRate = 0\n let goodFramesThreshold = state.goodFramesThreshold\n if (state.lastFrameCapturedAt) {\n frameCaptureRate =\n 1000.0 /\n (frameCapturedAt.getTime() - state.lastFrameCapturedAt.getTime())\n\n if (frameCaptureRate > 0) {\n goodFramesThreshold = Math.ceil(3 * frameCaptureRate)\n }\n }\n\n const barcodeScanRequired =\n state.autoCaptureBarcodeRequired === true ||\n (state.autoCaptureBarcodeRequired === 'mobile' && isMobile())\n const shouldScanBarcode =\n state.barcodeScanningEnabled &&\n pdf417DetectionThresholdMet &&\n barcodeScanRequired\n const waitingForBarcodeScan = shouldScanBarcode && !state.barcodeResult\n\n const isGoodFrame =\n detectionThresholdMet &&\n documentInBounds &&\n !documentTooClose &&\n focusThresholdMet\n\n let goodFramesCount = state.goodFramesCount\n if (isGoodFrame) {\n goodFramesCount += 1\n }\n\n return {\n ...state,\n\n videoWidth: frameWidth,\n videoHeight: frameHeight,\n\n detectedObjects,\n bestDocument: bestDocument,\n bestMrz,\n bestPdf417,\n\n documentType: detectedDocumentType,\n documentInBounds,\n documentTooClose,\n documentDetectionScore: detectionScore,\n documentDetectionThresholdMet: detectionThresholdMet,\n\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n\n passportPageDetectionScore: passportDetectionScore,\n passportPageDetectionThresholdMet: passportDetectionThresholdMet,\n\n focusScore,\n focusThresholdMet,\n\n shouldScanBarcode,\n waitingForBarcodeScan,\n\n isGoodFrame,\n goodFramesCount,\n goodFramesThreshold,\n goodFramesThresholdMet: goodFramesCount >= goodFramesThreshold,\n\n lastFrameCapturedAt: frameCapturedAt,\n frameCaptureRate,\n }\n\n case 'predictionMade': {\n const { detectedDocumentType, passportDetectionScore } = action.payload\n const { requestedDocumentType } = state\n const newState = { ...state, detectedDocumentType }\n\n if (state.captureRequirement === 'idCardOrPassport') {\n const predictionIsRequestedType =\n requestedDocumentType.startsWith(detectedDocumentType)\n\n if (predictionIsRequestedType) {\n newState.differentDocumentTypeDetections = 0\n }\n\n if (\n detectedDocumentType === 'passport' &&\n requestedDocumentType !== 'passport'\n ) {\n newState.requestedDocumentType = 'passport'\n }\n\n if (\n requestedDocumentType === 'passport' &&\n passportDetectionScore < 0.3\n ) {\n newState.requestedDocumentType =\n 'idCardFront' in state.capturedDocuments\n ? 'idCardBack'\n : 'idCardFront'\n }\n }\n\n return newState\n }\n\n case 'barcodeScanned':\n return {\n ...state,\n barcodeResult: action.payload.result,\n waitingForBarcodeScan: false,\n autoCaptureBarcodeRequired: false,\n }\n\n case 'barcodeScanFailed': {\n const newState = {\n ...state,\n barcodeScanFailedAttempts: state.barcodeScanFailedAttempts + 1,\n }\n\n if (\n newState.barcodeScanFailedAttempts >= newState.maxBarcodeScanAttempts\n ) {\n newState.autoCaptureBarcodeRequired = false\n newState.shouldScanBarcode = false\n newState.waitingForBarcodeScan = false\n }\n\n return newState\n }\n\n case 'captureStarted':\n return {\n ...state,\n captureStartedAt: new Date(),\n capturing: false,\n captureFailed: false,\n }\n\n case 'capturing':\n return {\n ...state,\n capturing: true,\n captureFailed: false,\n }\n\n case 'captured':\n return {\n ...state,\n capturing: false,\n captureFailed: false,\n }\n\n case 'frameCaptured':\n return { ...state, imageUrl: action.payload.imageUrl }\n\n case 'captureFailed':\n return {\n ...state,\n capturing: false,\n captureFailed: true,\n }\n\n case 'documentCaptured': {\n const newState = {\n ...state,\n capturing: false,\n captureFailed: false,\n goodFramesCount: 0,\n capturedDocuments: {\n ...state.capturedDocuments,\n [action.payload.documentType]: action.payload,\n },\n }\n\n let remainingRequirements = requiredDocumentsForOption[\n state.captureRequirement\n ].filter((v) => !(v in newState.capturedDocuments))\n\n if (state.captureRequirement === 'idCardOrPassport') {\n if (state.requestedDocumentType === 'passport') {\n remainingRequirements = []\n } else {\n remainingRequirements = remainingRequirements.filter(\n (v) => v !== 'passport',\n )\n }\n }\n\n if (remainingRequirements.length === 0) {\n newState.captureState = 'complete'\n } else {\n newState.requestedDocumentType = remainingRequirements[0]\n if (\n state.requestedDocumentType === 'idCardFront' &&\n newState.requestedDocumentType === 'idCardBack'\n ) {\n newState.captureState = 'requestingFlip'\n newState.documentDetectionThresholdMet = false\n newState.passportPageDetectionThresholdMet = false\n }\n }\n\n return newState\n }\n\n case 'documentCapturedManually': {\n const newState = {\n ...state,\n capturedDocuments: {\n ...state.capturedDocuments,\n [state.requestedDocumentType]: {\n ...action.payload,\n width: 0,\n height: 0,\n },\n },\n }\n\n let remainingRequirements = requiredDocumentsForOption[\n state.captureRequirement\n ].filter((v) => !(v in newState.capturedDocuments))\n\n if (state.captureRequirement === 'idCardOrPassport') {\n if (state.requestedDocumentType === 'passport') {\n remainingRequirements = []\n } else {\n remainingRequirements = remainingRequirements.filter(\n (v) => v !== 'passport',\n )\n }\n }\n\n if (remainingRequirements.length === 0) {\n newState.captureState = 'complete'\n } else {\n newState.requestedDocumentType = remainingRequirements[0]\n if (\n state.requestedDocumentType === 'idCardFront' &&\n newState.requestedDocumentType === 'idCardBack'\n ) {\n newState.captureState = 'requestingFlip'\n newState.documentDetectionThresholdMet = false\n newState.passportPageDetectionThresholdMet = false\n }\n }\n\n return newState\n }\n\n case 'flipRequestCompleted':\n return { ...state, captureState: 'capturing' }\n\n case 'resetWizard':\n return { ...initialState }\n\n default:\n return state\n }\n}\n\nexport const IdCaptureStateProvider = ({\n children,\n}: {\n children: ReactNode\n}) => {\n const [state, dispatch] = useReducer(reducer, initialState)\n\n const onResize = useDebouncedCallback(() => {\n dispatch({ type: 'redrawRequested' })\n }, 500)\n\n useLayoutEffect(() => {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', onResize)\n return () => {\n window.removeEventListener('resize', onResize)\n }\n }, [onResize])\n\n return (\n <IdCaptureStateContext.Provider value={state}>\n <IdCaptureDispatchContext.Provider value={dispatch}>\n {children}\n </IdCaptureDispatchContext.Provider>\n </IdCaptureStateContext.Provider>\n )\n}\n\nexport const useIdCaptureState = (): [IdCaptureState, IdCaptureDispatch] => {\n const state = useContext(IdCaptureStateContext)\n const dispatch = useContext(IdCaptureDispatchContext)\n if (!state || !dispatch)\n throw new Error(\n 'useIdCaptureState cannot be used without IdCaptureStateProvider',\n )\n\n return [state, dispatch]\n}\n","import styled from 'styled-components'\nimport React, { ReactElement, ReactNode, useMemo } from 'react'\nimport { useIdCaptureState } from '../id_capture/IdCaptureStateProvider'\nimport { DetectedObject } from '../../lib/models/DocumentDetection'\nimport { Face, FaceKeypoint } from '../../lib/models/FaceDetection'\nimport { createPortal } from 'react-dom'\n\nexport function DebugStatsPane({ children }: { children: ReactNode }) {\n const element = <DebugStatsPaneDiv>{children}</DebugStatsPaneDiv>\n const portalLocation = document.getElementById(\n 'idmission-above-guides-content',\n )\n if (!portalLocation) return element\n return createPortal(element, portalLocation)\n}\n\nexport const DebugStatsPaneDiv = styled.span`\n font-size: 16px;\n font-family: monospace;\n position: absolute;\n left: 20px;\n bottom: 20px;\n margin-right: 20px;\n padding: 8px;\n color: limegreen;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10002;\n`\n\nexport const ObjectDetectionDebugOverlayDiv = styled.div<{ $flipX?: boolean }>`\n position: absolute;\n z-index: 1001;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n overflow: hidden;\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport const ObjectDetectionDebugBox = styled.div<{\n $color?: string\n $flipX?: boolean\n}>`\n font: 10px monospace;\n position: absolute;\n border: 3px solid ${({ $color }) => $color ?? 'green'};\n color: ${({ $color }) => $color ?? 'green'};\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport const FaceDetectionKeypointMarker = styled.div<{\n $color?: string\n $flipX?: boolean\n}>`\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ${({ $color }) => $color ?? 'red'};\n font: 10px monospace;\n color: ${({ $color }) => $color ?? 'red'};\n border-radius: 50%;\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport type DebugScalingDetails = {\n horizontal: boolean\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n scaledWidth: number\n scaledHeight: number\n xOffset: number\n yOffset: number\n}\n\nexport function useDebugScalingDetails({\n enabled = true,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n}: {\n enabled?: boolean\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n}): DebugScalingDetails {\n return useMemo(() => {\n let horizontal = false,\n scaledWidth = 0,\n scaledHeight = 0,\n xOffset = 0,\n yOffset = 0\n\n if (enabled) {\n horizontal = pageWidth / pageHeight < videoWidth / videoHeight\n if (horizontal) {\n scaledWidth = videoWidth * (pageHeight / videoHeight)\n xOffset = (scaledWidth - pageWidth) / 2\n } else {\n scaledHeight = videoHeight * (pageWidth / videoWidth)\n yOffset = (scaledHeight - pageHeight) / 2\n }\n }\n\n return {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n }\n }, [enabled, pageHeight, pageWidth, videoHeight, videoWidth])\n}\n\nexport const DebugBoundingBoxOverlay = ({\n scaling,\n $flipX,\n children,\n}: {\n scaling?: DebugScalingDetails\n $flipX?: boolean\n children: ReactNode\n}) => {\n const [{ guideRectWidth, guideRectHeight, guideRectX, guideRectY }] =\n useIdCaptureState()\n\n return (\n <ObjectDetectionDebugOverlayDiv\n id=\"debug-overlay-div\"\n $flipX={$flipX}\n style={{\n top: guideRectY,\n left: guideRectX,\n width: guideRectWidth || scaling?.pageWidth,\n height: guideRectHeight || scaling?.pageHeight,\n }}\n >\n {children}\n </ObjectDetectionDebugOverlayDiv>\n )\n}\n\nexport type DetectedObjectDebugBoxProps = {\n obj: DetectedObject\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function IdCaptureDetectedObjectDebugBox({\n obj,\n flipX,\n color = 'green',\n scaling,\n}: DetectedObjectDebugBoxProps): ReactElement {\n const {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n } = scaling\n\n if (!videoWidth || !videoHeight || !pageWidth || !pageHeight) return <></>\n\n let top\n let left\n let width\n let height\n\n if (horizontal) {\n top = (obj.box.yMin / videoHeight) * pageHeight\n left = (obj.box.xMin / videoWidth) * scaledWidth - xOffset\n width = (obj.box.width / videoWidth) * scaledWidth\n height = (obj.box.height / videoHeight) * pageHeight\n } else {\n top = (obj.box.yMin / videoHeight) * scaledHeight - yOffset\n left = (obj.box.xMin / videoWidth) * pageWidth\n width = (obj.box.width / videoWidth) * pageWidth\n height = (obj.box.height / videoHeight) * scaledHeight\n }\n\n return (\n <ObjectDetectionDebugBox\n $flipX={flipX}\n $color={color}\n style={{ top, left, width, height }}\n />\n )\n}\n\nexport type SelfieCaptureFaceDebugBoxProps = {\n face: Face\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function SelfieCaptureFaceDebugBox({\n face,\n flipX,\n color = 'green',\n scaling,\n}: SelfieCaptureFaceDebugBoxProps): ReactElement {\n const {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n } = scaling\n\n if (!videoWidth || !videoHeight || !pageWidth || !pageHeight) return <></>\n\n let top\n let left\n let width\n let height\n\n if (horizontal) {\n top = (face.box.yMin / videoHeight) * pageHeight\n left = (face.box.xMin / videoWidth) * scaledWidth - xOffset\n width = (face.box.width / videoWidth) * scaledWidth\n height = (face.box.height / videoHeight) * pageHeight\n } else {\n top = (face.box.yMin / videoHeight) * scaledHeight - yOffset\n left = (face.box.xMin / videoWidth) * pageWidth\n width = (face.box.width / videoWidth) * pageWidth\n height = (face.box.height / videoHeight) * scaledHeight\n }\n\n return (\n <>\n <ObjectDetectionDebugBox\n $flipX={flipX}\n $color={color}\n style={{ top, left, width, height }}\n />\n\n {face.keypoints.map((point, ii) => (\n <SelfieCaptureFaceKeypoint\n key={ii}\n point={point}\n scaling={scaling}\n flipX={flipX}\n />\n ))}\n </>\n )\n}\n\ntype SelfieCaptureFaceKeypointProps = {\n point: FaceKeypoint\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function SelfieCaptureFaceKeypoint({\n point,\n flipX,\n color = 'red',\n scaling: {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n },\n}: SelfieCaptureFaceKeypointProps): ReactElement {\n let left, top\n if (horizontal) {\n left = (point.x / videoWidth) * scaledWidth - xOffset\n top = (point.y / videoHeight) * pageHeight\n } else {\n left = (point.x / videoWidth) * pageWidth\n top = (point.y / videoHeight) * scaledHeight - yOffset\n }\n\n top -= 2\n left -= 2\n\n return (\n <FaceDetectionKeypointMarker\n $flipX={flipX}\n $color={color}\n style={{ top, left }}\n />\n )\n}\n","export default {}\n","export default {\n 'Use your device camera to capture your ID':\n 'Para capturar la identificación hay que utilizar la cámara del dispositivo.',\n\n 'Use your iPhone as a webcam': 'Usar el iPhone como cámara web',\n 'Models warming up...': 'Cargando modelos...',\n 'Camera initializing...': 'Inicializando la cámara...',\n 'Camera access blocked': 'Acceso bloqueado a la cámara',\n 'Location access blocked': 'Acceso bloqueado a la localización',\n Continue: 'Continuar',\n 'Processing...': 'Procesando...',\n\n 'Your camera permission is disabled':\n 'El permiso de la cámara está desactivado',\n 'This application requires access to your camera to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for camera permissions, you must go to settings and provide camera access to the current browser.':\n 'Esta aplicación requiere el acceso a la cámara para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso a la cámara en el explorador actual.',\n 'Your microphone permission is disabled':\n 'El permiso de la micrófono está desactivado',\n 'This application requires access to your microphone to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for microphone permissions, you must go to settings and provide microphone access to the current browser.':\n 'Esta aplicación requiere tener acceso al micrófono para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso al micrófono en el explorador actual.',\n 'Your location permission is disabled':\n 'El permiso de la localización está desactivado',\n 'This application requires access to your location to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for location permissions, you must go to settings and provide location access to the current browser.':\n 'Esta aplicación requiere el acceso a la localización para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso a la localización en el explorador actual.',\n Retry: 'Reintentar',\n\n 'Scan the front of ID': 'Escanear el frente de la ID',\n 'Scan the back of ID': 'Escanear el reverso de la ID',\n 'Scan the ID page of passport': 'Escanear la página de datos del pasaporte',\n\n 'ID Card Front': 'Frente de la ID',\n 'ID Card Back': 'Reverso de la ID',\n Passport: 'Pasaporte',\n\n 'Document not detected': 'No se ha detectado el documento',\n 'Document is not centered': 'Documento no centrado',\n 'Document too close, please back up':\n 'Documento muy cerca, favor de alejarse',\n 'Document out of focus – try improving the lighting':\n 'Documento no enfocado - hay que tratar de mejorar la iluminación',\n 'Document detected, hold still...':\n 'Se ha detectado el documento, no moverse por favor...',\n\n 'Capturing...': 'Capturando...',\n 'Capture failed!': 'Falló la captura',\n\n 'Please flip your ID card...': 'Por favor voltea la identificación...',\n 'ID card front captured.': 'Se ha capturado el frente de la identificación.',\n\n 'ID Capture Successful': 'Captura Exitosa de ID',\n 'Verify the entire ID was captured clearly with no glare.':\n 'Hay que verificar que toda la ID se vea completa y sin reflejos.',\n\n Submit: 'Enviar',\n 'Submitting...': 'Enviando...',\n\n 'Use your device camera to capture your face':\n 'Hay que utilizar la cámara del dispositivo para capturar el rostro',\n\n 'Remove Sunglasses & Hat': 'Hay que quitarse lentes y/o la gorra',\n 'Avoid Excessive Backlighting': 'Hay que evitar demasiada luz en el fondo',\n\n 'Hold still for a few seconds...':\n 'Hay que permanecer quieto por unos segundos...',\n 'Look straight into the camera...':\n 'Hay que mirar directamente a la cámara...',\n 'Move back...': 'Hay que hacerse hacia atrás..',\n 'Move forward...': 'Hay que hacerse hacia adelante...',\n 'Move to the center...': 'Hay que moverse hacia el centro...',\n 'Please remove your eye coverings (sunglasses, eye patch, etc.)...':\n 'Hay que quitarse lo que cubre los ojos (lentes, parche, etc.)...',\n 'Please remove your head coverings (hat, scarf, etc.)...':\n 'Hay que quitarse lo que cubre la cabeza (gorra, mascada, etc.)...',\n 'Please remove your mask...': 'Hay que quitarse el cubrebocas...',\n 'Live face not detected, please try again':\n 'Rostro vivo no detectado. Por favor hay que intentar de nuevo.',\n Exit: 'Salir',\n 'Face liveness has been verified!':\n 'Se ha verificado la Prueba de Vida en rostro!',\n Done: 'Terminar',\n\n 'Customer has been identified!': '¡Se ha identificado al cliente!',\n 'Customer not found': 'Cliente no encontrado',\n\n 'Additional document capture': 'Captura de otro documento',\n Next: 'Siguiente',\n\n 'Please sign the box below':\n 'Por favor, hay que firmar en el recuadro de abajo',\n Accept: 'Aceptar',\n Clear: 'Borrar',\n\n 'Video signature has been successfully captured!':\n 'La video firma ha sido exitosa.',\n\n 'Network unreachable': 'No hay conexión a internet.',\n \"We're having trouble reaching our services, please check your connection and try again.\": `Estamos teniendo problemas para alcanzar nuestros servicios, por favor verificar la conexión a internet e intentar de nuevo.`,\n \"We're sorry, an unexpected error has occurred.\": `Lo sentimos, se ha producido un error inesperado.`,\n\n 'Document Capture': 'Captura de documento',\n Capture: 'Capturar',\n 'Retry capture': 'Reintentar la captura',\n Upload: 'Enviar',\n 'Uploading...': 'Procesando...',\n 'Upload succeeded!': 'Proceso completo!',\n\n 'Display the front of your ID card...':\n 'Hay que mostrar el frente de la identificación...',\n 'Display the back of your ID card...':\n 'Hay que mostrar el reverso de la identificación...',\n 'Please move your face to the center...':\n 'Por favor, hay que mover la cabeza hacia el centro...',\n 'Searching for ID card...':\n 'Localizando la identificación...',\n 'Please read the following text aloud':\n 'Hay que leer el siguiente texto en voz alta',\n 'Video ID has been successfully captured!':\n 'Video ID capturado exitosamente!',\n 'ID Front Image':\n 'Frente de ID',\n 'ID Back Image':\n 'Reverso de ID',\n\n \"We're having some trouble.\": 'Se ha presentado un problema.',\n 'On-device capture guidance failed, please capture a selfie manually.':\n 'La captura automática para toma de selfie falló. Por favor, hay que tomarse la selfie manualmente.',\n 'Verifying...': 'Verificando....',\n 'Please capture the front of your ID card.':\n 'Hay que capturar el frente de la identificación.',\n 'Please capture the back of your ID card.':\n 'Hay que capturar el reverso de la identificación.',\n 'Please capture the front of your ID card, or the ID page of your passport.':\n 'Hay que capturar el frente de la identificación o la página de datos del pasaporte.',\n 'Please capture the back of your ID card, or click Done if submitting a passport.':\n 'Hay que capturar el reverso de la identificación o hay que presionar el botón de Terminar si se trata de un pasaporte.',\n 'Please capture the ID page of your passport.':\n 'Hay que capturar la página de datos del pasaporte.',\n 'On-device capture guidance failed, please capture a photo of your ID card manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación manualmente.',\n 'On-device capture guidance failed, please capture a photo of your passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la pasaporte manualmente.',\n 'On-device capture guidance failed, please capture photos of your ID card and passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación y del pasaporte manualmente.',\n 'On-device capture guidance failed, please capture photos of your ID card or passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación o del pasaporte manualmente.',\n 'Capture ID page of passport':\n 'Captura pasaporte (página de la foto)',\n 'Capture back of ID card':\n 'Captura del reverso',\n\n 'Downloading...': 'Descargando...',\n 'Accessing camera...': 'Accediendo a la cámara',\n 'Camera ready': 'Cámara está lista',\n 'Loading guided capture experience...':\n 'Cargando la experiencia guiada para la captura....',\n 'Guided capture experience ready': 'La experiencia guiada está lista',\n \"Let's Go!\": 'Vamos!',\n}\n","import { useEffect, useMemo } from 'react'\nimport { initReactI18next, useTranslation } from 'react-i18next'\nimport enTranslation from './en/translation'\nimport esTranslation from './es/translation'\nimport LanguageDetector from 'i18next-browser-languagedetector'\nimport i18n from 'i18next'\n\nexport const ALL_LANGUAGES = ['auto', 'en', 'es'] as const\nexport type LangOptions = typeof ALL_LANGUAGES\nexport type LangOption = LangOptions[number] | string\n\nexport const resources = {\n en: { translation: enTranslation },\n es: { translation: esTranslation },\n}\n\nexport function initializeI18n() {\n i18n\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n resources,\n detection: { caches: [] },\n fallbackLng: 'en',\n debug: false,\n interpolation: { escapeValue: false },\n })\n}\n\nexport const useLanguage = (lang: LangOption): void => {\n const { i18n } = useTranslation()\n useEffect(() => {\n if (lang !== 'auto') {\n i18n.changeLanguage(lang)\n } else {\n i18n.changeLanguage() // call without argument to use detection\n }\n }, [i18n, lang])\n}\n\nexport type CustomerSuppliedTranslations = { [lang: string]: string }\nexport type CustomerSuppliedVerbiage =\n | string\n | CustomerSuppliedTranslations\n | undefined\nexport type RecursiveVerbiageObject =\n | CustomerSuppliedVerbiage\n | { [key: string]: RecursiveVerbiageObject }\n\nfunction evaluateVerbiage(\n t: (key: string) => string,\n currentLanguage: string,\n verbiage: CustomerSuppliedVerbiage,\n fallback: string,\n): string {\n if (typeof verbiage === 'string') return verbiage\n\n if (typeof verbiage === 'object') {\n const translations = verbiage as CustomerSuppliedTranslations\n if (translations[currentLanguage]) return translations[currentLanguage]\n\n const nonLocaleLang = currentLanguage.split('-')[0]\n if (translations[nonLocaleLang]) return translations[nonLocaleLang]\n }\n\n return t(fallback)\n}\n\nexport function useVerbiage(\n verbiage: CustomerSuppliedVerbiage,\n fallback: string,\n): string {\n const { t, i18n } = useTranslation()\n\n return useMemo(\n () => evaluateVerbiage(t, i18n.language, verbiage, fallback),\n [fallback, i18n.language, t, verbiage],\n )\n}\n\nexport function useTranslations<\n T extends { [key: string]: RecursiveVerbiageObject },\n>(\n verbiage: T | undefined,\n fallbacks: { [K in keyof T]: string },\n): { [K in keyof T]: string } {\n const { t, i18n } = useTranslation()\n\n return useMemo(\n () => ({\n ...verbiage,\n ...Object.keys(fallbacks).reduce(\n (result, key) => ({\n ...result,\n [key as keyof T]: evaluateVerbiage(\n t,\n i18n.language,\n verbiage?.[key] as CustomerSuppliedVerbiage,\n fallbacks[key],\n ),\n }),\n {} as { [K in keyof T]: string },\n ),\n }),\n [fallbacks, i18n.language, t, verbiage],\n )\n}\n","import React, { ReactNode } from 'react'\nimport styled from 'styled-components'\nimport { createPortal } from 'react-dom'\n\nexport type GuidanceMessageVariant = 'default' | 'positive' | 'negative'\n\nexport const GuidanceMessageContainerDiv = styled.div<{\n $top?: string\n $bottom?: string\n}>`\n position: absolute;\n top: calc(${({ $top }) => $top ?? '10vh'});\n ${({ $bottom }) => ($bottom ? `bottom: ${$bottom};` : ``)}\n font-weight: bold;\n width: 100%;\n display: flex;\n`\n\nexport const GuidanceMessageContainer = (props: {\n $top?: string\n $bottom?: string\n className?: string\n children?: ReactNode\n}) => {\n const element = <GuidanceMessageContainerDiv {...props} />\n const portalLocation = document.getElementById(\n 'idmission-above-guides-content',\n )\n if (!portalLocation) return element\n return createPortal(element, portalLocation)\n}\n\nexport const GuidanceMessage = styled.div<{\n $background?: string\n $textColor?: string\n $variant?: GuidanceMessageVariant\n}>`\n margin-left: auto;\n margin-right: auto;\n background: ${(props) =>\n props.$background ??\n props.theme?.guidanceMessages?.[props.$variant ?? 'default']\n ?.backgroundColor ??\n '#ccc'};\n color: ${(props) =>\n props.$textColor ??\n props.theme?.guidanceMessages?.[props.$variant ?? 'default']?.textColor ??\n 'black'};\n padding: 10px 12px 8px;\n border-radius: 8px;\n z-index: 10001;\n`\n","export const DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets'\n","import React, { useContext, useEffect } from 'react'\nimport useResizeObserver from 'use-resize-observer'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport { supportsNativeBarcodeScanning } from '../../lib/barcode/Scan'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { CaptureAttemptMetadata } from '../../contexts/SubmissionContext'\nimport { PageContainer } from '../common/Page'\nimport {\n IdCaptureModelsContext,\n IdCapturePrediction,\n} from './IdCaptureModelsProvider'\nimport {\n DebugBoundingBoxOverlay,\n DebugStatsPane,\n IdCaptureDetectedObjectDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { IdCaptureImagePreviewClassNames } from '../common/SelfieProgressPreview'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { useTheme } from 'styled-components'\nimport { CapturedDocumentType } from './CapturedDocuments'\nimport { IdCaptureFitGuideClassNames } from './IdCaptureFitGuide'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport log from '../../lib/utils/logger'\nimport { defaultDocumentDetectionThresholds } from '../../lib/models/DocumentDetection'\nimport { defaultFocusThresholds } from '../../lib/models/Focus'\n\nexport type IdCaptureAssets = {\n portraitGuidesImageUrl?: string\n landscapeGuidesImageUrl?: string\n}\n\nexport type IdCaptureClassNames = {\n container?: string\n guides?: IdCaptureFitGuideClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n imagePreview?: IdCaptureImagePreviewClassNames\n exitCaptureBtn?: string\n}\n\nexport type IdCaptureColors = {\n guideBoxUnsatisfiedColor?: string\n guideBoxSatisfiedColor?: string\n guidanceMessagesSatisfiedBackgroundColor?: string\n guidanceMessagesUnsatisfiedBackgroundColor?: string\n guidanceMessagesSatisfiedTextColor?: string\n guidanceMessagesUnsatisfiedTextColor?: string\n}\n\nexport type IdCaptureVerbiage = {\n instructionText?: CustomerSuppliedVerbiage\n processingIdCardText?: CustomerSuppliedVerbiage\n capturingText?: CustomerSuppliedVerbiage\n captureFailedText?: CustomerSuppliedVerbiage\n guidanceSatisfiedText?: CustomerSuppliedVerbiage\n guidanceTooBlurryText?: CustomerSuppliedVerbiage\n guidanceNotCenteredText?: CustomerSuppliedVerbiage\n guidanceTooCloseText?: CustomerSuppliedVerbiage\n guidanceNotDetectedText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureProps = {\n requiredDocumentType?: CapturedDocumentType\n autoCaptureEnabled?: boolean\n idCardDetectionThreshold?: number\n passportDetectionThreshold?: number\n autoCaptureBarcodeRequired?: boolean | 'mobile'\n mrzDetectionScoreThreshold?: number\n pdf417DetectionThreshold?: number\n\n barcodeScanningEnabled?: boolean\n maxBarcodeScanAttempts?: number\n\n idCardFocusScoreThreshold?: number\n passportFocusScoreThreshold?: number\n\n guidanceMessage?: string\n guidanceSatisfied?: boolean\n\n onPrediction?: (prediction: IdCapturePrediction) => void\n onBarcodeScanned?: (result: PDF417DetectionResult) => void\n onCapture?: (\n frame: string,\n width: number,\n height: number,\n documentType: CapturedDocumentType,\n metadata: CaptureAttemptMetadata,\n ) => void\n\n assets?: IdCaptureAssets\n classNames?: IdCaptureClassNames\n colors?: IdCaptureColors\n verbiage?: IdCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const IdCapture = ({\n requiredDocumentType,\n autoCaptureEnabled = true,\n autoCaptureBarcodeRequired = 'mobile',\n idCardDetectionThreshold = defaultDocumentDetectionThresholds.idCard,\n passportDetectionThreshold = defaultDocumentDetectionThresholds.passport,\n mrzDetectionScoreThreshold = defaultDocumentDetectionThresholds.mrz,\n pdf417DetectionThreshold = defaultDocumentDetectionThresholds.pdf417,\n idCardFocusScoreThreshold = defaultFocusThresholds.idCard?.mobile,\n passportFocusScoreThreshold = defaultFocusThresholds.passport?.mobile,\n barcodeScanningEnabled = true,\n maxBarcodeScanAttempts = 10,\n guidanceMessage,\n guidanceSatisfied,\n onPrediction,\n onCapture,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: IdCaptureProps): React.ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const [state, dispatch] = useIdCaptureState()\n const { cameraRef } = useContext(CameraStateContext)\n const {\n ready: modelsReady,\n setThresholds,\n onPredictionMade,\n detectionTime,\n focusPredictionTime,\n getBestFrame,\n } = useContext(IdCaptureModelsContext)\n\n useEffect(() => {\n dispatch({\n type: 'configureCapture',\n payload: {\n autoCaptureBarcodeRequired,\n barcodeScanningEnabled,\n maxBarcodeScanAttempts,\n },\n })\n }, [\n autoCaptureBarcodeRequired,\n barcodeScanningEnabled,\n dispatch,\n maxBarcodeScanAttempts,\n ])\n\n useEffect(() => {\n setThresholds({\n idCard: idCardDetectionThreshold,\n passport: passportDetectionThreshold,\n mrz: mrzDetectionScoreThreshold,\n pdf417: pdf417DetectionThreshold,\n focus: {\n idCard: { mobile: idCardFocusScoreThreshold },\n passport: { mobile: passportFocusScoreThreshold },\n },\n })\n }, [\n idCardDetectionThreshold,\n idCardFocusScoreThreshold,\n mrzDetectionScoreThreshold,\n passportDetectionThreshold,\n passportFocusScoreThreshold,\n pdf417DetectionThreshold,\n setThresholds,\n ])\n\n useEffect(() => {\n if (!requiredDocumentType) return\n dispatch({\n type: 'setRequiredDocumentType',\n payload: requiredDocumentType,\n })\n }, [dispatch, requiredDocumentType])\n\n useEffect(() => {\n dispatch({\n type: 'pageRendered',\n payload: { pageWidth: width, pageHeight: height },\n })\n }, [dispatch, height, width])\n\n useEffect(() => {\n onPredictionMade((prediction) => {\n dispatch({ type: 'objectsDetected', payload: { prediction } })\n onPrediction?.(prediction)\n })\n }, [dispatch, onPrediction, onPredictionMade])\n\n const shouldCapture =\n autoCaptureEnabled &&\n state.goodFramesThresholdMet &&\n !state.capturing &&\n !state.waitingForBarcodeScan &&\n timeSince(state.captureStartedAt) >= 3000\n\n useEffect(() => {\n if (!shouldCapture) return\n\n dispatch({ type: 'capturing' })\n\n const bestFrame = getBestFrame()\n if (!bestFrame) {\n log('uh oh, i did not get a photo')\n dispatch({ type: 'captureFailed' })\n return\n }\n\n const {\n canvas: originalCanvas,\n documentType,\n boundingBox,\n detectionScore,\n focusScore,\n } = bestFrame\n const { width, height } = originalCanvas\n let canvas = originalCanvas\n\n // resize image to 2k max if barcode is read\n const isGreaterThan2k =\n (width > 1920 && height > 1080) || (width > 1080 && height > 1920)\n if (isGreaterThan2k && !!state.barcodeResult) {\n canvas = document.createElement('canvas')\n\n if (width > height) {\n canvas.width = 1920\n canvas.height = height * (1920 / width)\n } else {\n canvas.height = 1920\n canvas.width = width * (1920 / height)\n }\n const ctx2d = canvas.getContext('2d')\n if (!ctx2d) return\n ctx2d.drawImage(originalCanvas, 0, 0, canvas.width, canvas.height)\n }\n\n const imageUrl = canvas.toDataURL('image/jpeg', 0.95)\n dispatch({ type: 'frameCaptured', payload: { imageUrl } })\n\n const capturedDocumentType: CapturedDocumentType =\n documentType === 'passport' ? 'passport' : state.requestedDocumentType\n\n setTimeout(() => {\n const captureTime =\n new Date().getTime() - (state.captureStartedAt ?? new Date()).getTime()\n const metadata: CaptureAttemptMetadata = {\n autoCapture: 'Y',\n captureTime,\n boundingBox,\n bestDetectionScore: detectionScore,\n bestFocusScore: focusScore,\n }\n onCapture?.(imageUrl, width, height, capturedDocumentType, metadata)\n dispatch({ type: 'captured' })\n }, 0)\n }, [\n dispatch,\n getBestFrame,\n onCapture,\n shouldCapture,\n state.barcodeResult,\n state.captureStartedAt,\n state.requestedDocumentType,\n ])\n\n assets.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n\n const theme = useTheme()\n colors.guideBoxUnsatisfiedColor ||=\n theme.idCapture?.guideBox?.unsatisfiedColor ?? 'white'\n colors.guideBoxSatisfiedColor ||=\n theme.idCapture?.guideBox?.satisfiedColor ?? 'green'\n\n const verbiage = useTranslations(rawVerbiage, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n capturingText: 'Capturing...',\n captureFailedText: 'Capture failed!',\n guidanceSatisfiedText: 'Document detected, hold still...',\n guidanceTooBlurryText: 'Document out of focus – try improving the lighting',\n guidanceNotCenteredText: 'Document is not centered',\n guidanceTooCloseText: 'Document too close, please back up',\n guidanceNotDetectedText: 'Document not detected',\n })\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: state.guideRectWidth,\n pageHeight: state.guideRectHeight,\n videoWidth: state.videoWidth,\n videoHeight: state.videoHeight,\n })\n\n let satisfied = state.isGoodFrame\n if (typeof guidanceSatisfied === 'boolean') satisfied = guidanceSatisfied\n\n guidanceMessage ||= satisfied\n ? verbiage.guidanceSatisfiedText\n : !state.documentDetectionThresholdMet\n ? verbiage.guidanceNotDetectedText\n : !state.documentInBounds\n ? verbiage.guidanceNotCenteredText\n : state.documentTooClose\n ? verbiage.guidanceTooCloseText\n : !state.focusThresholdMet\n ? verbiage.guidanceTooBlurryText\n : ''\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n {guidanceMessage !== '' && (\n <GuidanceMessageContainer\n $top=\"\"\n $bottom=\"12.5dvh\"\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n $variant={satisfied ? 'positive' : 'default'}\n className={classNames.guidanceMessage}\n >\n {guidanceMessage}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && (\n <DebugBoundingBoxOverlay\n $flipX={!cameraRef.current?.isRearFacing}\n scaling={debugScalingDetails}\n >\n {state.detectedObjects.map((obj, i) => (\n <IdCaptureDetectedObjectDebugBox\n key={i}\n obj={obj}\n scaling={debugScalingDetails}\n flipX={!cameraRef.current?.isRearFacing}\n />\n ))}\n </DebugBoundingBoxOverlay>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {state.frameCaptureRate > 0.75 ? '✅' : '👎'} Frame Rate:{' '}\n {Math.round((state.frameCaptureRate + Number.EPSILON) * 1000) / 1000}{' '}\n fps ({detectionTime}ms doc detect, {focusPredictionTime}ms focus)\n <br />\n {modelsReady ? (\n <>\n {state.documentDetectionThresholdMet ? '✅' : '❌'} Document\n Score: {state.documentDetectionScore.toFixed(3)} (\n {state.documentType})\n <br />\n {state.passportPageDetectionThresholdMet ? '✅' : '❌'} Passport\n Score: {state.passportPageDetectionScore.toFixed(3)}\n <br />\n {state.focusThresholdMet ? '✅' : '❌'} Focus Score:{' '}\n {state.focusScore.toFixed(3)}\n <br />\n {state.documentInBounds ? '✅' : '❌'} Document In Bounds\n <br />\n {state.goodFramesThresholdMet ? '✅' : '❌'} Good Frame Count:{' '}\n {state.goodFramesCount}/{state.goodFramesThreshold}\n {barcodeScanningEnabled && state.autoCaptureBarcodeRequired ? (\n <>\n <br />\n {state.barcodeResult ? '✅' : '❌'} Barcode Scanned (\n {supportsNativeBarcodeScanning() ? 'Native' : 'ZXing'},{' '}\n {state.barcodeScanFailedAttempts}/\n {state.maxBarcodeScanAttempts} failed attempts)\n </>\n ) : null}\n </>\n ) : (\n <>❌ Models not ready</>\n )}\n </DebugStatsPane>\n )}\n </PageContainer>\n )\n}\n\nconst timeSince = (t: Date | null): number => {\n if (!t) return 0\n return Math.abs(new Date().getTime() - t.getTime())\n}\n","import React from 'react'\nimport styled from 'styled-components'\n\nexport const ExitCaptureStyledButton = styled.button`\n position: absolute;\n top: 12px;\n right: 12px;\n font-size: 20px;\n width: 32px;\n height: 32px;\n font-family: monospace;\n z-index: 1002;\n border: none;\n border-radius: 4px;\n background: #ccc;\n cursor: pointer;\n padding: 8px;\n box-sizing: border-box;\n display: flex;\n\n &:hover {\n background: #ddd;\n }\n\n & > svg {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n`\n\nexport const ExitCaptureButton = ({\n onClick,\n className,\n}: {\n onClick?: () => void\n className?: string\n}) => {\n return (\n <ExitCaptureStyledButton onClick={onClick} className={className}>\n <svg\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n x=\"0px\"\n y=\"0px\"\n viewBox=\"19.3 19.3 25.499999999999996 25.499999999999996\"\n enableBackground=\"new 0 0 64 64\"\n width={16}\n height={16}\n >\n <g id=\"close-outline-bot_x5F_s1g1_x5F_s2g2_x5F_s3g1_x5F_s4g1\">\n <line\n fill=\"none\"\n stroke=\"#000000\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeMiterlimit=\"10\"\n x1=\"19.75\"\n y1=\"44.25\"\n x2=\"44.25\"\n y2=\"19.75\"\n />\n </g>\n <g id=\"close-outline-top_x5F_s1g1_x5F_s2g2_x5F_s3g1_x5F_s4g1\">\n <line\n fill=\"none\"\n stroke=\"#000000\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeMiterlimit=\"10\"\n x1=\"44.25\"\n y1=\"44.25\"\n x2=\"19.75\"\n y2=\"19.75\"\n />\n </g>\n </svg>\n </ExitCaptureStyledButton>\n )\n}\n","import styled from 'styled-components'\n\nexport const ButtonsRow = styled.div`\n display: flex;\n gap: 0 15px;\n justify-content: center;\n`\n","import React, { useEffect, useState } from 'react'\nimport { useTheme } from 'styled-components'\n\nexport type IdCaptureLoadingGraphicProps = {\n width?: number\n height?: number\n className?: string\n}\n\nexport default function IdCaptureLoadingGraphic(\n props: IdCaptureLoadingGraphicProps,\n) {\n const isMobile = window.innerHeight > window.innerWidth\n return isMobile ? (\n <IdCaptureLoadingGraphicMobile {...props} />\n ) : (\n <IdCaptureLoadingGraphicDesktop {...props} />\n )\n}\n\nexport function IdCaptureLoadingGraphicDesktop({\n width = 698,\n height = 452,\n className,\n}: IdCaptureLoadingGraphicProps) {\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 7)\n }, 1000)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n const accentOpacity =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentOpacity ?? 0.2\n\n return (\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '100%',\n }}\n >\n <svg\n className={className}\n width={width}\n height={height}\n viewBox=\"0 0 698 452\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n margin: 'auto',\n transform: `scale(${frame > 1 ? 1 : frame === 1 ? 1.25 : 0.75})`,\n transition: 'transform 0.2s linear, border-width 0.2s linear',\n border: `${frame >= 5 ? 10 : 0}px solid ${accentColor}`,\n }}\n >\n <g filter={frame === 1 ? 'url(#filter0_f_91_884)' : undefined}>\n <path\n d=\"M10 0.5L688 0.5C693.247 0.5 697.5 4.75329 697.5 10L697.5 442C697.5 447.246 693.247 451.5 688 451.5L9.99999 451.5C4.75328 451.5 0.5 447.246 0.5 442L0.5 9.99998C0.5 4.75328 4.75329 0.5 10 0.5Z\"\n fill=\"#F3F3F3\"\n stroke=\"#DCDCDC\"\n />\n <mask\n id=\"mask0_91_854\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"30\"\n y=\"60\"\n width=\"207\"\n height=\"266\"\n >\n <rect\n x=\"30.7754\"\n y=\"60.5945\"\n width=\"205.426\"\n height=\"265.304\"\n rx=\"3\"\n fill=\"#D9D9D9\"\n />\n </mask>\n <g mask=\"url(#mask0_91_854)\">\n <path\n d=\"M161.429 226.164C161.472 226.322 161.474 226.488 161.438 226.647C157.252 244.639 146.071 257.508 132.955 257.508C119.837 257.508 108.632 244.59 104.447 226.595C104.411 226.439 104.413 226.276 104.453 226.121L107.568 214.051L108.337 211.118C108.453 210.678 108.85 210.371 109.305 210.371L156.578 210.371C157.034 210.371 157.432 210.68 157.546 211.122L160.976 224.435L161.305 225.701L161.429 226.164Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M185.475 157.408C185.556 157.356 185.628 157.291 185.693 157.219C210.004 130.149 193.715 196.897 180.188 189.065C157.256 175.818 183.525 158.645 185.475 157.408Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M267.491 324.918C267.577 325.255 267.487 325.608 267.24 325.853C254.85 338.143 225.105 345.481 222.791 346.037C222.686 346.063 222.601 346.067 222.493 346.058C219.509 345.795 174.209 342.097 147.081 357.481C142.849 359.881 122.568 356.455 121.909 356.343C121.888 356.339 121.882 356.339 121.861 356.337L89.946 352.929C89.8715 352.921 89.8068 352.921 89.7323 352.929C87.9869 353.117 64.0883 355.438 45.1808 343.79C29.8522 334.346 9.55527 336.584 -1.36759 325.857C-1.61519 325.614 -1.71005 325.255 -1.62441 324.919L1.46107 312.802C6.33129 293.793 21.3654 279.026 40.5404 274.455L42.6579 273.963L66.162 268.361L72.5851 266.837C75.2907 266.181 77.8788 265.267 80.3256 264.095C82.3725 263.11 84.3253 261.962 86.1605 260.649C88.1368 259.243 89.9955 257.649 91.6659 255.891C96.1597 251.18 99.4771 245.367 101.171 238.827L103.665 229.17L104.324 226.568L104.371 226.357L107.571 214.051L108.319 211.123C108.433 210.681 108.831 210.371 109.288 210.371L156.558 210.371C157.013 210.371 157.411 210.679 157.526 211.12L160.978 224.435L161.308 225.701L161.475 226.325C161.489 226.377 161.496 226.431 161.496 226.486V226.486C161.496 226.54 161.503 226.595 161.517 226.647L162.202 229.193L164.696 238.827C167.025 247.781 172.413 255.446 179.73 260.649C183.729 263.532 188.317 265.665 193.282 266.837L199.211 268.244L225.326 274.455C244.501 279.026 259.535 293.793 264.406 312.802L267.491 324.918Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M161.429 226.164C161.472 226.322 161.474 226.488 161.438 226.647C157.252 244.639 146.071 257.508 132.955 257.508C119.837 257.508 108.632 244.59 104.447 226.595C104.411 226.439 104.413 226.276 104.453 226.121L107.568 214.051L108.337 211.118C108.453 210.678 108.85 210.371 109.305 210.371L156.578 210.371C157.034 210.371 157.432 210.68 157.546 211.122L160.976 224.435L161.305 225.701L161.429 226.164Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M80.3983 157.408C80.3166 157.356 80.2445 157.291 80.1799 157.219C55.8686 130.149 72.1582 196.897 85.685 189.065C108.616 175.818 82.3476 158.645 80.3983 157.408Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M189.527 137.873C189.52 137.873 189.515 137.879 189.515 137.885C189.515 139.944 189.397 141.956 189.162 143.968C188.974 145.796 188.15 153.601 186.692 163.54C185.895 169.048 184.865 175.184 183.649 181.346C183.638 181.398 183.635 181.447 183.631 181.5V181.5C183.625 181.607 183.575 181.713 183.554 181.818C180.568 196.836 176.367 211.751 170.881 217.193C164.67 223.381 159.682 229.007 153.988 233.062C148.295 237.14 141.919 239.672 132.978 239.672C124.038 239.672 117.662 237.14 111.968 233.062C106.298 229.007 101.286 223.381 95.0752 217.193C89.5754 211.714 85.367 196.715 82.3561 181.682C82.3499 181.651 82.3467 181.628 82.3467 181.596V181.596C82.3467 181.566 82.3438 181.526 82.338 181.496C81.9648 179.566 81.6147 177.636 81.2645 175.728C81.1233 174.932 80.9821 174.135 80.841 173.338C80.2528 169.962 79.7352 166.657 79.2646 163.563C77.5768 152.19 76.7532 143.609 76.7472 143.546C76.747 143.544 76.7471 143.545 76.7469 143.543C76.5589 141.692 76.4648 139.794 76.4648 137.873C76.4648 137.381 76.4648 136.889 76.4648 136.397C76.5825 131.967 77.1942 127.654 78.3 123.528C78.3471 123.341 78.3941 123.153 78.4412 122.966C84.723 100.089 105.121 83.0011 129.731 81.6416C130.814 81.5713 131.872 81.5479 132.978 81.5479C148.601 81.5479 162.741 87.8531 172.975 98.0494C181.822 106.839 187.75 118.559 189.186 131.615C189.42 133.674 189.538 135.756 189.539 137.862C189.539 137.868 189.533 137.873 189.527 137.873V137.873Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M141.871 188.529C141.871 192.42 137.895 195.561 132.977 195.561C128.06 195.561 124.107 192.42 124.107 188.529V188.529C124.107 188.132 124.593 188.105 124.773 188.459C126.079 191.03 129.266 192.842 132.977 192.842C136.689 192.842 139.893 191.03 141.204 188.458C141.381 188.112 141.871 188.14 141.871 188.529V188.529Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M267.512 325.037C267.599 325.374 267.509 325.727 267.264 325.974C232.886 360.672 133.16 359.767 132.956 359.765C132.95 359.765 132.962 359.765 132.956 359.765C132.752 359.767 33.0007 360.672 -1.3537 325.95C-1.59784 325.703 -1.68748 325.351 -1.60167 325.014L1.48353 312.922C6.35375 293.889 21.3879 279.122 40.5629 274.551L66.2315 268.456L72.6075 266.933C75.2325 266.311 77.7789 265.415 80.1745 264.28C80.5729 264.092 81.0485 264.176 81.3541 264.494C94.359 278.009 112.66 286.435 132.956 286.435C153.253 286.435 171.556 278.008 184.562 264.49C184.865 264.174 185.337 264.088 185.734 264.274C188.127 265.395 190.657 266.311 193.304 266.933L198.88 268.269L225.349 274.551C244.524 279.122 259.558 293.889 264.405 312.922L267.512 325.037Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M197.318 267.895C198.038 268.068 198.334 268.924 197.847 269.481C190.872 277.457 169.982 297.251 132.954 298.717C92.046 300.357 71.408 275.554 67.0543 269.627C66.6418 269.065 66.9505 268.284 67.6281 268.122L72.606 266.933C75.231 266.311 77.7773 265.415 80.173 264.28C80.5713 264.092 81.0469 264.176 81.3526 264.494C94.3575 278.009 112.659 286.435 132.954 286.435C153.252 286.435 171.555 278.008 184.56 264.49C184.864 264.174 185.336 264.088 185.732 264.274C188.126 265.395 190.655 266.311 193.303 266.933L197.318 267.895Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M75.4663 140.851C75.4663 152.603 78.3795 166.091 80.4253 174.114C80.713 175.242 82.458 175.01 82.5156 173.848C83.0875 162.287 85.7494 140.134 97.4904 130.033C108.545 120.523 117.526 131.201 132.13 131.201C145.353 131.201 157.695 120.704 168.836 130.033C181.053 140.264 183.463 159.992 183.739 171.736C183.767 172.936 185.717 173.218 186.003 172.053C187.986 163.959 190.429 151.77 190.429 140.851C190.429 100.426 174.665 81.3704 132.13 81.3704C93.3928 81.3704 75.4663 100.225 75.4663 140.851Z\"\n fill=\"#525252\"\n />\n </g>\n <rect\n x=\"30.7754\"\n y=\"360.29\"\n width=\"640.93\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"134.29\"\n width=\"402.636\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"209.623\"\n width=\"180.775\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"481.069\"\n y=\"209.623\"\n width=\"188.992\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"284.956\"\n width=\"180.775\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"481.069\"\n y=\"284.956\"\n width=\"188.992\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"266.829\"\n y=\"58.3618\"\n width=\"402.636\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n\n <g\n fillOpacity={frame === 3 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect\n x=\"672\"\n y=\"55\"\n width=\"47\"\n height=\"410\"\n transform=\"rotate(90 672 55)\"\n fill={accentColor}\n />\n <rect\n x=\"670\"\n y=\"206\"\n width=\"47\"\n height=\"194\"\n transform=\"rotate(90 670 206)\"\n fill={accentColor}\n />\n <rect\n x=\"242\"\n y=\"61\"\n width=\"271\"\n height=\"218\"\n transform=\"rotate(90 242 61)\"\n fill={accentColor}\n />\n <rect\n x=\"677\"\n y=\"357\"\n width=\"47\"\n height=\"653\"\n transform=\"rotate(90 677 357)\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame === 4 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect\n x=\"455\"\n y=\"281\"\n width=\"47\"\n height=\"194\"\n transform=\"rotate(90 455 281)\"\n fill={accentColor}\n />\n <rect\n x=\"672\"\n y=\"131\"\n width=\"47\"\n height=\"411\"\n transform=\"rotate(90 672 131)\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame >= 5 ? 1 : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <circle cx=\"360\" cy=\"215\" r=\"41\" fill={accentColor} />\n <path\n d=\"M339.937 218.076L350.044 229.83L381.809 201.915\"\n stroke=\"white\"\n strokeWidth=\"10\"\n strokeOpacity={frame >= 5 ? 1 : 0}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ transition: 'stroke-opacity 0.2s linear' }}\n />\n </g>\n </g>\n\n <filter\n id=\"filter0_f_91_884\"\n x=\"0\"\n y=\"0\"\n width=\"848\"\n height=\"556\"\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\n <feBlend\n mode=\"normal\"\n in=\"SourceGraphic\"\n in2=\"BackgroundImageFix\"\n result=\"shape\"\n />\n <feGaussianBlur\n stdDeviation=\"5\"\n result=\"effect1_foregroundBlur_91_884\"\n />\n </filter>\n </svg>\n </div>\n )\n}\n\nexport function IdCaptureLoadingGraphicMobile({\n width = 428,\n height = 747,\n className,\n}: IdCaptureLoadingGraphicProps) {\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 7)\n }, 1000)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n const accentOpacity =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentOpacity ?? 0.2\n\n return (\n <svg\n className={className}\n width={width}\n height={height}\n viewBox=\"0 0 428 747\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g\n id=\"card\"\n style={{\n transform: `translate(${frame < 1 ? '-500px' : '0'}, 0)`,\n transition: 'transform 0.3s linear',\n }}\n >\n <path\n d=\"M76.5001 181.274C76.5001 176.027 80.7534 171.774 86.0001 171.774L342 171.774C347.247 171.774 351.5 176.027 351.5 181.274L351.5 586C351.5 591.247 347.247 595.5 342 595.5L86.0001 595.5C80.7534 595.5 76.5001 591.247 76.5001 586L76.5001 181.274Z\"\n fill=\"#F3F3F3\"\n stroke=\"#DCDCDC\"\n />\n <mask\n id=\"mask0_29_1815\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"113\"\n y=\"452\"\n width=\"163\"\n height=\"126\"\n >\n <rect\n x=\"113\"\n y=\"577.273\"\n width=\"125\"\n height=\"162\"\n rx=\"3\"\n transform=\"rotate(-90 113 577.273)\"\n fill=\"#D9D9D9\"\n />\n </mask>\n <g mask=\"url(#mask0_29_1815)\">\n <path\n d=\"M214.008 497.796C214.165 497.754 214.33 497.751 214.489 497.788C225.426 500.352 233.24 507.14 233.24 515.098C233.24 523.058 225.395 529.861 214.455 532.423C214.3 532.46 214.138 532.458 213.983 532.418L206.704 530.546L205.204 530.154C204.764 530.039 204.457 529.641 204.457 529.186L204.457 501.028C204.457 500.571 204.766 500.173 205.208 500.059L213.044 498.048L213.817 497.847L214.008 497.796Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M172.144 483.183C172.092 483.102 172.027 483.031 171.955 482.966C155.547 468.233 196.225 478.134 191.447 486.357C183.444 500.161 173.096 484.665 172.144 483.183Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M274.192 433.287C274.528 433.202 274.882 433.292 275.124 433.541C282.444 441.074 286.849 458.59 287.283 460.373C287.308 460.479 287.314 460.558 287.305 460.667C287.111 462.898 284.971 490.135 294.285 506.502C295.735 509.05 293.703 521.155 293.593 521.803C293.589 521.823 293.587 521.84 293.585 521.861L291.51 541.224C291.502 541.299 291.502 541.364 291.509 541.439C291.65 542.782 292.959 557.13 285.925 568.508C280.203 577.763 281.504 589.995 275.126 596.677C274.887 596.927 274.528 597.02 274.193 596.935L267.003 595.111C255.396 592.147 246.379 582.999 243.588 571.332L243.287 570.043L239.866 555.741L238.936 551.833C238.535 550.186 237.977 548.611 237.262 547.123C236.66 545.877 235.959 544.689 235.158 543.572C234.299 542.37 233.326 541.239 232.252 540.222C229.375 537.488 225.826 535.469 221.832 534.438L215.936 532.921L214.347 532.52L214.218 532.491L206.704 530.544L205.21 530.164C204.767 530.051 204.457 529.652 204.457 529.194L204.457 501.04C204.457 500.584 204.765 500.186 205.207 500.071L213.044 498.046L213.817 497.846L214.198 497.744C214.23 497.736 214.263 497.731 214.297 497.731C214.33 497.731 214.363 497.727 214.395 497.718L215.95 497.302L221.832 495.784C227.3 494.367 231.98 491.088 235.158 486.636C236.918 484.202 238.22 481.411 238.936 478.39L239.795 474.782L243.588 458.891C246.379 447.223 255.396 438.075 267.003 435.112L274.192 433.287Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M214.008 497.796C214.165 497.754 214.33 497.751 214.489 497.788C225.426 500.352 233.24 507.14 233.24 515.098C233.24 523.058 225.395 529.861 214.455 532.423C214.3 532.46 214.138 532.458 213.983 532.418L206.704 530.546L205.204 530.154C204.764 530.039 204.457 529.641 204.457 529.186L204.457 501.028C204.457 500.571 204.766 500.173 205.208 500.059L213.044 498.048L213.817 497.847L214.008 497.796Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M172.144 547.035C172.092 547.117 172.027 547.188 171.955 547.252C155.547 561.986 196.225 552.085 191.447 543.861C183.444 530.057 173.096 545.553 172.144 547.035Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M160.188 480.675C160.188 480.679 160.191 480.682 160.195 480.682C161.452 480.682 162.681 480.754 163.91 480.897C165.026 481.011 169.792 481.512 175.861 482.4C179.224 482.885 182.971 483.511 186.733 484.252C186.765 484.258 186.795 484.26 186.827 484.262C186.893 484.266 186.958 484.296 187.022 484.309C196.192 486.126 205.299 488.682 208.623 492.02C212.401 495.8 215.836 498.835 218.312 502.3C220.803 505.764 222.348 509.644 222.348 515.084C222.348 520.524 220.803 524.404 218.312 527.869C215.836 531.319 212.401 534.368 208.623 538.148C205.277 541.494 196.118 544.055 186.939 545.887C186.92 545.891 186.906 545.893 186.886 545.893C186.867 545.893 186.844 545.895 186.825 545.898C185.646 546.125 184.468 546.338 183.303 546.551C182.817 546.637 182.33 546.723 181.843 546.809C179.782 547.167 177.764 547.482 175.875 547.768C168.946 548.793 163.714 549.294 163.652 549.3C163.651 549.3 163.651 549.3 163.649 549.3C162.519 549.415 161.361 549.472 160.188 549.472C159.888 549.472 159.587 549.472 159.287 549.472C156.581 549.4 153.948 549.028 151.429 548.355C151.314 548.327 151.2 548.298 151.085 548.269C137.116 544.447 126.682 532.035 125.852 517.06C125.809 516.401 125.795 515.757 125.795 515.084C125.795 505.578 129.645 496.974 135.871 490.746C141.238 485.363 148.395 481.756 156.367 480.882C157.624 480.739 158.895 480.668 160.181 480.668C160.185 480.668 160.188 480.671 160.188 480.675Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M191.119 509.673C193.495 509.673 195.413 512.092 195.413 515.084C195.413 518.077 193.495 520.482 191.119 520.482C190.877 520.482 190.861 520.186 191.077 520.077C192.647 519.282 193.753 517.343 193.753 515.084C193.753 512.826 192.647 510.876 191.077 510.079C190.866 509.971 190.883 509.673 191.119 509.673Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M274.264 433.275C274.6 433.189 274.954 433.278 275.199 433.524C296.217 454.568 295.682 514.893 295.68 515.097C295.68 515.103 295.68 515.092 295.68 515.098C295.682 515.302 296.217 575.643 275.184 596.673C274.939 596.917 274.586 597.007 274.251 596.921L267.076 595.097C255.454 592.134 246.437 582.986 243.646 571.318L239.925 555.699L238.994 551.819C238.638 550.318 238.133 548.86 237.499 547.48C237.314 547.078 237.398 546.602 237.715 546.294C245.845 538.394 250.903 527.342 250.903 515.098C250.903 502.851 245.844 491.798 237.711 483.897C237.396 483.591 237.311 483.119 237.493 482.719C238.122 481.341 238.638 479.89 238.994 478.376L239.81 474.983L243.646 458.877C246.437 447.21 255.454 438.061 267.076 435.112L274.264 433.275Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M239.436 476.54C239.609 475.821 240.466 475.529 241.015 476.024C246.147 480.64 257.535 493.254 258.403 515.098C259.367 539.068 245.359 551.601 241.088 554.862C240.535 555.285 239.753 554.982 239.59 554.305L238.994 551.82C238.638 550.319 238.133 548.86 237.499 547.48C237.314 547.079 237.398 546.603 237.715 546.295C245.845 538.394 250.903 527.343 250.903 515.098C250.903 502.852 245.844 491.799 237.711 483.898C237.396 483.592 237.311 483.119 237.493 482.72C238.122 481.342 238.638 479.891 238.994 478.377L239.436 476.54Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M162.007 550.079C167.945 550.079 174.609 548.865 179.507 547.741C180.642 547.481 180.435 545.695 179.275 545.595C171.872 544.959 160.808 542.941 155.401 536.678C149.594 529.951 156.114 524.486 156.114 515.6C156.114 507.554 149.704 500.044 155.401 493.265C160.661 487.005 170.034 484.976 177.145 484.392C178.342 484.293 178.605 482.241 177.431 481.993C172.848 481.025 167.193 480.126 162.007 480.126C137.322 480.126 125.686 489.718 125.686 515.6C125.686 539.171 137.2 550.079 162.007 550.079Z\"\n fill=\"#525252\"\n />\n </g>\n <rect\n x=\"296\"\n y=\"577.273\"\n width=\"390\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 296 577.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"158\"\n y=\"433.273\"\n width=\"245\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 158 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"204\"\n y=\"433.273\"\n width=\"110\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 204 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"204\"\n y=\"303.274\"\n width=\"115\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 204 303.274)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"250\"\n y=\"433.273\"\n width=\"110\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 250 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"250\"\n y=\"303.274\"\n width=\"115\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 250 303.274)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"111.637\"\n y=\"433.637\"\n width=\"245\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 111.637 433.637)\"\n fill=\"#C1C1C1\"\n />\n\n <g\n fillOpacity={frame === 2 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect x=\"200\" y=\"188\" width=\"33\" height=\"118\" fill={accentColor} />\n <rect x=\"108\" y=\"444\" width=\"171\" height=\"136\" fill={accentColor} />\n <rect x=\"108\" y=\"187\" width=\"33\" height=\"247\" fill={accentColor} />\n <rect x=\"293\" y=\"186\" width=\"31\" height=\"394\" fill={accentColor} />\n </g>\n\n <g\n fillOpacity={frame === 3 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect x=\"154\" y=\"185\" width=\"33\" height=\"249\" fill={accentColor} />\n <rect\n x=\"247\"\n y=\"322\"\n width=\"31\"\n height=\"113\"\n rx=\"5\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame >= 4 ? 1 : 0}\n strokeOpacity={frame >= 4 ? 1 : 0}\n style={{\n transition: 'fill-opacity 0.2s linear, stroke-opacity 0.2s linear',\n }}\n >\n <rect\n x=\"78.5\"\n y=\"171.5\"\n width=\"271\"\n height=\"426\"\n rx=\"2.5\"\n stroke={accentColor}\n strokeWidth=\"5\"\n />\n <circle cx=\"214.5\" cy=\"383.5\" r=\"23.5\" fill={accentColor} />\n <path\n d=\"M203 385.263L208.793 392L227 376\"\n stroke=\"white\"\n strokeWidth=\"5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n </g>\n\n <g\n id=\"phone\"\n clipPath=\"url(#clip0_29_1778)\"\n style={{\n transform: `translate(${frame < 1 ? '40px' : '0'}, 0)`,\n transition: 'transform 0.3s linear',\n }}\n >\n <rect x=\"154\" y=\"693\" width=\"120\" height=\"5\" rx=\"2.5\" fill=\"#333343\" />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M372.869 156.244H373.495V156.241C376.342 156.241 378.647 158.551 378.647 161.396V234.788C378.647 237.637 376.339 239.944 373.495 239.944H372.869V677.09C372.869 698.895 355.203 716.571 333.411 716.571H94.2366C72.444 716.571 54.7781 698.895 54.7781 677.09V278.699H54.1523C51.3051 278.699 49 276.39 49 273.544V228.052C49 225.203 51.3082 222.897 54.1523 222.897H54.7781V212.047H54.1523C51.3051 212.047 49 209.737 49 206.892V161.399C49 158.551 51.3082 156.244 54.1523 156.244H54.7781V90.4813C54.7781 68.6761 72.444 51 94.2366 51H333.411C355.203 51 372.869 68.6761 372.869 90.4813V156.244ZM98.3077 60.7649H329.34C347.039 60.7649 361.387 75.1214 361.387 92.8311V674.734C361.387 692.444 347.039 706.8 329.34 706.8H98.3077C80.6082 706.8 66.26 692.444 66.26 674.734V92.8311C66.26 75.1214 80.6082 60.7649 98.3077 60.7649Z\"\n fill=\"#333343\"\n />\n <rect x=\"154\" y=\"71\" width=\"120\" height=\"20\" rx=\"10\" fill=\"#333343\" />\n </g>\n\n <defs>\n <clipPath id=\"clip0_29_1778\">\n <rect width=\"428\" height=\"747\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n )\n}\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { OverlayContainer, OverlayImageContainer } from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { IdCaptureModelsContext } from './IdCaptureModelsProvider'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureLoadingOverlayProps } from './IdCaptureLoadingOverlay'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport IdCaptureLoadingGraphic from './IdCaptureLoadingGraphic'\n\nconst legacyInstructionImageUrl = `${DEFAULT_CDN_URL}/WebSDK-Instruction-DL-Capture-3-Portrait.png`\n\nexport const IdCaptureLoadingOverlayDefault = ({\n onDismissed,\n onUserCancel,\n instructions,\n rotateImage = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureLoadingOverlayProps): ReactElement => {\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n IdCaptureModelsContext,\n )\n const {\n cameraReady,\n cameraAccessDenied,\n iphoneContinuityCameraAvailable,\n setIphoneContinuityCameraAllowed,\n } = useContext(CameraStateContext)\n const [dismissed, setDismissed] = useState(false)\n\n assets.instructionImageUrl ||= legacyInstructionImageUrl\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your ID',\n useContinuityCameraText: 'Use your iPhone as a webcam',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Loading guided capture experience...',\n modelsReadyText: 'Guided capture experience ready',\n cameraInitializingText: 'Camera initializing...',\n cameraInitializedText: 'Camera ready',\n continueText: \"Let's Go!\",\n })\n\n useEffect(() => {\n if (modelsReady && cameraReady) return () => null\n\n const t = setTimeout(() => {\n setDismissed(false)\n }, 500)\n\n return () => {\n clearTimeout(t)\n }\n }, [cameraReady, modelsReady])\n\n const imageRef = useRef<HTMLImageElement>(null)\n\n if (dismissed) return <></>\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n let imageStyle = {}\n if (rotateImage) {\n const naturalWidth = imageRef.current?.naturalWidth ?? 0\n const naturalHeight = imageRef.current?.naturalHeight ?? 0\n const scale =\n naturalWidth > naturalHeight ? naturalHeight / naturalWidth : 1\n imageStyle = { transform: `rotate(-90deg) scale(${scale})` }\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <OverlayHeader>\n <StyledGuidanceMessage className={classNames.heading}>\n {verbiage.headingText}\n </StyledGuidanceMessage>\n </OverlayHeader>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <StyledOverlayImageContainer\n className={classNames.imageContainer}\n style={{ pointerEvents: 'none' }}\n >\n {assets?.instructionImageUrl &&\n assets.instructionImageUrl !== legacyInstructionImageUrl ? (\n <CustomLoadingGraphic\n ref={imageRef}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n className={classNames.image}\n style={imageStyle}\n />\n ) : (\n <IdCaptureLoadingGraphic className={classNames.image} />\n )}\n </StyledOverlayImageContainer>\n\n {instructions}\n\n <ContinuityCameraCheckboxContainer\n className={classNames.continuityCameraCheckboxContainer}\n >\n {iphoneContinuityCameraAvailable && (\n <ContinuityCameraCheckboxInner\n className={classNames.continuityCameraCheckboxInner}\n >\n <ContinuityCameraCheckbox\n className={classNames.continuityCameraCheckbox}\n id=\"use-continuity-camera\"\n type=\"checkbox\"\n defaultChecked={true}\n onChange={(e) => {\n setIphoneContinuityCameraAllowed(e.target.checked)\n }}\n />\n <label\n htmlFor=\"use-continuity-camera\"\n className={classNames.continuityCameraCheckboxLabel}\n >\n {verbiage.useContinuityCameraText}\n </label>\n </ContinuityCameraCheckboxInner>\n )}\n </ContinuityCameraCheckboxContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <ProgressContainer className={classNames.progressContainer}>\n <ProgressBarBackground className={classNames.progressBackground} />\n <ProgressBar\n $progress={modelDownloadProgress}\n className={classNames.progressBar}\n >\n <ProgressIndicator className={classNames.progressIndicator} />\n </ProgressBar>\n </ProgressContainer>\n\n <LoadingListContainer className={classNames.loadingListContainer}>\n <LoadingList className={classNames.loadingList}>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n cameraReady ? 'done' : 'running'\n }`}\n >\n {cameraReady\n ? verbiage.cameraInitializedText\n : verbiage.cameraInitializingText}\n </LoadingListItem>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n modelsReady ? 'done' : 'running'\n }`}\n >\n {modelsReady\n ? verbiage.modelsReadyText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoadingListItem>\n </LoadingList>\n </LoadingListContainer>\n\n <ContinueButtonContainer className={classNames.continueBtnContainer}>\n {modelsReady && cameraReady && (\n <ContinueButton\n finished\n className={classNames.continueBtn}\n variant=\"positive\"\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {verbiage.continueText}\n </ContinueButton>\n )}\n </ContinueButtonContainer>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst OverlayInner = styled.div`\n height: 100dvh;\n display: flex;\n flex-direction: column;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.backgroundColor ?? '#ecedf3'};\n color: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.textColor ?? 'black'};\n`\n\nconst OverlayHeader = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n padding-bottom: 0;\n`\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 16px 24px;\n margin-top: 16px;\n font-size: 18px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst StyledOverlayImageContainer = styled(OverlayImageContainer)`\n padding: 0 0 100px;\n\n & > svg {\n height: 100%;\n }\n`\n\nconst ContinuityCameraCheckboxContainer = styled.div`\n position: fixed;\n bottom: 120px;\n width: 100dvw;\n display: flex;\n`\n\nconst ContinuityCameraCheckboxInner = styled(GuidanceMessage)`\n padding: 12px 18px;\n margin: 0 auto;\n font-size: 14px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst ContinuityCameraCheckbox = styled.input`\n margin-right: 8px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n display: flex;\n flex-direction: row;\n padding: 15px 25px;\n height: 100px;\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarTextColor ??\n 'white'};\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.idCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100dvw;\n box-sizing: border-box;\n`\n\nconst LoadingListContainer = styled.div`\n display: flex;\n position: relative;\n z-index: 2;\n`\n\nconst LoadingList = styled.ul`\n display: block;\n margin: auto;\n list-style: none;\n padding: 0;\n`\n\nconst LoadingListItem = styled.li`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n padding: 2px 1.25rem 2px 0;\n line-height: 1rem;\n\n &::before {\n content: '';\n display: inline-block;\n height: 1rem;\n min-width: 1rem;\n vertical-align: middle;\n background-size: cover;\n background-repeat: no-repeat;\n margin: auto 0.5rem auto 0;\n }\n\n &.done::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzg1KSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyNEMxOC42Mjc0IDI0IDI0IDE4LjYyNzQgMjQgMTJDMjQgNS4zNzI1OCAxOC42Mjc0IDAgMTIgMEM1LjM3MjU4IDAgMCA1LjM3MjU4IDAgMTJDMCAxOC42Mjc0IDUuMzcyNTggMjQgMTIgMjRaTTE5LjU2NDMgOC4yNzg1MkMxOS45NTQ5IDcuODg3OTkgMTkuOTU0OSA3LjI1NDgzIDE5LjU2NDMgNi44NjQzQzE5LjE3MzggNi40NzM3OCAxOC41NDA2IDYuNDczNzggMTguMTUwMSA2Ljg2NDNMOS40Mjg2NiAxNS41ODU4TDUuODUwMDUgMTIuMDA3MkM1LjQ1OTUzIDExLjYxNjYgNC44MjYzNiAxMS42MTY2IDQuNDM1ODQgMTIuMDA3MkM0LjA0NTMxIDEyLjM5NzcgNC4wNDUzMSAxMy4wMzA5IDQuNDM1ODQgMTMuNDIxNEw4LjcyMTU1IDE3LjcwNzFDOS4xMTIwOCAxOC4wOTc2IDkuNzQ1MjQgMTguMDk3NiAxMC4xMzU4IDE3LjcwNzFMMTkuNTY0MyA4LjI3ODUyWiIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF80OV8zODUiPjxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=');\n }\n\n &.running::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzcwKSI+PG1hc2sgaWQ9InBhdGgtMS1pbnNpZGUtMV80OV8zNzAiIGZpbGw9IndoaXRlIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMuNTE0NzIgMjAuNDg1NUM4LjIwMTAxIDI1LjE3MTggMTUuNzk5IDI1LjE3MTggMjAuNDg1MyAyMC40ODU1QzI1LjE3MTYgMTUuNzk5MiAyNS4xNzE2IDguMjAxMTkgMjAuNDg1MyAzLjUxNDlDMTUuNzk5IC0xLjE3MTM5IDguMjAxMDEgLTEuMTcxMzkgMy41MTQ3MiAzLjUxNDlDLTEuMTcxNTcgOC4yMDExOSAtMS4xNzE1NyAxNS43OTkyIDMuNTE0NzIgMjAuNDg1NVoiLz48L21hc2s+PHBhdGggZD0iTTYuMzk4MTQgMTEuNDU5QzUuODQ1ODYgMTEuNDU5IDUuMzk4MTQgMTEuOTA2NyA1LjM5ODE0IDEyLjQ1OUM1LjM5ODE0IDEzLjAxMTIgNS44NDU4NiAxMy40NTkgNi4zOTgxNCAxMy40NTlWMTEuNDU5Wk0xNy42MDE5IDEzLjQ1OUMxOC4xNTQxIDEzLjQ1OSAxOC42MDE5IDEzLjAxMTIgMTguNjAxOSAxMi40NTlDMTguNjAxOSAxMS45MDY3IDE4LjE1NDEgMTEuNDU5IDE3LjYwMTkgMTEuNDU5VjEzLjQ1OVpNNi4zOTgxNCAxMy40NTlIMTcuNjAxOVYxMS40NTlINi4zOTgxNFYxMy40NTlaTTMuNTE0NzIgMjAuNDg1NUw0LjkyODkzIDE5LjA3MTNMNC45Mjg5MyAxOS4wNzEzTDMuNTE0NzIgMjAuNDg1NVpNMjAuNDg1MyAzLjUxNDlMMTkuMDcxMSA0LjkyOTEyTDE5LjA3MTEgNC45MjkxMkwyMC40ODUzIDMuNTE0OVpNMy41MTQ3MiAzLjUxNDlMNC45Mjg5MyA0LjkyOTEyTDQuOTI4OTMgNC45MjkxMkwzLjUxNDcyIDMuNTE0OVpNMTkuMDcxMSAxOS4wNzEzQzE1LjE2NTggMjIuOTc2NSA4LjgzNDE3IDIyLjk3NjUgNC45Mjg5MyAxOS4wNzEzTDIuMTAwNTEgMjEuODk5N0M3LjU2Nzg0IDI3LjM2NyAxNi40MzIyIDI3LjM2NyAyMS44OTk1IDIxLjg5OTdMMTkuMDcxMSAxOS4wNzEzWk0xOS4wNzExIDQuOTI5MTJDMjIuOTc2MyA4LjgzNDM2IDIyLjk3NjMgMTUuMTY2IDE5LjA3MTEgMTkuMDcxM0wyMS44OTk1IDIxLjg5OTdDMjcuMzY2OCAxNi40MzIzIDI3LjM2NjggNy41NjgwMyAyMS44OTk1IDIuMTAwNjlMMTkuMDcxMSA0LjkyOTEyWk00LjkyODkzIDQuOTI5MTJDOC44MzQxNyAxLjAyMzg3IDE1LjE2NTggMS4wMjM4NyAxOS4wNzExIDQuOTI5MTJMMjEuODk5NSAyLjEwMDY5QzE2LjQzMjIgLTMuMzY2NjUgNy41Njc4NCAtMy4zNjY2NSAyLjEwMDUxIDIuMTAwNjlMNC45Mjg5MyA0LjkyOTEyWk00LjkyODkzIDE5LjA3MTNDMS4wMjM2OSAxNS4xNjYgMS4wMjM2OSA4LjgzNDM2IDQuOTI4OTMgNC45MjkxMkwyLjEwMDUxIDIuMTAwNjlDLTMuMzY2ODMgNy41NjgwMyAtMy4zNjY4MyAxNi40MzIzIDIuMTAwNTEgMjEuODk5N0w0LjkyODkzIDE5LjA3MTNaIiBmaWxsPSJ3aGl0ZSIgbWFzaz0idXJsKCNwYXRoLTEtaW5zaWRlLTFfNDlfMzcwKSIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImNsaXAwXzQ5XzM3MCI+PHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==');\n }\n`\n\nconst ProgressContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n`\n\nconst ProgressBarBackground = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarBackgroundColor ??\n 'var(--idm-color-positive-600)'};\n opacity: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarBackgroundOpacity ??\n 0.75};\n`\n\nconst ProgressBar = styled.span<{ $progress: number }>`\n display: block;\n width: ${(props) => props.$progress}%;\n height: 100%;\n`\n\nconst ProgressIndicator = styled.span`\n display: block;\n height: 100%;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarIndicatorColor ??\n 'var(--idm-color-positive-600)'};\n animation: progressBar 3s ease-in-out;\n animation-fill-mode: both;\n\n @keyframes progressBar {\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n }\n`\n\nconst CustomLoadingGraphic = styled.img``\n\nconst ContinueButtonContainer = styled.div`\n display: flex;\n`\n\nconst ContinueButton = styled(LoaderButton)`\n margin: auto;\n white-space: nowrap;\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.idCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.continueBtnBorder\n ? `border: ${props.theme?.idCapture?.loadingOverlay?.continueBtnBorder};`\n : ''}\n`\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { IdCaptureModelsContext } from './IdCaptureModelsProvider'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureLoadingOverlayProps } from './IdCaptureLoadingOverlay'\n\nconst ContinuityCameraCheckboxContainer = styled.div`\n margin-top: 15px;\n margin-bottom: 15px;\n`\n\nconst ContinuityCameraCheckbox = styled.input`\n margin-right: 8px;\n`\n\nexport const IdCaptureLoadingOverlayLegacy = ({\n onDismissed,\n onUserCancel,\n instructions,\n rotateImage = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureLoadingOverlayProps): ReactElement => {\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n IdCaptureModelsContext,\n )\n const {\n cameraReady,\n cameraAccessDenied,\n iphoneContinuityCameraAvailable,\n setIphoneContinuityCameraAllowed,\n } = useContext(CameraStateContext)\n const [dismissed, setDismissed] = useState(false)\n\n assets.instructionImageUrl ||= `${DEFAULT_CDN_URL}/WebSDK-Instruction-DL-Capture-3-Portrait.png`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your ID',\n useContinuityCameraText: 'Use your iPhone as a webcam',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Models warming up...',\n cameraInitializingText: 'Camera initializing...',\n continueText: 'Continue',\n })\n\n useEffect(() => {\n if (modelsReady && cameraReady) return () => null\n\n const t = setTimeout(() => {\n setDismissed(false)\n }, 500)\n\n return () => {\n clearTimeout(t)\n }\n }, [cameraReady, modelsReady])\n\n const imageRef = useRef<HTMLImageElement>(null)\n\n if (dismissed) return <></>\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n let imageStyle = {}\n if (rotateImage) {\n const naturalWidth = imageRef.current?.naturalWidth ?? 0\n const naturalHeight = imageRef.current?.naturalHeight ?? 0\n const scale =\n naturalWidth > naturalHeight ? naturalHeight / naturalWidth : 1\n imageStyle = { transform: `rotate(-90deg) scale(${scale})` }\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <h3 className={classNames.heading}>{verbiage.headingText}</h3>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <OverlayImageContainer\n className={classNames.imageContainer}\n style={{ pointerEvents: 'none' }}\n >\n <img\n ref={imageRef}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n className={classNames.image}\n style={imageStyle}\n />\n </OverlayImageContainer>\n\n {instructions}\n\n <ContinuityCameraCheckboxContainer\n className={classNames.continuityCameraCheckboxContainer}\n >\n {iphoneContinuityCameraAvailable && (\n <>\n <ContinuityCameraCheckbox\n className={classNames.continuityCameraCheckbox}\n id=\"use-continuity-camera\"\n type=\"checkbox\"\n defaultChecked={true}\n onChange={(e) => {\n setIphoneContinuityCameraAllowed(e.target.checked)\n }}\n />\n <label\n htmlFor=\"use-continuity-camera\"\n className={classNames.continuityCameraCheckboxLabel}\n >\n {verbiage.useContinuityCameraText}\n </label>\n </>\n )}\n </ContinuityCameraCheckboxContainer>\n\n <LoaderButton\n className={classNames.continueBtn}\n variant=\"positive\"\n disabled={!cameraReady || !modelsReady}\n finished={modelsReady && cameraReady}\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {cameraReady && modelsReady\n ? verbiage.continueText\n : modelsReady\n ? verbiage.cameraInitializingText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoaderButton>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import { CapturedDocument } from '../id_capture/CapturedDocuments'\nimport React, { useRef, useState } from 'react'\nimport { cropToDetectedObjectBox } from '../../lib/utils/cropping'\n\nexport const CapturedDocumentImg = ({\n alt,\n className,\n image,\n}: {\n alt?: string\n className?: string\n image: CapturedDocument\n}) => {\n const [url, setUrl] = useState(image.imageData)\n const [cropped, setCropped] = useState(false)\n const bbox = image.boundingBox\n const imgRef = useRef<HTMLImageElement>(null)\n\n function onLoaded() {\n if (!bbox || cropped) return\n setCropped(true)\n setTimeout(() => {\n setUrl(\n cropToDetectedObjectBox(imgRef.current!, bbox).toDataURL(\n 'image/jpeg',\n 0.95,\n ),\n )\n }, 100)\n }\n\n return (\n <div style={{ position: 'relative' }}>\n <img\n ref={imgRef}\n alt={alt}\n className={className}\n src={url}\n onLoad={onLoaded}\n onClick={() => {\n fetch(image.imageData)\n .then((resp) => resp.blob())\n .then((blob) => {\n const url = URL.createObjectURL(new Blob([blob]))\n const link = document.createElement('a')\n link.href = url\n link.setAttribute('download', `${image.documentType}.jpg`)\n document.body.appendChild(link)\n link.click()\n link.parentNode?.removeChild(link)\n })\n }}\n />\n </div>\n )\n}\n","import React, { ReactElement, useContext } from 'react'\nimport { SubmissionStatus } from '../../contexts/SubmissionContext'\nimport { CapturedDocuments } from './CapturedDocuments'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayImageRow,\n OverlayInner,\n} from '../common/overlay'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { CapturedDocumentImg } from '../common/CapturedDocumentImg'\n\nexport const OverlayInstruction = styled.p`\n font-size: 18px;\n margin: 30px 0;\n`\n\nexport type IdCaptureSuccessClassNames = {\n container?: string\n inner?: string\n heading?: string\n imageContainer?: string\n imageRow?: string\n imageCol?: string\n imageHeading?: string\n imageWrapper?: string\n image?: string\n instruction?: string\n buttonsRow?: string\n retryBtn?: string\n submitBtn?: string\n}\n\nexport type IdCaptureSuccessVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n idCardFrontText?: CustomerSuppliedVerbiage\n idCardBackText?: CustomerSuppliedVerbiage\n passportText?: CustomerSuppliedVerbiage\n instructionText?: CustomerSuppliedVerbiage\n retryText?: CustomerSuppliedVerbiage\n submittingText?: CustomerSuppliedVerbiage\n submitText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureSuccessColors = {\n doneBtn?: LoaderButtonColors\n retryBtn?: LoaderButtonColors\n}\n\nexport type IdCaptureSuccessProps = {\n capturedDocuments: CapturedDocuments\n barcodeResult?: PDF417DetectionResult | null\n onSubmitClick?: () => void\n onRetryClick?: () => void\n\n classNames?: IdCaptureSuccessClassNames\n colors?: IdCaptureSuccessColors\n verbiage?: IdCaptureSuccessVerbiage\n}\n\nexport const IdCaptureSuccess = ({\n capturedDocuments,\n // barcodeResult,\n onSubmitClick,\n onRetryClick,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureSuccessProps): ReactElement => {\n const { submissionStatus } = useContext(SubmissionContext)\n const { idCardFront, idCardBack, passport } = capturedDocuments\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'ID Capture Successful',\n idCardFrontText: 'ID Card Front',\n idCardBackText: 'ID Card Back',\n passportText: 'Passport',\n instructionText: 'Verify the entire ID was captured clearly with no glare.',\n retryText: 'Retry',\n submittingText: 'Submitting...',\n submitText: 'Done',\n })\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <ImagesContainer className={classNames.imageContainer}>\n <ImageRow className={classNames.imageRow}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n {idCardFront && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.idCardFrontText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={idCardFront}\n className={classNames.image}\n alt={verbiage.idCardFrontText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n {idCardBack && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.idCardBackText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={idCardBack}\n className={classNames.image}\n alt={verbiage.idCardBackText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n {passport && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.passportText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={passport}\n className={classNames.image}\n alt={verbiage.passportText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n </ImageRow>\n </ImagesContainer>\n\n {/*{barcodeResult && (*/}\n {/* <>*/}\n {/* <h3>Barcode Result</h3>*/}\n {/* <pre>{JSON.stringify(barcodeResult, null, 2)}</pre>*/}\n {/* </>*/}\n {/*)}*/}\n\n <OverlayInstruction className={classNames.instruction}>\n {verbiage.instructionText}\n </OverlayInstruction>\n\n <ButtonsRow className={classNames.buttonsRow}>\n <LoaderButton\n className={classNames.retryBtn}\n variant=\"warning\"\n onClick={onRetryClick}\n colors={colors.retryBtn}\n finished\n >\n {verbiage.retryText}\n </LoaderButton>\n\n <LoaderButton\n className={classNames.submitBtn}\n variant=\"positive\"\n onClick={onSubmitClick}\n disabled={submissionStatus === SubmissionStatus.SUBMITTING}\n colors={colors.doneBtn}\n finished\n >\n {submissionStatus === SubmissionStatus.SUBMITTING\n ? verbiage.submittingText\n : verbiage.submitText}\n </LoaderButton>\n </ButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst Heading = styled.h1`\n margin-bottom: 12px;\n`\n\nconst ImagesContainer = styled(OverlayImageContainer)`\n overflow-y: auto;\n`\n\nconst ImageRow = styled(OverlayImageRow)`\n flex-direction: column;\n`\n\nconst ImageCol = styled.div`\n max-height: none !important;\n`\n\nconst ImageHeading = styled.h3`\n text-align: left;\n margin-top: 24px;\n margin-bottom: 8px;\n font-size: 16px;\n font-weight: normal;\n`\n\nconst CapturedImageWrapper = styled.div`\n border: 1px solid\n ${(props) =>\n props.theme.idCapture?.success?.imageBorderColor ??\n 'var(--idm-color-primary-400)'};\n border-radius: 6px;\n padding: 4px;\n background: white;\n display: flex;\n`\n\nconst StyledImage = styled(CapturedDocumentImg)`\n width: 100%;\n border-radius: 4px;\n`\n","import React, { ReactElement, useCallback, useContext, useEffect } from 'react'\nimport styled from 'styled-components'\nimport { CameraStateContext } from './CameraProvider'\n\nexport const CameraVideoTag = ({\n className,\n}: {\n className?: string\n}): ReactElement => {\n const { videoRef, setVideoLoaded, onVideoUnmounted, cameraRef } =\n useContext(CameraStateContext)\n\n useEffect(\n function notifyCameraProviderOfUnmount() {\n const videoElement = videoRef.current\n if (!videoElement) return\n return () => {\n onVideoUnmounted(videoElement)\n }\n },\n [onVideoUnmounted, videoRef],\n )\n\n useEffect(\n function setVideoLoadedToFalseOnMount() {\n setVideoLoaded(false)\n },\n [setVideoLoaded],\n )\n\n useEffect(\n function attachCameraStreamToVideoTagWhenReady() {\n if (videoRef.current && cameraRef.current?.stream) {\n videoRef.current.srcObject = cameraRef.current.stream\n }\n },\n [cameraRef, videoRef],\n )\n\n const onLoadedData = useCallback(() => {\n setVideoLoaded(true)\n }, [setVideoLoaded])\n\n return (\n <FullscreenVideoTag\n className={className}\n autoPlay\n playsInline\n muted\n ref={videoRef}\n onLoadedData={onLoadedData}\n $isRearFacing={cameraRef.current?.isRearFacing}\n />\n )\n}\n\nexport const FullscreenVideoTag = styled.video<{ $isRearFacing?: boolean }>`\n transform: ${(props) => (props.$isRearFacing ? '' : 'scaleX(-1)')};\n min-width: 100%;\n min-height: 100%;\n width: auto;\n height: auto;\n max-width: 100%;\n max-height: 100%;\n object-fit: cover;\n background: black;\n z-index: -2;\n`\n","import { useEffect, useState } from 'react'\n\nexport function useShowSuccessScreen(\n skipSuccessScreen: boolean | (() => Promise<boolean>),\n successScreenReady: boolean,\n onDoneCallback?: () => void,\n): boolean {\n const [skipSuccessScreenResolvedFalse, setSkipSuccessScreenResolvedFalse] =\n useState(false)\n\n useEffect(() => {\n if (successScreenReady && skipSuccessScreen) {\n if (typeof skipSuccessScreen === 'function') {\n ;(async () => {\n if (await skipSuccessScreen()) {\n onDoneCallback?.()\n } else {\n setSkipSuccessScreenResolvedFalse(true)\n }\n })()\n } else {\n onDoneCallback?.()\n }\n }\n }, [successScreenReady, onDoneCallback, skipSuccessScreen])\n\n return !skipSuccessScreen || skipSuccessScreenResolvedFalse\n}\n","export function setCanvasDimensions(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n) {\n let devicePixelRatio = 1\n if (typeof window !== 'undefined') devicePixelRatio = window.devicePixelRatio\n canvas.width = width * devicePixelRatio\n canvas.height = height * devicePixelRatio\n canvas.style.width = width + 'px'\n canvas.style.height = height + 'px'\n\n canvas.getContext('2d')?.scale(devicePixelRatio, devicePixelRatio)\n}\n\nexport function resetCanvasDimensions(canvas: HTMLCanvasElement) {\n canvas.width = 0\n canvas.height = 0\n canvas.style.width = '0'\n canvas.style.height = '0'\n}\n","import React, {\n ReactElement,\n SyntheticEvent,\n useContext,\n useEffect,\n} from 'react'\nimport { GuideOrientationContext } from '../../contexts/GuideOrientationContext'\nimport { PageContainerDiv } from '../common/Page'\nimport styled, { useTheme } from 'styled-components'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nconst StyledPageContainer = styled(PageContainerDiv)`\n z-index: 1000;\n`\n\nexport const GuidesContainer = styled.div`\n display: flex;\n flex-flow: column nowrap;\n width: 100dvw;\n height: 100dvh;\n`\n\nexport const GuideCenterRow = styled.div`\n position: relative;\n display: flex;\n flex-flow: row nowrap;\n align-items: center;\n justify-items: center;\n box-sizing: border-box;\n max-width: 100%;\n max-height: 100%;\n min-height: 0;\n flex: 1;\n`\n\nexport const GuideRegion = styled.div<{\n $minWidth?: number\n $minHeight?: number\n $maskColor?: string\n}>`\n display: flex;\n flex-direction: column;\n justify-content: end;\n width: 100%;\n position: relative;\n z-index: 1000;\n background: ${(props) =>\n props.$maskColor ??\n props.theme?.idCapture?.guideOverlay?.backgroundColor ??\n 'rgba(0, 0, 0, 0.5)'};\n color: ${(props) =>\n props.theme?.idCapture?.guideOverlay?.textColor ?? 'white'};\n text-align: center;\n ${(props) => (props.$minWidth ? `min-width: ${props.$minWidth}px;` : ``)}\n ${(props) => (props.$minHeight ? `min-height: ${props.$minHeight}px;` : ``)}\n`\n\nexport const Spacer = styled(GuideRegion)`\n display: block;\n width: auto;\n`\n\nexport const GuideCenterRegion = styled.div<{\n $minWidth?: number\n $isMirrored?: boolean\n}>`\n ${(props) => (props.$minWidth ? `min-width: ${props.$minWidth}px;` : ``)}\n ${(props) => (props.$isMirrored ? 'transform: scaleX(-1);' : '')}\n box-sizing: border-box;\n display: flex;\n flex: 1;\n max-height: 100%;\n height: 100%;\n`\n\nexport const GuideCenterBorder = styled.div<{\n $borderWidth: number\n $borderColor?: string\n}>`\n box-sizing: border-box;\n border: ${(props) =>\n `${props.$borderWidth ?? 4}px solid ${props.$borderColor ?? 'white'}`};\n display: flex;\n flex: 1;\n justify-content: center;\n max-height: 100%;\n min-height: 0;\n position: relative;\n`\n\nexport const GuideText = styled.span`\n align-content: center;\n margin-top: 12px;\n margin-bottom: 12px;\n`\n\nexport const GuideImage = styled.img<{\n $width?: number\n $height?: number\n $padding: number\n $visible?: boolean\n}>`\n position: relative;\n z-index: 1;\n padding: ${(props) => props.$padding}px;\n box-sizing: border-box;\n opacity: ${(props) => (props.$visible ? 1 : 0)};\n transition: opacity 0.5s;\n max-height: 100%;\n max-width: 100%;\n`\n\nexport type IdCaptureGuideOverlayClassNames = {\n container?: string\n inner?: string\n dimmingRegion?: string\n dimmingRegionTop?: string\n dimmingRegionLeft?: string\n dimmingRegionRight?: string\n dimmingRegionBottom?: string\n centerRow?: string\n centerRegion?: string\n centerRegionInner?: string\n image?: string\n guideText?: string\n}\n\nexport type IdCaptureGuideOverlayProps = {\n classNames?: IdCaptureGuideOverlayClassNames\n width?: number\n height?: number\n padding?: number\n imagePadding?: number\n imageVisible?: boolean\n borderWidth?: number\n borderColor?: string\n maskColor?: string\n isMirrored?: boolean\n instruction?: string\n portraitGuidesImageUrl?: string\n landscapeGuidesImageUrl?: string\n onClick?: () => void\n}\n\nexport const IdCaptureGuideOverlay = ({\n classNames = {},\n width = 0,\n height = 0,\n padding: userSuppliedPadding,\n imagePadding: userSuppliedImagePadding,\n imageVisible = true,\n borderWidth,\n borderColor,\n maskColor,\n isMirrored = false,\n instruction = '',\n portraitGuidesImageUrl,\n landscapeGuidesImageUrl,\n onClick,\n}: IdCaptureGuideOverlayProps): ReactElement => {\n const {\n orientation,\n wrapperRef,\n wrapperWidth,\n wrapperHeight,\n imageAspectRatio,\n wrapperAspectRatio,\n onImageLoaded: guideOrientationOnImageLoaded,\n setDimensions,\n } = useContext(GuideOrientationContext)\n\n const dispatch = useIdCaptureState()[1]\n\n function onImageLoaded(e: SyntheticEvent) {\n guideOrientationOnImageLoaded(e)\n\n const img = e.target as HTMLImageElement\n dispatch({\n type: 'guideImageLoaded',\n payload: { width: img.naturalWidth, height: img.naturalHeight },\n })\n }\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n\n if (width == 0) width = wrapperWidth\n if (height == 0) height = wrapperHeight\n\n useEffect(() => {\n setDimensions({ width, height })\n }, [height, setDimensions, width])\n\n const padding =\n userSuppliedPadding ??\n (isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 50)\n const paddingAndBorderPx = padding * 2 + borderWidth * 2\n const imgSrc =\n orientation === 'portrait'\n ? portraitGuidesImageUrl\n : landscapeGuidesImageUrl\n\n const imagePadding =\n userSuppliedImagePadding ?? theme.idCapture?.guideBox?.imagePadding ?? 0\n let imageWidth: number | undefined = undefined,\n imageHeight: number | undefined = undefined\n if (imageAspectRatio >= wrapperAspectRatio) {\n imageWidth = wrapperWidth - paddingAndBorderPx\n } else {\n imageHeight = wrapperHeight - paddingAndBorderPx\n }\n\n return (\n <StyledPageContainer\n ref={wrapperRef}\n onClick={onClick}\n className={classNames.container}\n >\n <GuidesContainer className={classNames.inner}>\n <GuideRegion\n $maskColor={maskColor}\n $minHeight={padding}\n className={regionClsx(classNames, 'Top')}\n >\n {instruction !== '' && (\n <GuideText className={classNames.guideText}>\n {instruction}\n </GuideText>\n )}\n </GuideRegion>\n\n <GuideCenterRow className={classNames.centerRow}>\n <Spacer\n $maskColor={maskColor}\n $minWidth={padding}\n className={regionClsx(classNames, 'Left')}\n />\n\n <GuideCenterRegion\n $minWidth={imageWidth}\n $isMirrored={isMirrored}\n className={classNames.centerRegion}\n >\n <GuideCenterBorder\n $borderWidth={borderWidth}\n $borderColor={borderColor}\n className={classNames.centerRegionInner}\n >\n <GuideImage\n src={imgSrc}\n alt=\"\"\n onLoad={onImageLoaded}\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $visible={imageVisible}\n />\n </GuideCenterBorder>\n </GuideCenterRegion>\n\n <Spacer\n $maskColor={maskColor}\n $minWidth={padding}\n className={regionClsx(classNames, 'Right')}\n />\n </GuideCenterRow>\n\n <GuideRegion\n $maskColor={maskColor}\n $minHeight={padding}\n className={regionClsx(classNames, 'Bottom')}\n >\n {instruction !== '' && (\n <GuideText style={{ opacity: 0 }}>{instruction}</GuideText>\n )}\n </GuideRegion>\n </GuidesContainer>\n </StyledPageContainer>\n )\n}\n\nconst regionClsx = (\n classNames: IdCaptureGuideOverlayClassNames,\n which: 'Top' | 'Left' | 'Right' | 'Bottom',\n): string =>\n [classNames.dimmingRegion, classNames[`dimmingRegion${which}`]]\n .filter((v) => v)\n .join(' ')\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport useResizeObserver from 'use-resize-observer'\nimport { GuideOrientationContext } from '../../contexts/GuideOrientationContext'\nimport { PageContainer } from '../common/Page'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport {\n GuideCenterBorder,\n GuideCenterRegion,\n GuideCenterRow,\n GuideImage,\n GuideRegion,\n GuidesContainer,\n GuideText,\n Spacer,\n} from './IdCaptureGuideOverlay'\nimport styled, { useTheme } from 'styled-components'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nconst FlippingImage = styled(GuideImage)<{\n $transitionTime?: number\n $transforms?: string\n}>`\n backface-visibility: hidden;\n transform-style: preserve-3d;\n position: absolute;\n height: 100%;\n top: 0;\n left: 50%;\n transition: transform ${(props) => props.$transitionTime}s;\n transform: translateX(-50%) ${(props) => props.$transforms};\n`\n\nexport type FlipIdPromptAssets = {\n frontPortraitGuidesImageUrl?: string\n frontLandscapeGuidesImageUrl?: string\n backPortraitGuidesImageUrl?: string\n backLandscapeGuidesImageUrl?: string\n}\n\nexport type FlipIdPromptClassNames = {\n container?: string\n inner?: string\n dimmingRegion?: string\n dimmingRegionTop?: string\n dimmingRegionLeft?: string\n dimmingRegionRight?: string\n dimmingRegionBottom?: string\n centerRow?: string\n centerRegion?: string\n image?: string\n guideText?: string\n}\n\nexport type FlipIdPromptVerbiage = {\n instructionText?: CustomerSuppliedVerbiage\n}\n\nexport type FlipIdPromptProps = {\n padding?: number\n imagePadding?: number\n borderWidth?: number\n borderColor?: string\n maskColor?: string\n assets?: FlipIdPromptAssets\n classNames?: FlipIdPromptClassNames\n verbiage?: FlipIdPromptVerbiage\n}\n\nexport const FlipIdPrompt = ({\n padding: userSuppliedPadding,\n imagePadding: userSuppliedImagePadding,\n borderWidth,\n borderColor,\n maskColor,\n assets = {},\n classNames = {},\n verbiage = {},\n}: FlipIdPromptProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const { cameraRef } = useContext(CameraStateContext)\n const theme = useTheme()\n\n assets.frontPortraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.frontLandscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backPortraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Portrait-2.svg`\n assets.backLandscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const instruction = useVerbiage(\n verbiage.instructionText,\n 'Please flip your ID card...',\n )\n\n const padding =\n userSuppliedPadding ?? isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 50\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n const isMirrored = !cameraRef.current?.isRearFacing\n\n const {\n orientation,\n wrapperRef,\n wrapperWidth,\n wrapperHeight,\n imageAspectRatio,\n wrapperAspectRatio,\n onImageLoaded,\n setDimensions,\n } = useContext(GuideOrientationContext)\n\n useEffect(() => {\n setDimensions({ width, height })\n }, [height, setDimensions, width])\n\n const paddingAndBorderPx = padding * 2 + borderWidth * 2\n\n const imagePadding =\n userSuppliedImagePadding ?? theme.idCapture?.guideBox?.imagePadding ?? 0\n let imageWidth: number | undefined = undefined,\n imageHeight: number | undefined = undefined\n if (imageAspectRatio >= wrapperAspectRatio) {\n imageWidth = wrapperWidth - paddingAndBorderPx\n } else {\n imageHeight = wrapperHeight - paddingAndBorderPx\n }\n\n const [transitionTime, setTransitionTime] = useState(1)\n const [rotationAngle, setRotationAngle] = useState(0)\n const frontTransforms = [`rotateY(${rotationAngle}deg)`]\n if (isMirrored) frontTransforms.push('scaleX(-1)')\n const backTransforms = [`rotateY(${180 - rotationAngle}deg)`]\n if (isMirrored) backTransforms.push('scaleX(-1)')\n\n useEffect(() => {\n const doFlip = () => {\n setTransitionTime(1)\n setRotationAngle(180)\n\n setTimeout(() => {\n setTransitionTime(0)\n setRotationAngle(0)\n }, 1500)\n }\n\n setTimeout(doFlip, 250)\n const interval = setInterval(doFlip, 2500)\n\n return () => {\n clearInterval(interval)\n }\n }, [])\n\n return (\n <PageContainer ref={ref} className={classNames.container}>\n <GuidesContainer ref={wrapperRef} className={classNames.inner}>\n <GuideRegion\n $minHeight={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Top')}\n >\n {instruction !== '' && (\n <GuideText className={classNames.guideText}>\n {instruction}\n </GuideText>\n )}\n </GuideRegion>\n\n <GuideCenterRow className={classNames.centerRow}>\n <Spacer\n $minWidth={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Left')}\n />\n\n <GuideCenterRegion>\n <GuideCenterBorder\n $borderWidth={borderWidth}\n $borderColor={borderColor}\n className={classNames.centerRegion}\n >\n <FlippingImage\n src={\n orientation === 'portrait'\n ? assets.frontPortraitGuidesImageUrl\n : assets.frontLandscapeGuidesImageUrl\n }\n alt=\"\"\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $transitionTime={transitionTime}\n $transforms={frontTransforms.join(' ')}\n $visible\n onLoad={onImageLoaded}\n />\n\n <FlippingImage\n src={\n orientation === 'portrait'\n ? assets.backPortraitGuidesImageUrl\n : assets.backLandscapeGuidesImageUrl\n }\n alt=\"\"\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $transitionTime={transitionTime}\n $transforms={backTransforms.join(' ')}\n $visible\n />\n </GuideCenterBorder>\n </GuideCenterRegion>\n\n <Spacer\n $minWidth={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Right')}\n />\n </GuideCenterRow>\n\n <GuideRegion\n $minHeight={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Bottom')}\n >\n {instruction !== '' && (\n <GuideText style={{ opacity: 0 }}>{instruction}</GuideText>\n )}\n </GuideRegion>\n </GuidesContainer>\n </PageContainer>\n )\n}\n\nconst regionClsx = (\n classNames: FlipIdPromptClassNames,\n which: 'Top' | 'Left' | 'Right' | 'Bottom',\n): string =>\n [classNames.dimmingRegion, classNames[`dimmingRegion${which}`]]\n .filter((v) => v)\n .join(' ')\n","import React, { useEffect, useRef } from 'react'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport styled, { useTheme } from 'styled-components'\nimport {\n resetCanvasDimensions,\n setCanvasDimensions,\n} from '../../lib/utils/canvas'\nimport useResizeObserver from 'use-resize-observer'\nimport {\n IdCaptureGuideOverlay,\n IdCaptureGuideOverlayClassNames,\n} from './IdCaptureGuideOverlay'\nimport { FlipIdPrompt } from './FlipIdPrompt'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type IdCaptureFitGuideClassNames = IdCaptureGuideOverlayClassNames & {\n canvasWrapper?: string\n canvas?: string\n}\n\nexport type IdCaptureFitGuideProps = {\n aspectRatio?: number\n maskColor?: string\n borderRadius?: number\n borderColor?: string\n borderWidth?: number\n padding?: number\n imageUrl?: string\n imageVisible?: boolean\n frontImageUrl?: string\n backImageUrl?: string\n isMirrored?: boolean\n instruction?: string\n requestingFlip?: boolean\n classNames?: IdCaptureFitGuideClassNames\n}\n\nexport const IdCaptureFitGuide = ({\n aspectRatio,\n maskColor,\n borderRadius = 33,\n borderColor,\n borderWidth,\n padding,\n imageUrl,\n imageVisible,\n frontImageUrl,\n backImageUrl,\n isMirrored,\n instruction,\n requestingFlip = false,\n classNames = {},\n}: IdCaptureFitGuideProps) => {\n const [{ redrawing, guideImageWidth, guideImageHeight }, dispatch] =\n useIdCaptureState()\n const canvasRef = useRef<HTMLCanvasElement>(null)\n\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n\n if (padding === undefined) {\n padding = isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 0\n }\n\n if (aspectRatio === undefined && guideImageWidth !== 0) {\n aspectRatio = guideImageWidth / guideImageHeight\n }\n\n if (maskColor === undefined) {\n maskColor = theme.idCapture?.guideOverlay?.backgroundColor ?? '#708090'\n }\n\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n\n if (redrawing) {\n resetCanvasDimensions(canvas)\n setTimeout(() => {\n dispatch({ type: 'redrawInProgress' })\n }, 10)\n return\n }\n\n const boundingWidth = wrapperWidth - padding! * 2 - borderWidth! * 2\n const boundingHeight = wrapperHeight - padding! * 2 - borderWidth! * 2\n\n let [rectX, rectY, rectWidth, rectHeight] = [\n padding! + borderWidth!,\n padding! + borderWidth!,\n boundingWidth,\n boundingHeight,\n ]\n\n if (aspectRatio !== undefined) {\n const scaledWidth = boundingHeight * aspectRatio\n const scaledHeight = boundingWidth / aspectRatio\n\n if (scaledWidth < boundingWidth) {\n rectWidth = scaledWidth\n rectX += (boundingWidth - rectWidth) / 2\n } else {\n rectHeight = scaledHeight\n rectY += (boundingHeight - rectHeight) / 2\n }\n }\n\n setCanvasDimensions(canvas, wrapperWidth, wrapperHeight)\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.fillStyle = maskColor!\n ctx.clearRect(0, 0, wrapperWidth, wrapperHeight)\n ctx.fillRect(0, 0, wrapperWidth, wrapperHeight)\n\n // const radius = Math.min(wrapperWidth, wrapperHeight) / 2 - padding!\n ctx.beginPath()\n // ctx.arc(wrapperWidth / 2, wrapperHeight / 2, radius, 0, Math.PI * 2, true) // Hole anticlockwise\n ctx.roundRect(rectX, rectY, rectWidth, rectHeight, borderRadius!)\n\n ctx.lineWidth = borderWidth!\n ctx.strokeStyle = borderColor ?? 'white'\n if (borderColor?.startsWith('var(')) {\n ctx.strokeStyle = getComputedStyle(\n document.documentElement,\n ).getPropertyValue(borderColor.slice(4, -1))\n }\n ctx.stroke()\n\n // make alpha solid (the color doesn't matter)\n ctx.fillStyle = 'rgba(0,0,0,1)'\n\n // change composite mode and fill\n ctx.globalCompositeOperation = 'destination-out'\n ctx.fill()\n\n // reset composite mode to default\n ctx.globalCompositeOperation = 'source-over'\n\n const rectOffsetTop = canvas.offsetTop\n\n dispatch({\n type: 'redrawCompleted',\n payload: {\n guideRectX: rectX,\n guideRectY: rectY,\n guideRectWidth: rectWidth,\n guideRectHeight: rectHeight,\n guideRectOffsetTop: rectOffsetTop,\n },\n })\n }, [\n aspectRatio,\n borderColor,\n borderRadius,\n borderWidth,\n dispatch,\n maskColor,\n padding,\n redrawing,\n wrapperHeight,\n wrapperWidth,\n ])\n\n return (\n <>\n <CanvasWrapper\n ref={wrapperRef}\n $maskColor={maskColor}\n className={classNames.canvasWrapper}\n >\n <Canvas ref={canvasRef} className={classNames.canvas} />\n </CanvasWrapper>\n\n {requestingFlip ? (\n <FlipIdPrompt\n maskColor=\"transparent\"\n borderWidth={0}\n // instruction={instruction}\n classNames={classNames}\n assets={{\n frontLandscapeGuidesImageUrl: frontImageUrl,\n backLandscapeGuidesImageUrl: backImageUrl,\n }}\n />\n ) : (\n <IdCaptureGuideOverlay\n landscapeGuidesImageUrl={imageUrl}\n maskColor=\"transparent\"\n borderWidth={0}\n isMirrored={isMirrored}\n instruction={instruction}\n classNames={classNames}\n imageVisible={imageVisible}\n />\n )}\n </>\n )\n}\n\nconst CanvasWrapper = styled.div<{ $maskColor: string }>`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n flex-grow: 1;\n background-clip: padding-box;\n box-shadow: inset 0 0 0 2px ${(props) => props.$maskColor};\n z-index: -1;\n`\n\nconst Canvas = styled.canvas`\n display: block;\n`\n","import {\n IdCaptureFitGuide,\n IdCaptureFitGuideClassNames,\n} from './IdCaptureFitGuide'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport React, { useContext } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useTranslations } from '../../lib/locales'\nimport { IdCaptureGuideOverlay } from './IdCaptureGuideOverlay'\nimport {\n IdCaptureAssets,\n IdCaptureColors,\n IdCaptureVerbiage,\n} from './IdCapture'\nimport { FlipIdPromptAssets } from './FlipIdPrompt'\n\nexport type IdCaptureGuideType = 'fit' | 'overlay'\n\nexport function IdCaptureGuides({\n guideType = 'fit',\n portraitGuidesOnMobile = false,\n requestingFlip = false,\n flipIdPromptAssets = {},\n classNames = {},\n assets = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: {\n guideType?: IdCaptureGuideType\n portraitGuidesOnMobile?: boolean\n requestingFlip?: boolean\n flipIdPromptAssets?: FlipIdPromptAssets\n classNames?: IdCaptureFitGuideClassNames\n assets?: IdCaptureAssets\n colors?: IdCaptureColors\n verbiage?: IdCaptureVerbiage\n}) {\n const [state] = useIdCaptureState()\n\n const { cameraRef } = useContext(CameraStateContext)\n\n const verbiage = useTranslations(rawVerbiage, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n capturingText: 'Capturing...',\n captureFailedText: 'Capture failed!',\n guidanceSatisfiedText: 'Document detected, hold still...',\n guidanceTooBlurryText: 'Document out of focus – try improving the lighting',\n guidanceNotCenteredText: 'Document is not centered',\n guidanceNotDetectedText: 'Document not detected',\n })\n\n const isMobile = window.innerWidth < window.innerHeight\n const frontImageUrl =\n portraitGuidesOnMobile && isMobile\n ? flipIdPromptAssets?.frontPortraitGuidesImageUrl\n : flipIdPromptAssets?.frontLandscapeGuidesImageUrl\n\n const backImageUrl =\n portraitGuidesOnMobile && isMobile\n ? flipIdPromptAssets?.backPortraitGuidesImageUrl\n : flipIdPromptAssets?.backLandscapeGuidesImageUrl\n\n return (\n <>\n {/* TODO: ternary for flip requests */}\n {guideType === 'overlay' && (\n <IdCaptureGuideOverlay\n classNames={classNames}\n width={state.pageWidth}\n height={state.pageHeight}\n instruction={\n state.captureFailed\n ? verbiage.captureFailedText\n : state.capturing\n ? verbiage?.capturingText\n : verbiage.instructionText\n }\n portraitGuidesImageUrl={assets.portraitGuidesImageUrl}\n landscapeGuidesImageUrl={assets.landscapeGuidesImageUrl}\n isMirrored={!cameraRef.current?.isRearFacing}\n borderColor={\n state.isGoodFrame\n ? colors.guideBoxSatisfiedColor\n : colors.guideBoxUnsatisfiedColor\n }\n imageVisible={\n requestingFlip ||\n !state.documentDetectionThresholdMet ||\n !state.documentInBounds ||\n state.documentTooClose\n }\n />\n )}\n\n {guideType === 'fit' && (\n <IdCaptureFitGuide\n classNames={classNames}\n requestingFlip={requestingFlip}\n instruction={\n state.captureFailed\n ? verbiage.captureFailedText\n : state.capturing\n ? verbiage?.capturingText\n : verbiage.instructionText\n }\n imageUrl={\n portraitGuidesOnMobile && isMobile\n ? assets?.portraitGuidesImageUrl\n : assets?.landscapeGuidesImageUrl\n }\n frontImageUrl={frontImageUrl}\n backImageUrl={backImageUrl}\n isMirrored={!cameraRef.current?.isRearFacing}\n borderColor={\n state.isGoodFrame\n ? colors.guideBoxSatisfiedColor\n : colors.guideBoxUnsatisfiedColor\n }\n imageVisible={\n requestingFlip ||\n !state.documentDetectionThresholdMet ||\n !state.documentInBounds ||\n state.documentTooClose\n }\n />\n )}\n </>\n )\n}\n","import { Spinner } from './spinner'\nimport styled from 'styled-components'\nimport React, { useRef, useState } from 'react'\nimport { error } from '../../lib/utils/logger'\n\nexport type IdCaptureImagePreviewClassNames = {\n container?: string\n text?: string\n imageContainer?: string\n image?: string\n}\n\nexport type IdCaptureImagePreviewProps = {\n classNames?: IdCaptureImagePreviewClassNames\n text?: string\n imageUrl: string\n}\n\nexport const IdCaptureImagePreview = ({\n classNames = {},\n text,\n imageUrl,\n}: IdCaptureImagePreviewProps) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [loaded, setLoaded] = useState(false)\n const [aspectRatio, setAspectRatio] = useState(0)\n\n function onLoad() {\n const aspectRatio =\n imageRef.current!.naturalWidth / imageRef.current!.naturalHeight\n setAspectRatio(aspectRatio)\n setLoaded(true)\n }\n\n function onError() {\n error('failed to load image from url', imageUrl)\n }\n\n return (\n <ImagePreviewWrapper\n className={classNames.container}\n style={{ opacity: loaded ? 1 : 0 }}\n >\n {text && (\n <ImagePreviewText className={classNames.text}>{text}</ImagePreviewText>\n )}\n\n <ImagePreviewImageWrapper\n className={classNames.imageContainer}\n style={{ aspectRatio }}\n >\n <img\n ref={imageRef}\n src={imageUrl}\n alt=\"\"\n className={classNames.image}\n onLoad={onLoad}\n onError={onError}\n />\n </ImagePreviewImageWrapper>\n </ImagePreviewWrapper>\n )\n}\n\nexport type SelfieProgressPreviewClassNames = {\n container?: string\n text?: string\n spinner?: string\n imageContainer?: string\n image?: string\n}\n\nexport type SelfieProgressPreviewProps = {\n classNames?: SelfieProgressPreviewClassNames\n text: string\n imageUrl: string\n}\n\nexport const SelfieProgressPreview = ({\n classNames = {},\n text,\n imageUrl,\n}: SelfieProgressPreviewProps) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [loaded, setLoaded] = useState(false)\n const [aspectRatio, setAspectRatio] = useState(0)\n\n function onLoad() {\n const aspectRatio =\n imageRef.current!.naturalWidth / imageRef.current!.naturalHeight\n setAspectRatio(aspectRatio)\n setLoaded(true)\n }\n\n function onError() {\n error('failed to load image from url', imageUrl)\n }\n\n return (\n <ImagePreviewWrapper\n className={classNames.container}\n style={{ aspectRatio, opacity: loaded ? 1 : 0 }}\n >\n <ImagePreviewText className={classNames.text}>\n <StyledSpinner\n className={classNames.spinner}\n $size={24}\n $color=\"white\"\n $thickness={3}\n />\n {text}\n </ImagePreviewText>\n\n <ImagePreviewImageWrapper className={classNames.imageContainer}>\n <img\n ref={imageRef}\n src={imageUrl}\n alt=\"\"\n className={classNames.image}\n onLoad={onLoad}\n onError={onError}\n />\n </ImagePreviewImageWrapper>\n </ImagePreviewWrapper>\n )\n}\n\nconst StyledSpinner = styled(Spinner)`\n position: relative;\n top: 4px;\n left: -3px;\n margin: 0 3px 0 -12px;\n`\n\nconst ImagePreviewWrapper = styled.div`\n position: absolute;\n display: flex;\n flex-direction: column;\n height: 33%;\n bottom: 12px;\n right: 12px;\n`\n\nconst ImagePreviewText = styled.div`\n display: block;\n position: absolute;\n top: -32px;\n font:\n 14px -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n Helvetica,\n Arial,\n sans-serif,\n 'Apple Color Emoji',\n 'Segoe UI Emoji',\n 'Segoe UI Symbol';\n color: white;\n text-align: center;\n margin: 0 auto;\n width: 100%;\n`\n\nconst ImagePreviewImageWrapper = styled.div`\n position: relative;\n height: calc(100% - 8px);\n padding: 4px;\n border-radius: 4px;\n background: white;\n\n & > img {\n border-radius: 4px;\n width: auto;\n max-height: 100%;\n }\n`\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useDebouncedCallback } from 'use-debounce'\nimport { drawToCanvas } from '../common/InvisibleCanvas'\nimport { CameraFeedMode } from '../../lib/camera/CameraFeedWrapper'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\n\nexport type OnDocumentCaptured = (document: CapturedDocument) => void\nexport type OnDocumentUploaded = (document: CapturedDocument) => void\nexport type OnAllDocumentsUploaded = (\n documents: CapturedDocument[],\n) => Promise<void>\n\nexport type CapturedDocument = {\n title?: string\n aspectRatio?: number\n cameraFeedMode?: CameraFeedMode\n instructions?: ReactNode\n documentId?: string\n content?: Blob\n contentUrl?: string\n uploadState?: DocumentCaptureUploadState\n onCaptured?: OnDocumentCaptured\n onUploaded?: OnDocumentUploaded\n}\n\ntype DocumentCaptureUploadState =\n | 'not_started'\n | 'in_progress'\n | 'succeeded'\n | 'failed'\n\nexport type DocumentCaptureState = {\n documents: CapturedDocument[]\n currentDocumentIndex: number\n initialDrawComplete: boolean\n redrawing: boolean\n rectX: number\n rectY: number\n rectWidth: number\n rectHeight: number\n rectOffsetTop: number\n capturing: boolean\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n}\n\nexport type DocumentCaptureStateWithActions = DocumentCaptureState & {\n uploadCapturedDocument: (content: Blob, filetype?: string) => Promise<void>\n}\n\nexport const documentCaptureInitialState = {\n documents: [],\n currentDocumentIndex: 0,\n initialDrawComplete: false,\n redrawing: false,\n capturing: false,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n uploadCapturedDocument: () => Promise.resolve(),\n} satisfies DocumentCaptureStateWithActions\n\nexport const DocumentCaptureStateContext =\n createContext<DocumentCaptureStateWithActions>(documentCaptureInitialState)\n\nexport type DocumentCaptureAction =\n | { type: 'setDocuments'; payload: CapturedDocument[] }\n | {\n type: 'setHooks'\n payload: {\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n }\n }\n | { type: 'redrawRequested' }\n | { type: 'redrawInProgress' }\n | {\n type: 'redrawCompleted'\n payload: {\n rectX: number\n rectY: number\n rectWidth: number\n rectHeight: number\n rectOffsetTop: number\n }\n }\n | { type: 'captureRequested' }\n | { type: 'captureCompleted'; payload: { content: Blob; contentUrl: string } }\n | { type: 'retryCapture' }\n | { type: 'uploadStarted' }\n | { type: 'uploadCompleted'; payload: { documentId: string } }\n | { type: 'uploadFailed' }\n\nexport type DocumentCaptureDispatch = Dispatch<DocumentCaptureAction>\n\nexport const DocumentCaptureDispatchContext =\n createContext<DocumentCaptureDispatch>(() => {})\n\nexport const documentCaptureStateReducer = (\n state: DocumentCaptureState,\n action: DocumentCaptureAction,\n): DocumentCaptureState => {\n switch (action.type) {\n case 'setDocuments':\n return { ...state, documents: action.payload, currentDocumentIndex: 0 }\n\n case 'setHooks':\n return { ...state, ...action.payload }\n\n case 'redrawRequested':\n return {\n ...state,\n redrawing: true,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n }\n\n case 'redrawInProgress':\n return {\n ...state,\n redrawing: false,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n }\n\n case 'redrawCompleted':\n return { ...state, ...action.payload, initialDrawComplete: true }\n\n case 'captureRequested':\n return { ...state, capturing: true }\n\n case 'captureCompleted': {\n const newState = { ...state, capturing: false }\n const index = state.currentDocumentIndex\n newState.documents[index].content = action.payload.content\n newState.documents[index].contentUrl = action.payload.contentUrl\n state.onDocumentCaptured?.(newState.documents[index])\n return newState\n }\n\n case 'retryCapture': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].content = undefined\n newState.documents[index].contentUrl = undefined\n return newState\n }\n\n case 'uploadStarted': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].uploadState = 'in_progress'\n return newState\n }\n\n case 'uploadCompleted': {\n const newState = { ...state }\n\n const index = state.currentDocumentIndex\n newState.documents[index].documentId = action.payload.documentId\n newState.documents[index].uploadState = 'succeeded'\n newState.documents[index].onUploaded?.(newState.documents[index])\n state.onDocumentUploaded?.(newState.documents[index])\n\n if (state.documents.length - 1 > index) {\n newState.currentDocumentIndex += 1\n } else {\n state.onAllDocumentsUploaded?.(newState.documents)\n }\n\n return newState\n }\n\n case 'uploadFailed': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].uploadState = 'failed'\n return newState\n }\n\n default:\n return state\n }\n}\n\nexport const DocumentCaptureStateProvider = ({\n documents = [],\n aspectRatio,\n cameraFeedMode,\n instructions,\n onDocumentCaptured,\n onDocumentUploaded,\n onAllDocumentsUploaded,\n children,\n}: {\n documents?: CapturedDocument[]\n aspectRatio?: number\n cameraFeedMode?: CameraFeedMode\n instructions?: ReactNode\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n children: ReactNode\n}) => {\n const [state, dispatch] = useReducer(\n documentCaptureStateReducer,\n documentCaptureInitialState,\n )\n\n const { cameraRef, videoRef } = useContext(CameraStateContext)\n const { uploadDocument } = useContext(SubmissionContext)\n\n const uploadCapturedDocument = useCallback(\n async (content: Blob, filetype?: string) => {\n try {\n dispatch({ type: 'uploadStarted' })\n const documentId = await uploadDocument(content!, { filetype })\n setTimeout(() => {\n dispatch({ type: 'uploadCompleted', payload: { documentId } })\n }, 0)\n } catch (e) {\n dispatch({ type: 'uploadFailed' })\n }\n },\n [uploadDocument],\n )\n\n useEffect(() => {\n const resolvedDocuments: CapturedDocument[] = documents?.length\n ? documents.map((d) => ({\n title: 'Document Capture',\n aspectRatio,\n cameraFeedMode: 'snapToGuides',\n instructions,\n ...d,\n uploadState: 'not_started',\n }))\n : [\n {\n title: 'Document Capture',\n aspectRatio,\n cameraFeedMode: cameraFeedMode ?? 'snapToGuides',\n instructions,\n uploadState: 'not_started',\n },\n ]\n\n dispatch({ type: 'setDocuments', payload: resolvedDocuments })\n\n resolvedDocuments.forEach((d) => {\n if (d.content) {\n d.contentUrl ||= URL.createObjectURL(d.content)\n uploadCapturedDocument(d.content, d.content.type)\n }\n })\n }, [\n aspectRatio,\n cameraFeedMode,\n documents,\n instructions,\n uploadCapturedDocument,\n ])\n\n useEffect(() => {\n dispatch({\n type: 'setHooks',\n payload: {\n onDocumentCaptured,\n onDocumentUploaded,\n onAllDocumentsUploaded,\n },\n })\n }, [onDocumentCaptured, onAllDocumentsUploaded, onDocumentUploaded])\n\n const onResize = useDebouncedCallback(() => {\n dispatch({ type: 'redrawRequested' })\n }, 500)\n\n useLayoutEffect(() => {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', onResize)\n return () => {\n window.removeEventListener('resize', onResize)\n }\n }, [onResize])\n\n const videoTag = videoRef.current\n useEffect(() => {\n if (!state.capturing) return\n if (!cameraRef.current) return\n\n function onComplete(content: Blob | null) {\n if (!content) return\n const contentUrl = URL.createObjectURL(content)\n dispatch({\n type: 'captureCompleted',\n payload: { content, contentUrl },\n })\n }\n\n if (typeof ImageCapture !== 'undefined') {\n const tracks = cameraRef.current.stream.getTracks()\n const videoCameraTrack = tracks.find((track) => {\n return track.kind === 'video'\n })\n\n if (videoCameraTrack) {\n const imageCapture = new ImageCapture(videoCameraTrack)\n imageCapture\n .takePhoto()\n .then(onComplete)\n .catch(() => {})\n } else {\n throw new Error('Failed to find a video feed for taking a photo')\n }\n } else if (videoTag) {\n const canvas = document.createElement('canvas')\n drawToCanvas(canvas, videoTag)\n canvas.toBlob(onComplete)\n }\n }, [cameraRef, state.capturing, videoTag])\n\n const stateWithActions = useMemo<DocumentCaptureStateWithActions>(\n () => ({ ...state, uploadCapturedDocument }),\n [state, uploadCapturedDocument],\n )\n\n return (\n <DocumentCaptureStateContext.Provider value={stateWithActions}>\n <DocumentCaptureDispatchContext.Provider value={dispatch}>\n {children}\n </DocumentCaptureDispatchContext.Provider>\n </DocumentCaptureStateContext.Provider>\n )\n}\n\nexport const useDocumentCaptureState = (): [\n DocumentCaptureStateWithActions,\n DocumentCaptureDispatch,\n] => {\n const state = useContext(DocumentCaptureStateContext)\n const dispatch = useContext(DocumentCaptureDispatchContext)\n if (!state || !dispatch)\n throw new Error(\n 'useDocumentCaptureState cannot be used without DocumentCaptureStateProvider',\n )\n\n return [state, dispatch]\n}\n","import React, { useEffect, useRef } from 'react'\nimport styled, { useTheme } from 'styled-components'\nimport useResizeObserver from 'use-resize-observer'\nimport { useDocumentCaptureState } from './DocumentCaptureStateProvider'\nimport {\n resetCanvasDimensions,\n setCanvasDimensions,\n} from '../../lib/utils/canvas'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type DocumentCaptureGuideOverlayClassNames = {\n container?: string\n}\n\nexport type DocumentCaptureGuideOverlayProps = {\n aspectRatio?: number\n borderRadius?: number\n borderColor?: string\n borderWidth?: number\n maskColor: string\n padding?: number\n classNames?: DocumentCaptureGuideOverlayClassNames\n}\n\nexport const DocumentCaptureGuideOverlay = ({\n aspectRatio,\n borderRadius = 25,\n borderColor,\n borderWidth,\n maskColor,\n padding,\n classNames = {},\n}: DocumentCaptureGuideOverlayProps) => {\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const [{ redrawing }, dispatch] = useDocumentCaptureState()\n\n const canvasRef = useRef<HTMLCanvasElement>(null)\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.documentCapture?.guideBox?.borderWidth ?? 4\n\n if (padding === undefined) {\n padding = isMobile()\n ? theme.documentCapture?.guideBox?.mobilePadding ?? 0\n : theme.documentCapture?.guideBox?.desktopPadding ?? 0\n }\n\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n\n if (redrawing) {\n resetCanvasDimensions(canvas)\n setTimeout(() => {\n dispatch({ type: 'redrawInProgress' })\n }, 10)\n return\n }\n\n const boundingWidth = wrapperWidth - padding! * 2 - borderWidth! * 2\n const boundingHeight = wrapperHeight - padding! * 2 - borderWidth! * 2\n\n let [rectX, rectY, rectWidth, rectHeight] = [\n padding! + borderWidth!,\n padding! + borderWidth!,\n boundingWidth,\n boundingHeight,\n ]\n\n if (aspectRatio !== undefined) {\n const scaledWidth = boundingHeight * aspectRatio\n const scaledHeight = boundingWidth / aspectRatio\n\n if (scaledWidth < boundingWidth) {\n rectWidth = scaledWidth\n rectX += (boundingWidth - rectWidth) / 2\n } else {\n rectHeight = scaledHeight\n rectY += (boundingHeight - rectHeight) / 2\n }\n }\n\n setCanvasDimensions(canvas, wrapperWidth, wrapperHeight)\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.fillStyle = maskColor\n ctx.clearRect(0, 0, wrapperWidth, wrapperHeight)\n ctx.fillRect(0, 0, wrapperWidth, wrapperHeight)\n\n // const radius = Math.min(wrapperWidth, wrapperHeight) / 2 - padding!\n ctx.beginPath()\n // ctx.arc(wrapperWidth / 2, wrapperHeight / 2, radius, 0, Math.PI * 2, true) // Hole anticlockwise\n ctx.roundRect(rectX, rectY, rectWidth, rectHeight, borderRadius!)\n\n ctx.lineWidth = borderWidth!\n ctx.strokeStyle = borderColor ?? 'white'\n ctx.stroke()\n\n // make alpha solid (the color doesn't matter)\n ctx.fillStyle = 'rgba(0,0,0,1)'\n\n // change composite mode and fill\n ctx.globalCompositeOperation = 'destination-out'\n ctx.fill()\n\n // reset composite mode to default\n ctx.globalCompositeOperation = 'source-over'\n\n const rectOffsetTop = canvas.offsetTop\n\n dispatch({\n type: 'redrawCompleted',\n payload: { rectX, rectY, rectWidth, rectHeight, rectOffsetTop },\n })\n }, [\n aspectRatio,\n borderColor,\n borderRadius,\n borderWidth,\n dispatch,\n maskColor,\n padding,\n redrawing,\n wrapperHeight,\n wrapperWidth,\n ])\n\n return (\n <CanvasWrapper\n ref={wrapperRef}\n className={classNames.container}\n $maskColor={maskColor}\n >\n <Canvas ref={canvasRef} />\n </CanvasWrapper>\n )\n}\n\nconst CanvasWrapper = styled.div<{ $maskColor: string }>`\n flex-grow: 1;\n background-clip: padding-box;\n box-shadow: inset 0 0 0 2px ${(props) => props.$maskColor};\n`\n\nconst Canvas = styled.canvas`\n display: block;\n`\n","import React, { useContext, useEffect, useState } from 'react'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { DocumentCaptureGuideOverlay } from './DocumentCaptureGuideOverlay'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { PageContainer } from '../common/Page'\nimport { useDocumentCaptureState } from './DocumentCaptureStateProvider'\nimport styled, { useTheme } from 'styled-components'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { CameraFeedWrapper } from '../../lib/camera/CameraFeedWrapper'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\n\nexport type DocumentCaptureScreenClassNames = {\n container?: string\n cameraFeedWrapper?: string\n cameraFeed?: string\n previewImage?: string\n captureContainer?: string\n headingRow?: string\n heading?: string\n footerRow?: string\n instructions?: string\n buttonsRow?: string\n retryCameraAccessBtn?: string\n retryCaptureBtn?: string\n uploadBtn?: string\n uploadProgressBtn?: string\n captureBtn?: string\n}\n\nexport type DocumentCaptureScreenVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n loadingBtnText?: CustomerSuppliedVerbiage\n retryCameraAccessBtnText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n capturingBtnText?: CustomerSuppliedVerbiage\n retryCaptureBtnText?: CustomerSuppliedVerbiage\n uploadBtnText?: CustomerSuppliedVerbiage\n uploadingBtnText?: CustomerSuppliedVerbiage\n retryUploadBtnText?: CustomerSuppliedVerbiage\n successBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type DocumentCaptureScreenProps = {\n onCaptureClicked?: () => void\n classNames?: DocumentCaptureScreenClassNames\n verbiage?: DocumentCaptureScreenVerbiage\n}\n\nexport const DocumentCaptureScreen = ({\n onCaptureClicked,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: DocumentCaptureScreenProps) => {\n const [\n {\n documents,\n currentDocumentIndex,\n rectX,\n rectY,\n rectWidth,\n rectHeight,\n rectOffsetTop,\n capturing,\n uploadCapturedDocument,\n },\n dispatch,\n ] = useDocumentCaptureState()\n\n const {\n title,\n aspectRatio,\n cameraFeedMode,\n instructions,\n contentUrl,\n content,\n uploadState,\n } = documents[currentDocumentIndex] ?? {}\n\n const { cameraRef, cameraReady, cameraAccessDenied, requestCameraAccess } =\n useContext(CameraStateContext)\n\n const [cameraAccessRequested, setCameraAccessRequested] = useState(false)\n const cameraAccessNeeded = // we should force the browser to ask for camera access if...\n uploadState === 'not_started' && // we aren't in the middle of uploading a document...\n !content && // and the user hasn't passed a media blob for the current document...\n !cameraAccessRequested && // and we haven't already tried to force a camera request...\n !cameraRef.current?.stream?.active // and we don't already have camera access.\n\n useEffect(\n function requestCameraAccessIfNeeded() {\n if (!cameraAccessNeeded) return\n setCameraAccessRequested(true)\n requestCameraAccess()\n },\n [cameraAccessNeeded, requestCameraAccess],\n )\n\n const theme = useTheme()\n\n const maskColor =\n theme.documentCapture?.guideBox?.maskColor ??\n (cameraFeedMode === 'snapToGuides' ? '#708090' : `rgba(0, 0, 0, 0.5)`)\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: title,\n loadingBtnText: 'Camera initializing...',\n retryCameraAccessBtnText: 'Retry',\n captureBtnText: 'Capture',\n capturingBtnText: 'Capturing...',\n retryCaptureBtnText: 'Retry capture',\n uploadBtnText: 'Upload',\n uploadingBtnText: 'Uploading...',\n retryUploadBtnText: 'Retry',\n successBtnText: 'Upload succeeded!',\n })\n\n function onCaptureClick() {\n dispatch({ type: 'captureRequested' })\n onCaptureClicked?.()\n }\n\n async function onSubmitClick() {\n await uploadCapturedDocument(content!, 'image/jpeg')\n }\n\n return (\n <PageContainer className={`flex ${classNames.container ?? ''}`}>\n <CameraFeedWrapper\n className={classNames.cameraFeedWrapper}\n $mode={cameraFeedMode ?? 'snapToGuides'}\n $x={rectX}\n $y={rectY + rectOffsetTop}\n $w={rectWidth}\n $h={rectHeight}\n >\n {contentUrl ? (\n <PreviewImage\n alt=\"\"\n src={contentUrl}\n className={classNames.previewImage}\n />\n ) : (\n <CameraVideoTag className={classNames.cameraFeed} />\n )}\n </CameraFeedWrapper>\n\n <CaptureContainer className={classNames.captureContainer}>\n <HeadingRow $maskColor={maskColor} className={classNames.headingRow}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n </HeadingRow>\n\n <DocumentCaptureGuideOverlay\n aspectRatio={aspectRatio}\n classNames={classNames}\n maskColor={maskColor}\n />\n\n <FooterRow $maskColor={maskColor} className={classNames.footerRow}>\n {instructions && (\n <Instructions className={classNames.instructions}>\n {instructions}\n </Instructions>\n )}\n <StyledButtonsRow className={classNames.buttonsRow}>\n {cameraAccessDenied ? (\n <LoaderButton\n className={classNames.retryCameraAccessBtn}\n variant=\"negative\"\n finished\n onClick={requestCameraAccess}\n >\n {verbiage.retryCameraAccessBtnText}\n </LoaderButton>\n ) : contentUrl ? (\n <>\n {uploadState === 'not_started' ? (\n <>\n <LoaderButton\n className={classNames.retryCaptureBtn}\n finished\n variant=\"warning\"\n onClick={() => {\n dispatch({ type: 'retryCapture' })\n }}\n >\n {verbiage.retryCaptureBtnText}\n </LoaderButton>\n\n <LoaderButton\n className={classNames.uploadBtn}\n finished\n variant=\"positive\"\n onClick={onSubmitClick}\n >\n {verbiage.uploadBtnText}\n </LoaderButton>\n </>\n ) : (\n <LoaderButton\n className={classNames.uploadProgressBtn}\n finished={uploadState !== 'in_progress'}\n variant={uploadState === 'failed' ? 'negative' : 'positive'}\n onClick={onSubmitClick}\n disabled={['in_progress', 'succeeded'].includes(\n uploadState ?? '',\n )}\n >\n {uploadState === 'succeeded'\n ? verbiage.successBtnText\n : uploadState === 'failed'\n ? verbiage.retryUploadBtnText\n : verbiage.uploadingBtnText}\n </LoaderButton>\n )}\n </>\n ) : (\n <LoaderButton\n className={classNames.captureBtn}\n finished={cameraReady}\n variant=\"primary\"\n onClick={onCaptureClick}\n disabled={!cameraReady || capturing}\n >\n {!cameraReady\n ? verbiage.loadingBtnText\n : capturing\n ? verbiage.capturingBtnText\n : verbiage.captureBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </FooterRow>\n </CaptureContainer>\n </PageContainer>\n )\n}\n\nconst CaptureContainer = styled.div`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: var(--app-height);\n`\n\nconst HeadingRow = styled.div<{ $maskColor: string }>`\n background: ${(props) => props.$maskColor};\n text-align: center;\n color: white;\n`\n\nconst Heading = styled.h1`\n font-size: 22px;\n`\n\nconst FooterRow = styled.div<{ $maskColor: string }>`\n background: ${(props) => props.$maskColor};\n display: flex;\n flex-direction: column;\n justify-content: center;\n padding: 0 20px 20px;\n height: auto;\n color: white;\n`\n\nconst Instructions = styled.div`\n max-height: ${(props) =>\n props.theme.documentCapture?.instructions?.maxHeight ?? '8rem'};\n overflow-y: auto;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n padding-top: 20px;\n`\n\nconst PreviewImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n`\n","import React, { useCallback, useEffect, useState } from 'react'\n\nexport function useFileState() {\n const [file, setFile] = useState<File>()\n\n const fileInputOnChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setFile(e.currentTarget?.files?.[0])\n },\n [setFile],\n )\n\n return {\n rawFile: file,\n fileInputOnChange,\n }\n}\n\nexport function useFileDataUrl(file?: File) {\n const [url, setUrl] = useState<string>()\n\n useEffect(() => {\n if (!file) return\n let aborted = false\n const reader = new FileReader()\n reader.onload = () => !aborted && setUrl(reader.result as string)\n reader.readAsDataURL(file)\n return () => {\n aborted = true\n }\n }, [file])\n\n return {\n url,\n }\n}\n\nexport function useResizeMaxEdge({\n rawFile,\n maxEdgePx = 2048, //This is based on \"2K of 2048 x 1080\n}: {\n rawFile?: File\n maxEdgePx?: number\n}) {\n const { url } = useFileDataUrl(rawFile)\n const [resizedImageFile, setResizedImageFile] = useState<string>()\n\n useEffect(() => {\n if (!url) return\n // A flag to prevent out-or-order errors\n let aborted = false\n\n const image = new Image()\n image.onload = async () => {\n if (aborted) return\n\n const { width, height } =\n image.width > image.height\n ? {\n width: maxEdgePx,\n height: (maxEdgePx / image.width) * image.height,\n }\n : {\n width: (maxEdgePx / image.height) * image.width,\n height: maxEdgePx,\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n\n const context = canvas.getContext('2d')\n if (context == null) throw new Error(\"Can't obtain canvas context\")\n context.imageSmoothingQuality = 'high'\n\n context.drawImage(\n image, // source image\n 0, // source x, y, width, height\n 0,\n image.width,\n image.height,\n 0, // destination x, y, width height\n 0,\n width,\n height,\n )\n\n const dataUrl = canvas.toDataURL('image/jpeg', 0.95)\n if (aborted) return\n setResizedImageFile(dataUrl)\n }\n\n image.src = url\n\n // If one of the props changes before the resize completes then\n // abort in case this run completes after a subsequent one and\n // overwrites the result.\n return () => {\n aborted = true\n }\n }, [maxEdgePx, url])\n\n return {\n resizedImageFile,\n }\n}\n","import React, { ReactElement, useEffect, useRef, useState } from 'react'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n OverlayContainer,\n OverlayImageRow,\n OverlayInner,\n} from '../common/overlay'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport {\n allowedImageCountForOption,\n IdCaptureRequirementOption,\n requiredImageCountForOption,\n} from '../id_capture/IdCaptureRequirementOption'\nimport { DocumentCaptureWizard } from '../document_capture/DocumentCaptureWizard'\nimport { CapturedDocument } from '../document_capture/DocumentCaptureStateProvider'\nimport { useFileState, useResizeMaxEdge } from '../../lib/utils/resizeFile'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type IdCaptureFallbackClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n imageContainer?: string\n imageCol?: string\n image?: string\n instruction?: string\n buttonsRow?: string\n captureBtn?: string\n captureMoreBtn?: string\n doneBtn?: string\n}\n\nexport type IdCaptureFallbackColors = {\n captureBtn?: LoaderButtonColors\n captureMoreBtn?: LoaderButtonColors\n doneBtn?: LoaderButtonColors\n}\n\nexport type IdCaptureFallbackVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n descriptionText?: CustomerSuppliedVerbiage\n firstInstructionText?: CustomerSuppliedVerbiage\n secondInstructionText?: CustomerSuppliedVerbiage\n thirdInstructionText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n captureMoreBtnText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureFallbackProps = {\n idCaptureRequirement?: IdCaptureRequirementOption\n onCapture?: (imageData: string) => void\n onFinished?: (images: string[]) => void\n classNames?: IdCaptureFallbackClassNames\n colors?: IdCaptureFallbackColors\n verbiage?: IdCaptureFallbackVerbiage\n silentFallback?: boolean\n}\n\nexport const IdCaptureFallback = ({\n idCaptureRequirement = 'idCardOrPassport',\n onCapture,\n onFinished,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n silentFallback = false,\n}: IdCaptureFallbackProps): ReactElement => {\n const lastResizedFileRef = useRef<string | null>(null)\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [images, setImages] = useState<string[]>([])\n const [documentToCapture, setDocumentToCapture] = useState<\n string | undefined\n >()\n const [useFallback, setUseFallback] = useState<boolean>(silentFallback)\n const allowedImageCount = allowedImageCountForOption(idCaptureRequirement)\n const requiredImageCount = requiredImageCountForOption(idCaptureRequirement)\n const { rawFile, fileInputOnChange } = useFileState()\n const { resizedImageFile } = useResizeMaxEdge({\n rawFile,\n })\n const [isProcessing, setIsProcessing] = useState(false) // helps eliminate some of the flicker as the image processes\n\n const whatToCapture =\n idCaptureRequirement === 'idCard'\n ? 'ID card'\n : idCaptureRequirement === 'passport'\n ? 'passport'\n : idCaptureRequirement === 'idCardOrPassport'\n ? 'ID card or passport'\n : 'ID card and passport'\n\n const firstInstructionText =\n idCaptureRequirement === 'idCard' ||\n idCaptureRequirement === 'idCardAndPassport'\n ? 'Please capture the front of your ID card.'\n : idCaptureRequirement === 'passport'\n ? 'Please capture the ID page of your passport.'\n : 'Please capture the front of your ID card, or the ID page of your passport.'\n\n const secondInstructionText =\n idCaptureRequirement === 'idCardOrPassport'\n ? 'Please capture the back of your ID card, or click Done if submitting a passport.'\n : 'Please capture the back of your ID card.'\n\n const descriptionText = `On-device capture guidance failed, please capture ${\n requiredImageCount > 1 ? 'photos' : ' a photo'\n } of your ${whatToCapture} manually.`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: `We're having some trouble.`,\n descriptionText,\n firstInstructionText,\n secondInstructionText,\n thirdInstructionText: 'Please capture the ID page of your passport.',\n captureBtnText: 'Capture',\n captureMoreBtnText: `Capture ${\n images.length === 2 ? 'ID page of passport' : 'back of ID card'\n }`,\n doneBtnText: 'Done',\n })\n\n useEffect(\n function resetAfterCapturingImage() {\n // we only want to run this IF the file has changed\n // there IS risk in this if we ever capture multiple documents that are the same (from files)\n if (resizedImageFile && resizedImageFile !== lastResizedFileRef.current) {\n lastResizedFileRef.current = resizedImageFile\n setImages((images) => [...images, resizedImageFile])\n onCapture?.(resizedImageFile)\n setDocumentToCapture(undefined)\n setUseFallback(false)\n setIsProcessing(false)\n }\n },\n [onCapture, resizedImageFile],\n )\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n if (!e.target.files?.[0]) return\n\n setDocumentToCapture(undefined)\n setIsProcessing(true)\n fileInputOnChange(e)\n }\n\n const instructionText =\n images.length === 0\n ? verbiage.firstInstructionText\n : images.length === 1\n ? verbiage.secondInstructionText\n : verbiage.thirdInstructionText\n\n if (useFallback) {\n setUseFallback(false)\n setDocumentToCapture(instructionText)\n }\n\n if ((!isMobile() && documentToCapture) || useFallback) {\n return (\n <DocumentCaptureWizard\n documents={[{ title: documentToCapture }]}\n onDocumentCaptured={(document: CapturedDocument) => {\n const imageData = document.contentUrl!\n onCapture?.(imageData)\n // todo: this a hack to address what is probably some sub-optimal coupling - fix\n setTimeout(() => {\n setImages((images) => [...images, imageData])\n setDocumentToCapture(undefined)\n }, 0)\n }}\n />\n )\n }\n\n return (\n <>\n <OverlayContainer className={classNames.container}>\n <StyledOverlayInner className={classNames.inner}>\n {!silentFallback && (\n <>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n <Description className={classNames.description}>\n {verbiage.descriptionText}\n </Description>\n </>\n )}\n\n {(images.length > 0 || isProcessing) && (\n <OverlayImageRow className={classNames.imageContainer}>\n {images.map((image, i) => (\n <ImageCol key={i} className={classNames.imageCol}>\n <img src={image} alt=\"\" className={classNames.image} />\n </ImageCol>\n ))}\n </OverlayImageRow>\n )}\n\n {images.length < requiredImageCount && (\n <Instruction className={classNames.instruction}>\n {instructionText}\n </Instruction>\n )}\n\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={onFileSelected}\n hidden\n />\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n {images.length < allowedImageCount && (\n <LoaderButton\n variant={images.length > 0 ? 'secondary' : 'positive'}\n className={\n images.length > 0\n ? classNames.captureMoreBtn\n : classNames.captureBtn\n }\n colors={\n images.length > 0 ? colors.captureMoreBtn : colors.captureBtn\n }\n finished\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setDocumentToCapture(instructionText)\n }\n }}\n >\n {images.length > 0\n ? verbiage.captureMoreBtnText\n : verbiage.captureBtnText}\n </LoaderButton>\n )}\n\n {images.length >= requiredImageCount && (\n <LoaderButton\n variant=\"positive\"\n className={classNames.doneBtn}\n colors={colors.doneBtn}\n finished\n onClick={() => {\n onFinished?.(images)\n }}\n >\n {verbiage.doneBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </StyledOverlayInner>\n </OverlayContainer>\n </>\n )\n}\n\nconst StyledOverlayInner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst Instruction = styled.p`\n font-weight: bold;\n`\n\nconst ImageCol = styled.div`\n display: flex;\n justify-content: center;\n flex-grow: 1;\n flex-basis: 0;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, {\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react'\nimport {\n IdCapture,\n IdCaptureAssets,\n IdCaptureClassNames,\n IdCaptureColors,\n IdCaptureVerbiage,\n} from './IdCapture'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n IdCaptureLoadingOverlay,\n IdCaptureLoadingOverlayAssets,\n IdCaptureLoadingOverlayClassNames,\n IdCaptureLoadingOverlayColors,\n IdCaptureLoadingOverlayMode,\n IdCaptureLoadingOverlayVerbiage,\n} from './IdCaptureLoadingOverlay'\nimport {\n FlipIdPromptAssets,\n FlipIdPromptClassNames,\n FlipIdPromptVerbiage,\n} from './FlipIdPrompt'\nimport {\n dataUrlToBase64,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport {\n CaptureAttemptMetadata,\n SubmissionStatus,\n} from '../../contexts/SubmissionContext'\nimport { CapturedDocuments, CapturedDocumentType } from './CapturedDocuments'\nimport {\n IdCaptureSuccess,\n IdCaptureSuccessClassNames,\n IdCaptureSuccessColors,\n IdCaptureSuccessVerbiage,\n} from './IdCaptureSuccess'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { PageContainer } from '../common/Page'\nimport {\n IdCaptureModelsContext,\n IdCapturePrediction,\n} from './IdCaptureModelsProvider'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { useTranslations } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { IdCaptureRequirementOption } from './IdCaptureRequirementOption'\nimport { CameraFeedWrapper } from '../../lib/camera/CameraFeedWrapper'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport { IdCaptureGuides, IdCaptureGuideType } from './IdCaptureGuides'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureImagePreview } from '../common/SelfieProgressPreview'\nimport { useTheme } from 'styled-components'\nimport {\n IdCaptureFallback,\n IdCaptureFallbackClassNames,\n IdCaptureFallbackColors,\n IdCaptureFallbackVerbiage,\n} from '../fallback_flows/IdCapture'\nimport { defaultDocumentDetectionThresholds } from '../../lib/models/DocumentDetection'\nimport { defaultFocusThresholds } from '../../lib/models/Focus'\n\nexport type IdCaptureWizardAssets = {\n documentDetectionModelUrl?: string\n focusModelUrl?: string\n loadingOverlay?: IdCaptureLoadingOverlayAssets\n idCardFront?: IdCaptureAssets\n idCardBack?: IdCaptureAssets\n passport?: IdCaptureAssets\n flipIdPrompt?: FlipIdPromptAssets\n}\n\nexport type IdCaptureWizardClassNames = {\n container?: string\n cameraFeed?: string\n loadingOverlay?: IdCaptureLoadingOverlayClassNames\n capture?: IdCaptureClassNames\n flipIdPrompt?: FlipIdPromptClassNames\n success?: IdCaptureSuccessClassNames\n fallback?: IdCaptureFallbackClassNames\n}\n\nexport type IdCaptureWizardColors = IdCaptureColors & {\n loadingOverlay?: IdCaptureLoadingOverlayColors\n success?: IdCaptureSuccessColors\n fallback?: IdCaptureFallbackColors\n}\n\nexport type IdCaptureWizardVerbiage = {\n loadingOverlay?: IdCaptureLoadingOverlayVerbiage\n idCardFront?: IdCaptureVerbiage\n idCardBack?: IdCaptureVerbiage\n passport?: IdCaptureVerbiage\n flipIdPrompt?: FlipIdPromptVerbiage\n success?: IdCaptureSuccessVerbiage\n fallback?: IdCaptureFallbackVerbiage\n}\n\nexport type IdCaptureSubmission = {\n idFrontImage?: string\n idBackImage?: string\n passportImage?: string\n}\n\nexport type IdCaptureWizardProps = {\n onSuccess?: (submission: IdCaptureSubmission) => void\n onExitCapture?: () => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: IdCaptureLoadingOverlayMode\n modelLoadTimeoutMs?: number\n precapturedDocuments?: CapturedDocuments\n captureRequirement?: IdCaptureRequirementOption\n separateIdCardCaptureSequence?: boolean\n autoCaptureEnabled?: boolean\n autoCaptureBarcodeRequired?: 'mobile' | boolean\n barcodeScanningEnabled?: boolean\n idCardAutoCaptureScoreThreshold?: number\n passportAutoCaptureScoreThreshold?: number\n mrzDetectionScoreThreshold?: number\n idCardFocusScoreThreshold?: number\n passportFocusScoreThreshold?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n instructions?: ReactNode\n releaseCameraAccessOnExit?: boolean\n guideType?: IdCaptureGuideType\n portraitGuidesOnMobile?: boolean\n rotateLoadingOverlayImageWhenPortrait?: boolean\n silentFallback?: boolean\n\n assets?: IdCaptureWizardAssets\n classNames?: IdCaptureWizardClassNames\n colors?: IdCaptureWizardColors\n verbiage?: IdCaptureWizardVerbiage\n debugMode?: boolean\n}\n\nexport const IdCaptureWizard = ({\n onSuccess,\n onExitCapture,\n onUserCancel,\n\n loadingOverlayMode = 'default',\n precapturedDocuments,\n captureRequirement = 'idCardOrPassport',\n separateIdCardCaptureSequence = false,\n autoCaptureEnabled = true,\n autoCaptureBarcodeRequired = 'mobile',\n barcodeScanningEnabled = false,\n idCardAutoCaptureScoreThreshold = defaultDocumentDetectionThresholds.idCard,\n passportAutoCaptureScoreThreshold = defaultDocumentDetectionThresholds.passport,\n mrzDetectionScoreThreshold = defaultDocumentDetectionThresholds.mrz,\n idCardFocusScoreThreshold = defaultFocusThresholds.idCard?.mobile,\n passportFocusScoreThreshold = defaultFocusThresholds.passport?.mobile,\n skipSuccessScreen = false,\n instructions,\n releaseCameraAccessOnExit = true,\n guideType = 'fit',\n portraitGuidesOnMobile = false,\n rotateLoadingOverlayImageWhenPortrait = true,\n silentFallback = false,\n\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: IdCaptureWizardProps): ReactElement => {\n const [state, dispatch] = useIdCaptureState()\n const { cameraAccessDenied, releaseCameraAccess } =\n useContext(CameraStateContext)\n const [overlayDismissed, setOverlayDismissed] = useState(false)\n const {\n submissionStatus,\n setIdFrontImage,\n setIdBackImage,\n setPassportImage,\n logIdFrontCaptureAttempt,\n logIdBackCaptureAttempt,\n } = useContext(SubmissionContext)\n const { start, stop, modelError, resetBestFrame } = useContext(\n IdCaptureModelsContext,\n )\n\n useEffect(() => {\n dispatch({\n type: 'configureWizard',\n payload: { captureRequirement, precapturedDocuments },\n })\n }, [captureRequirement, dispatch, precapturedDocuments])\n\n const documentCount = Object.keys(state.capturedDocuments).length\n\n useEffect(() => {\n documentCount && resetBestFrame()\n }, [documentCount, resetBestFrame])\n\n const logCaptureMetadata = useCallback(\n (metadata: CaptureAttemptMetadata) => {\n metadata.operationTime =\n new Date().getTime() -\n (state.operationStartedAt ?? new Date()).getTime()\n\n state.requestedDocumentType === 'idCardBack'\n ? logIdBackCaptureAttempt(metadata)\n : logIdFrontCaptureAttempt(metadata)\n },\n [\n logIdBackCaptureAttempt,\n logIdFrontCaptureAttempt,\n state.operationStartedAt,\n state.requestedDocumentType,\n ],\n )\n\n useEffect(\n function startModelsWhenCapturing() {\n if (!overlayDismissed || state.captureState !== 'capturing') return\n dispatch({ type: 'captureStarted' })\n start()\n return () => {\n stop()\n }\n },\n [dispatch, overlayDismissed, start, state.captureState, stop],\n )\n\n const onPrediction = useCallback(\n (prediction: IdCapturePrediction) => {\n dispatch({ type: 'predictionMade', payload: prediction })\n },\n [dispatch],\n )\n\n const onCapture = useCallback(\n (\n imageData: string,\n width: number,\n height: number,\n documentType: CapturedDocumentType,\n metadata: CaptureAttemptMetadata,\n ) => {\n logCaptureMetadata(metadata)\n dispatch({\n type: 'documentCaptured',\n payload: {\n imageData,\n width,\n height,\n documentType,\n boundingBox: metadata.boundingBox,\n },\n })\n },\n [dispatch, logCaptureMetadata],\n )\n\n const onSubmitClick = useCallback(() => {\n const { idCardFront, idCardBack, passport } = state.capturedDocuments\n\n const idFrontImage =\n idCardFront && dataUrlToBase64Sync(idCardFront.imageData)\n const idBackImage = idCardBack && dataUrlToBase64Sync(idCardBack.imageData)\n const passportImage = passport && dataUrlToBase64Sync(passport.imageData)\n\n idFrontImage && setIdFrontImage(idFrontImage)\n idBackImage && setIdBackImage(idBackImage)\n passportImage && setPassportImage(passportImage)\n\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onSuccess?.({ idFrontImage, idBackImage, passportImage })\n }, 0)\n }, [\n onSuccess,\n releaseCameraAccess,\n releaseCameraAccessOnExit,\n setIdBackImage,\n setIdFrontImage,\n setPassportImage,\n state.capturedDocuments,\n ])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n state.captureState === 'complete',\n onSubmitClick,\n )\n\n const onRetryClick = useCallback(() => {\n dispatch({ type: 'resetWizard' })\n }, [dispatch])\n\n const [attempt, setAttempt] = useState(0)\n const onExit = useCallback(() => {\n setOverlayDismissed(false)\n setAttempt((n) => n + 1)\n dispatch({ type: 'resetWizard' })\n onExitCapture?.()\n }, [dispatch, onExitCapture])\n\n useEffect(() => {\n if (submissionStatus !== SubmissionStatus.READY) {\n releaseCameraAccessOnExit && releaseCameraAccess()\n }\n }, [releaseCameraAccess, releaseCameraAccessOnExit, submissionStatus])\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setOverlayDismissed(false)\n setAttempt((n) => n + 1)\n }\n }, [cameraAccessDenied])\n\n assets.idCardFront ||= {}\n assets.idCardFront.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.idCardFront.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.idCardBack ||= {}\n assets.idCardBack.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Portrait-2.svg`\n assets.idCardBack.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n assets.passport ||= {}\n assets.passport.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-Passport-Front-SVG-Portrait-2.svg`\n assets.passport.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-Passport-Front-SVG-Landscape-2.svg`\n assets.flipIdPrompt ||= {}\n assets.flipIdPrompt.frontPortraitGuidesImageUrl ||=\n assets.idCardFront.portraitGuidesImageUrl\n assets.flipIdPrompt.frontLandscapeGuidesImageUrl ||=\n assets.idCardFront.landscapeGuidesImageUrl\n assets.flipIdPrompt.backPortraitGuidesImageUrl ||=\n assets.idCardBack.portraitGuidesImageUrl\n assets.flipIdPrompt.backLandscapeGuidesImageUrl ||=\n assets.idCardBack.landscapeGuidesImageUrl\n\n const idCaptureVerbiages = {\n idCardFront: useTranslations(verbiage.idCardFront, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n }),\n idCardBack: useTranslations(verbiage.idCardBack, {\n instructionText: 'Scan the back of ID',\n }),\n passport: useTranslations(verbiage.passport, {\n instructionText: 'Scan the ID page of passport',\n }),\n }\n\n const theme = useTheme()\n const [\n { guideRectX, guideRectY, guideRectWidth, guideRectHeight, imageUrl },\n ] = useIdCaptureState()\n\n const idCaptureAssets = assets[\n state.requestedDocumentType as keyof typeof assets\n ] as IdCaptureAssets\n\n const idCaptureVerbiage = idCaptureVerbiages[\n state.requestedDocumentType as keyof typeof idCaptureVerbiages\n ] as IdCaptureVerbiage\n\n useEffect(() => {\n if (separateIdCardCaptureSequence) return\n if (state.captureState === 'requestingFlip') {\n setTimeout(() => {\n dispatch({ type: 'flipRequestCompleted' })\n }, 6000)\n }\n }, [dispatch, separateIdCardCaptureSequence, state.captureState])\n\n const handleCapture = useCallback(\n async (imageData: string) => {\n const base64ImageData = await dataUrlToBase64(imageData)\n dispatch({\n type: 'documentCapturedManually',\n payload: { imageData: base64ImageData },\n })\n },\n [dispatch],\n )\n\n useEffect(() => {}, [])\n\n if (modelError) {\n return (\n <IdCaptureFallback\n idCaptureRequirement={captureRequirement}\n onFinished={onSubmitClick}\n onCapture={handleCapture}\n classNames={classNames.fallback}\n colors={colors.fallback}\n verbiage={verbiage.fallback}\n silentFallback={silentFallback}\n />\n )\n }\n\n return (\n <PageContainer className={`flex ${classNames?.container ?? ''}`}>\n {state.captureState !== 'complete' && (\n <CameraFeedWrapper\n $x={guideRectX}\n $y={guideRectY}\n $w={guideRectWidth}\n $h={guideRectHeight}\n $mode={guideType === 'fit' ? 'snapToGuides' : 'fullscreen'}\n >\n <CameraVideoTag className={classNames?.cameraFeed} />\n </CameraFeedWrapper>\n )}\n\n {overlayDismissed && state.captureState === 'capturing' && (\n <IdCapture\n requiredDocumentType={state.requestedDocumentType}\n autoCaptureEnabled={autoCaptureEnabled}\n idCardDetectionThreshold={idCardAutoCaptureScoreThreshold}\n passportDetectionThreshold={passportAutoCaptureScoreThreshold}\n idCardFocusScoreThreshold={idCardFocusScoreThreshold}\n passportFocusScoreThreshold={passportFocusScoreThreshold}\n mrzDetectionScoreThreshold={mrzDetectionScoreThreshold}\n autoCaptureBarcodeRequired={autoCaptureBarcodeRequired}\n barcodeScanningEnabled={\n barcodeScanningEnabled &&\n state.requestedDocumentType === 'idCardBack'\n }\n onPrediction={onPrediction}\n onCapture={onCapture}\n assets={idCaptureAssets}\n classNames={classNames?.capture}\n colors={colors}\n verbiage={idCaptureVerbiage}\n debugMode={debugMode}\n />\n )}\n\n <IdCaptureGuides\n guideType={guideType}\n portraitGuidesOnMobile={portraitGuidesOnMobile}\n requestingFlip={state.captureState === 'requestingFlip'}\n flipIdPromptAssets={assets?.flipIdPrompt}\n classNames={classNames}\n assets={idCaptureAssets}\n colors={colors}\n verbiage={idCaptureVerbiage}\n />\n\n {!theme.idCapture?.capturePreview?.disabled &&\n state.captureState === 'requestingFlip' &&\n !separateIdCardCaptureSequence &&\n imageUrl && (\n <IdCaptureImagePreview\n classNames={classNames.capture?.imagePreview}\n text={idCaptureVerbiages?.idCardFront?.processingIdCardText}\n imageUrl={imageUrl}\n />\n )}\n\n {state.captureState !== 'complete' && (\n <div id=\"idmission-above-guides-content\" />\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.capture?.exitCaptureBtn}\n />\n\n {!overlayDismissed && (\n <IdCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n instructions={instructions}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onUserCancel={onUserCancel}\n onDismissed={() => {\n setOverlayDismissed(true)\n }}\n rotateImage={\n rotateLoadingOverlayImageWhenPortrait &&\n portraitGuidesOnMobile &&\n window.innerWidth < window.innerHeight\n }\n />\n )}\n\n {state.captureState === 'requestingFlip' &&\n separateIdCardCaptureSequence && (\n <IdCaptureSuccess\n capturedDocuments={state.capturedDocuments}\n classNames={classNames.success}\n onSubmitClick={() => {\n dispatch({ type: 'flipRequestCompleted' })\n }}\n onRetryClick={onRetryClick}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )}\n\n {state.captureState === 'complete' && showSuccessScreen && (\n <IdCaptureSuccess\n capturedDocuments={state.capturedDocuments}\n barcodeResult={state.barcodeResult}\n classNames={classNames.success}\n onSubmitClick={onSubmitClick}\n onRetryClick={onRetryClick}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )}\n </PageContainer>\n )\n}\n","import * as React from 'react'\nimport {\n createContext,\n MutableRefObject,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { error } from '../../lib/utils/logger'\nimport {\n defaultSelfieCaptureModelLoadTimeoutMs,\n Face,\n makeFaceDetectorPrediction,\n useLoadFaceDetector,\n} from '../../lib/models/FaceDetection'\nimport { useFrameLoop } from '../../lib/models/FrameLoop'\n\ntype PredictionHandler = (prediction: Face[]) => void\n\ntype SelfieGuidanceModelsState = {\n start: () => void\n stop: () => void\n onPredictionMade: (handler: PredictionHandler) => void\n canvasRef: MutableRefObject<HTMLCanvasElement | null>\n ready: boolean\n error: Error | null\n modelDownloadProgress: number\n}\n\nexport const SelfieGuidanceModelsContext =\n createContext<SelfieGuidanceModelsState>({\n start: () => null,\n stop: () => null,\n onPredictionMade: () => null,\n canvasRef: { current: null },\n ready: false,\n error: null,\n modelDownloadProgress: 0,\n })\n\nexport type SelfieGuidanceModelsProviderProps = {\n autoStart?: boolean\n children: ReactNode\n throttleMs?: number\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}\n\nexport function SelfieGuidanceModelsProvider({\n autoStart = true,\n children,\n throttleMs,\n onModelError,\n modelLoadTimeoutMs = defaultSelfieCaptureModelLoadTimeoutMs,\n}: SelfieGuidanceModelsProviderProps): ReactElement {\n const { videoRef, videoLoaded, cameraReady } = useContext(CameraStateContext)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const onPredictionHandler = useRef<PredictionHandler>()\n\n const { detector, ready, modelDownloadProgress, modelError } =\n useLoadFaceDetector({ onModelError, modelLoadTimeoutMs })\n\n const { start, stop } = useFrameLoop(\n useCallback(async () => {\n if (\n !videoLoaded ||\n !cameraReady ||\n !ready ||\n modelError ||\n !videoRef.current ||\n !detector.current ||\n !canvasRef.current\n )\n return\n\n const vw = videoRef.current.videoWidth\n const vh = videoRef.current.videoHeight\n const ctx = canvasRef.current.getContext('2d')\n canvasRef.current.width = vw\n canvasRef.current.height = vh\n\n if (ctx && videoRef.current.readyState === 4) {\n ctx.translate(vw, 0)\n ctx.scale(-1, 1)\n ctx.drawImage(videoRef.current, 0, 0, vw, vh)\n\n // Detectors can throw errors, for example when using custom URLs that\n // contain a model that doesn't provide the expected output.\n try {\n const { faces } = makeFaceDetectorPrediction(\n detector.current,\n canvasRef.current,\n )\n onPredictionHandler.current?.(faces)\n } catch (e) {\n error('caught face detection error', e)\n }\n }\n }, [cameraReady, detector, modelError, ready, videoLoaded, videoRef]),\n { throttleMs, autoStart },\n )\n\n const onPredictionMade = useCallback((handler: PredictionHandler) => {\n onPredictionHandler.current = handler\n }, [])\n\n const value = useMemo<SelfieGuidanceModelsState>(\n () => ({\n start,\n stop,\n ready,\n canvasRef,\n onPredictionMade,\n error: modelError,\n modelDownloadProgress,\n }),\n [modelError, modelDownloadProgress, onPredictionMade, ready, start, stop],\n )\n\n return (\n <SelfieGuidanceModelsContext.Provider value={value}>\n <InvisibleCanvas ref={canvasRef} />\n {children}\n </SelfieGuidanceModelsContext.Provider>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport const useTimeout = (\n durationMs?: number,\n onTimeout?: () => void,\n timeoutAverted?: boolean,\n shouldWaitLonger?: boolean,\n shouldStart: boolean = true,\n) => {\n const [timedOut, setTimedOut] = useState(false)\n const [timeoutStartedAt, setTimeoutStartedAt] = useState<Date | null>()\n\n useEffect(() => {\n if (!durationMs || !shouldStart) return\n\n setTimeoutStartedAt(new Date())\n const timer = setTimeout(() => {\n setTimedOut(true)\n }, durationMs)\n\n return () => {\n if (timer) clearTimeout(timer)\n }\n }, [durationMs, shouldStart])\n\n useEffect(() => {\n if (!timedOut || timeoutAverted) return\n if (!shouldWaitLonger) {\n onTimeout?.()\n return\n }\n\n const t = setTimeout(() => {\n onTimeout?.()\n }, 120000)\n\n return () => {\n clearTimeout(t)\n }\n }, [onTimeout, shouldWaitLonger, timedOut, timeoutAverted])\n\n return { timedOut, timeoutStartedAt }\n}\n","import React, { ReactElement, useEffect, useRef, useState } from 'react'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { DocumentCaptureWizard } from '../document_capture/DocumentCaptureWizard'\nimport { CapturedDocument } from '../document_capture/DocumentCaptureStateProvider'\nimport { useFileState, useResizeMaxEdge } from '../../lib/utils/resizeFile'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type SelfieCaptureFallbackClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n imageContainer?: string\n image?: string\n buttonsRow?: string\n captureBtn?: string\n doneBtn?: string\n retryCaptureBtn?: string\n}\n\nexport type SelfieCaptureFallbackColors = {\n captureBtn?: LoaderButtonColors\n doneBtn?: LoaderButtonColors\n}\n\nexport type SelfieCaptureFallbackVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n descriptionText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n doneBtnLoadingText?: CustomerSuppliedVerbiage\n livenessFailedText?: CustomerSuppliedVerbiage\n livenessFailedReasonText?: CustomerSuppliedVerbiage\n retryButtonText?: CustomerSuppliedVerbiage\n retryCaptureButtonText?: CustomerSuppliedVerbiage\n}\n\nexport type SelfieCaptureFallbackProps = {\n onFinished?: (imageData: string) => void\n onCapture?: (imageData: string) => void\n classNames?: SelfieCaptureFallbackClassNames\n colors?: SelfieCaptureFallbackColors\n verbiage?: SelfieCaptureFallbackVerbiage\n silentFallback?: boolean\n invalidSelfie?: boolean\n guidanceMessage?: string\n}\n\nexport const SelfieCaptureFallback = ({\n onFinished,\n onCapture,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n silentFallback = false,\n invalidSelfie = false,\n guidanceMessage = undefined,\n}: SelfieCaptureFallbackProps): ReactElement => {\n const [image, setImage] = useState<string | null>(null)\n const lastResizedFileRef = useRef<string | null>(null)\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [loading, setLoading] = useState(false)\n const [usingDocumentCapture, setUsingDocumentCapture] = useState(false)\n const { rawFile, fileInputOnChange } = useFileState()\n const { resizedImageFile } = useResizeMaxEdge({\n rawFile: rawFile,\n })\n\n useEffect(\n function resetAfterCapturingImage() {\n // we only want to run this IF the file has changed\n if (resizedImageFile && resizedImageFile !== lastResizedFileRef.current) {\n lastResizedFileRef.current = resizedImageFile\n setImage(resizedImageFile)\n setLoading(true)\n onCapture?.(resizedImageFile)\n onFinished?.(resizedImageFile)\n }\n },\n [resizedImageFile, onCapture, onFinished, loading],\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: `We're having some trouble.`,\n descriptionText: silentFallback\n ? 'Use your device camera to capture your face'\n : 'On-device capture guidance failed, please capture a selfie manually.',\n captureBtnText: 'Capture',\n doneBtnText: 'Done',\n doneBtnLoadingText: 'Verifying...',\n livenessFailedText: 'Live face not detected, please try again',\n livenessFailedReasonText: guidanceMessage,\n retryButtonText: 'Retry',\n retryCaptureButtonText: 'Retry capture',\n })\n\n useEffect(\n function triggerInputWhenInSilentFallbackMode() {\n let fallbackTimeout: NodeJS.Timeout\n if (silentFallback) {\n fallbackTimeout = setTimeout(() => {\n // using the input element, we want to click on it \"immediately\" which is 250ms to allow for even old browsers to finish connecting the input\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setUsingDocumentCapture(true)\n }\n }, 250)\n }\n\n return () => {\n clearTimeout(fallbackTimeout)\n }\n },\n [silentFallback],\n )\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n if (!e.target.files?.[0]) return\n setImage('LOADING') // this is to reduce some of the flicker - it isn't perfect since .readAsDataURL() is slow\n fileInputOnChange(e)\n }\n\n if (\n usingDocumentCapture ||\n (silentFallback && !!invalidSelfie && !image && !isMobile()) // desktop silent fallback - not a very realistic situation\n ) {\n return (\n <DocumentCaptureWizard\n documents={[\n {\n title: invalidSelfie\n ? verbiage.livenessFailedText\n : verbiage.descriptionText,\n },\n ]}\n onDocumentCaptured={(document: CapturedDocument) => {\n const imageData = document.contentUrl!\n onCapture?.(imageData)\n // todo: this a hack to address what is probably some sub-optimal coupling - fix\n setTimeout(() => {\n setImage(imageData)\n setUsingDocumentCapture(false)\n }, 0)\n }}\n />\n )\n }\n\n // todo: JN - we might be able to use the media stream instead if we clone it - as it stands today, we hae to use the camera to support iOS 16 devices\n return (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={onFileSelected}\n hidden\n />\n\n <OverlayContainer className={classNames.container}>\n <StyledOverlayInner className={classNames.inner}>\n {silentFallback ? (\n invalidSelfie && (\n <>\n <Heading className={classNames.heading}>\n {verbiage.livenessFailedText}\n </Heading>\n\n <Description className={classNames.description}>\n {verbiage.livenessFailedReasonText ||\n verbiage.descriptionText}\n </Description>\n </>\n )\n ) : (\n <>\n <Heading className={classNames.heading}>\n {invalidSelfie\n ? verbiage.livenessFailedText\n : verbiage.headingText}\n </Heading>\n\n <Description className={classNames.description}>\n {verbiage.livenessFailedReasonText || verbiage.descriptionText}\n </Description>\n </>\n )}\n\n {image && image !== 'LOADING' && (\n <ImageContainer className={classNames.imageContainer}>\n <img src={image} alt=\"\" className={classNames.image} />\n </ImageContainer>\n )}\n\n {/* todo: JN - this is arguably super gross - should break into two components - 1 for fallback and one for silentFallback*/}\n <StyledButtonsRow className={classNames.buttonsRow}>\n {image && !loading && !isMobile() && (\n <LoaderButton\n className={classNames.retryCaptureBtn}\n finished\n variant=\"warning\"\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setUsingDocumentCapture(true)\n }\n }}\n >\n {verbiage.retryCaptureButtonText}\n </LoaderButton>\n )}\n <LoaderButton\n variant=\"positive\"\n key={loading ? 'loading-btn' : 'ready-btn'}\n className={!image ? classNames.captureBtn : classNames?.doneBtn}\n colors={!image ? colors.captureBtn : colors?.doneBtn}\n finished={!image ? true : !loading}\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n if (!image) {\n setUsingDocumentCapture(true)\n } else {\n setLoading(true)\n onFinished?.(image)\n }\n }\n }}\n >\n {!image\n ? invalidSelfie\n ? verbiage.retryButtonText\n : verbiage.captureBtnText\n : loading\n ? verbiage.doneBtnLoadingText\n : verbiage.doneBtnText}\n </LoaderButton>\n </StyledButtonsRow>\n </StyledOverlayInner>\n </OverlayContainer>\n </>\n )\n}\n\nconst StyledOverlayInner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst ImageContainer = styled(OverlayImageContainer)`\n margin-top: 32px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport useResizeObserver from 'use-resize-observer'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n FaceCaptureGuideOverlay,\n FaceCaptureGuideOverlayClassNames,\n} from '../face_liveness/FaceCaptureGuideOverlay'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { PageContainer } from '../common/Page'\nimport {\n DebugStatsPane,\n ObjectDetectionDebugOverlayDiv,\n SelfieCaptureFaceDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n clearCanvas,\n drawToCanvas,\n InvisibleCanvas,\n} from '../common/InvisibleCanvas'\nimport {\n SelfieCaptureFallback,\n SelfieCaptureFallbackClassNames,\n} from '../fallback_flows/SelfieCapture'\nimport { Face } from '../../lib/models/FaceDetection'\n\ntype State = {\n videoWidth: number\n videoHeight: number\n\n capturing: boolean\n captured: boolean\n captureFailed: boolean\n\n frame: ImageBitmap | null\n faces: Face[]\n faceNotCentered: boolean\n faceLookingAway: boolean\n faceTooClose: boolean\n faceTooFar: boolean\n faceReady: boolean\n faceReadyAt: Date | null\n\n // TODO: remove good frames threshold\n goodFramesCount: number\n goodFramesThreshold: number\n goodFramesThresholdMet: boolean\n}\n\nconst initialState: State = {\n videoWidth: 0,\n videoHeight: 0,\n\n capturing: false,\n captured: false,\n captureFailed: false,\n\n frame: null,\n faces: [],\n faceNotCentered: false,\n faceLookingAway: false,\n faceTooClose: false,\n faceTooFar: false,\n faceReady: false,\n faceReadyAt: null,\n\n goodFramesCount: 0,\n goodFramesThreshold: 1,\n goodFramesThresholdMet: false,\n}\n\ntype Action =\n | { type: 'configure'; payload: { videoWidth: number; videoHeight: number } }\n | { type: 'capturing' }\n | { type: 'captured' }\n | { type: 'captureFailed' }\n | { type: 'facesDetected'; payload: { frame?: ImageBitmap; faces: Face[] } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'configure':\n return {\n ...state,\n videoWidth: action.payload.videoWidth,\n videoHeight: action.payload.videoHeight,\n }\n\n case 'capturing':\n return {\n ...state,\n capturing: true,\n captured: false,\n captureFailed: false,\n }\n\n case 'captured':\n return {\n ...state,\n capturing: false,\n captured: true,\n captureFailed: false,\n }\n\n case 'captureFailed':\n return {\n ...state,\n capturing: false,\n captured: false,\n captureFailed: true,\n }\n\n case 'facesDetected': {\n const { faces } = action.payload\n const face = faces[0]\n\n let faceNotCentered = true,\n faceLookingAway = false,\n faceTooClose = false,\n faceTooFar = false,\n faceReadyAt = state.faceReadyAt,\n goodFramesCount = state.goodFramesCount\n\n if (face) {\n // calculate centroids\n const vCX = state.videoWidth / 2\n const vCY = state.videoHeight / 2\n const fCX = (face.box.xMin + face.box.xMax) / 2\n const fCY = (face.box.yMin + face.box.yMax) / 2\n\n // calculate thresholds\n const vTX = state.videoWidth * 0.125\n const vTY = state.videoHeight * 0.125\n const fTW = face.box.width * 0.2\n const fTH = face.box.height * 0.2\n\n const nose = face.keypoints[2] //.find((k) => k.name === 'noseTip')\n if (nose) {\n faceNotCentered =\n Math.abs(vCX - fCX) > vTX || Math.abs(vCY + 50 - fCY) > vTY\n faceLookingAway =\n Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH\n }\n\n const isMobile = state.videoWidth < state.videoHeight\n\n const tooCloseMultiple = isMobile ? 2 : 4.5\n const tooFarMultiple = isMobile ? 6 : 7\n faceTooClose = face.box.width > state.videoWidth / tooCloseMultiple\n faceTooFar = face.box.width < state.videoWidth / tooFarMultiple\n }\n\n const faceReady =\n !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar\n\n if (!faceReady) {\n faceReadyAt = null\n goodFramesCount = 0\n } else if (!state.faceReady) {\n faceReadyAt = new Date()\n }\n\n return {\n ...state,\n faces,\n faceNotCentered,\n faceLookingAway,\n faceTooClose,\n faceTooFar,\n faceReady,\n faceReadyAt,\n goodFramesCount,\n }\n }\n }\n}\n\nexport type SelfieCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guides?: FaceCaptureGuideOverlayClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n exitCaptureBtn?: string\n fallback?: SelfieCaptureFallbackClassNames\n}\n\nexport type SelfieCaptureColors = {\n guidesUnsatisfiedColor?: string\n guidesSatisfiedColor?: string\n guidanceMessagesSatisfiedBackgroundColor?: string\n guidanceMessagesUnsatisfiedBackgroundColor?: string\n guidanceMessagesSatisfiedTextColor?: string\n guidanceMessagesUnsatisfiedTextColor?: string\n}\n\nexport type SelfieCaptureVerbiage = {\n guidanceHoldStillText?: CustomerSuppliedVerbiage\n guidanceLookStraightText?: CustomerSuppliedVerbiage\n guidanceMoveBackText?: CustomerSuppliedVerbiage\n guidanceMoveForwardText?: CustomerSuppliedVerbiage\n guidanceMoveToCenterText?: CustomerSuppliedVerbiage\n}\n\nexport type SelfieCaptureProps = {\n onGuidanceSatisfied?: () => void\n onGuidanceNotSatisfied?: () => void\n onSelfieCaptured?: (frame: ImageData, face: Face) => void\n onTimeout?: () => void\n onExit?: () => void\n timeoutDurationMs?: number\n guidanceMessage?: string\n guidanceSatisfied?: boolean\n classNames?: SelfieCaptureClassNames\n colors?: SelfieCaptureColors\n verbiage?: SelfieCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const SelfieCapture = ({\n onGuidanceSatisfied,\n onGuidanceNotSatisfied,\n onSelfieCaptured,\n onTimeout,\n onExit,\n timeoutDurationMs = 15000,\n guidanceMessage,\n guidanceSatisfied,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: SelfieCaptureProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const [state, dispatch] = useReducer(reducer, initialState)\n const lastPredictionCanvas = useRef<HTMLCanvasElement | null>(null)\n const { cameraRef, cameraReady, videoRef } = useContext(CameraStateContext)\n const { onPredictionMade, error: guidanceError } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n useEffect(() => {\n if (cameraReady && videoRef.current && videoRef.current.videoWidth !== 0) {\n dispatch({\n type: 'configure',\n payload: {\n videoWidth: videoRef.current.videoWidth,\n videoHeight: videoRef.current.videoHeight,\n },\n })\n }\n }, [cameraReady, videoRef])\n\n useEffect(() => {\n onPredictionMade((prediction) => {\n dispatch({\n type: 'facesDetected',\n payload: { faces: prediction },\n })\n })\n }, [onPredictionMade])\n\n const [captureReady, setCaptureReady] = useState(false)\n useEffect(() => {\n let timer: NodeJS.Timer\n\n if (state.faceReady) {\n onGuidanceSatisfied?.()\n timer = setTimeout(() => {\n setCaptureReady(true)\n }, 1000)\n } else {\n onGuidanceNotSatisfied?.()\n }\n\n return () => {\n if (timer) clearTimeout(timer)\n }\n }, [onGuidanceNotSatisfied, onGuidanceSatisfied, state.faceReady])\n\n useEffect(() => {\n ;(async () => {\n if (\n captureReady &&\n videoRef.current &&\n lastPredictionCanvas.current &&\n state.faces.length > 0\n ) {\n drawToCanvas(lastPredictionCanvas.current, videoRef.current)\n const ctx = lastPredictionCanvas.current.getContext('2d')\n if (!ctx) return\n const imageData = ctx.getImageData(\n 0,\n 0,\n videoRef.current.videoWidth,\n videoRef.current.videoHeight,\n )\n\n onSelfieCaptured?.(imageData, state.faces[0])\n clearCanvas(lastPredictionCanvas.current)\n }\n })()\n }, [captureReady, onSelfieCaptured, state.faces, videoRef])\n\n const { timedOut, timeoutStartedAt } = useTimeout(\n timeoutDurationMs,\n onTimeout,\n )\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: width,\n pageHeight: height,\n videoWidth: state.videoWidth,\n videoHeight: state.videoHeight,\n })\n\n colors.guidesUnsatisfiedColor ||= 'white'\n colors.guidesSatisfiedColor ||= 'green'\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceHoldStillText: 'Hold still for a few seconds...',\n guidanceLookStraightText: 'Look straight into the camera...',\n guidanceMoveBackText: 'Move back...',\n guidanceMoveForwardText: 'Move forward...',\n guidanceMoveToCenterText: 'Move to the center...',\n })\n\n let satisfied = state.faceReady\n if (typeof guidanceSatisfied === 'boolean') satisfied = guidanceSatisfied\n\n guidanceMessage ||= satisfied\n ? verbiage.guidanceHoldStillText\n : state.faceLookingAway\n ? verbiage.guidanceLookStraightText\n : state.faceTooClose\n ? verbiage.guidanceMoveBackText\n : state.faceTooFar\n ? verbiage.guidanceMoveForwardText\n : state.faceNotCentered\n ? verbiage.guidanceMoveToCenterText\n : ''\n\n if (guidanceError) {\n return <SelfieCaptureFallback classNames={classNames.fallback} />\n }\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n <InvisibleCanvas ref={lastPredictionCanvas} />\n\n <FaceCaptureGuideOverlay\n classNames={classNames.guides}\n variant={satisfied ? 'satisfied' : 'unsatisfied'}\n />\n\n {guidanceMessage !== '' && (\n <GuidanceMessageContainer\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n $variant={satisfied ? 'positive' : 'negative'}\n className={classNames.guidanceMessage}\n >\n {guidanceMessage}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && state.faces.length > 0 && (\n <ObjectDetectionDebugOverlayDiv>\n {state.faces.map((face, i) => (\n <SelfieCaptureFaceDebugBox\n key={i}\n face={face}\n scaling={debugScalingDetails}\n color={satisfied ? 'green' : 'red'}\n />\n ))}\n </ObjectDetectionDebugOverlayDiv>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {!state.faceNotCentered ? '✅' : '❌'} Face Centered\n <br />\n {!state.faceTooClose && !state.faceTooFar ? '✅' : '❌'} Face{' '}\n {state.faceTooClose\n ? 'Too Close'\n : state.faceTooFar\n ? 'Too Far'\n : 'Distance Correct'}\n <br />\n {!state.faceLookingAway ? '✅' : '❌'} Face Looking Forward\n <br />\n {state.goodFramesThresholdMet ? '✅' : '❌'} {state.goodFramesCount}{' '}\n Good Frames\n <br />\n {!timedOut ? '✅' : '❌'} Time Remaining:{' '}\n {Math.max(\n 0,\n timeoutDurationMs -\n (new Date().getTime() -\n (timeoutStartedAt ?? new Date()).getTime()),\n )}\n ms\n </DebugStatsPane>\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.exitCaptureBtn}\n />\n </PageContainer>\n )\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { LiveCheckResponse } from '../../contexts/SubmissionContext'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { SelfieCaptureFallback } from '../fallback_flows/SelfieCapture'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\ntype LivenessCheckState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'IN_PROGRESS'\n | 'PASSED'\n | 'FAILED'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n requestState: LivenessCheckState\n requestError: Error | null\n imageUrl: string | null\n faceLive: boolean\n eyeCoveringDetected: boolean\n maskDetected: boolean\n headCoveringDetected: boolean\n phoneDetected: boolean\n timesLivenessCheckFailed: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n requestState: 'CAPTURING',\n requestError: null,\n imageUrl: null,\n faceLive: false,\n eyeCoveringDetected: false,\n maskDetected: false,\n headCoveringDetected: false,\n phoneDetected: false,\n timesLivenessCheckFailed: 0,\n}\n\ntype Action =\n | { type: 'livenessReady'; payload: { frame: ImageData; face: Face } }\n | { type: 'livenessChecking' }\n | {\n type: 'livenessChecked'\n payload: {\n frame?: ImageData\n face?: Face\n imageUrl: string\n response: LiveCheckResponse\n }\n }\n | { type: 'livenessCheckFailed'; payload: { error: Error } }\n\n/** todo: JN - this feels like it should be hoisted up to the wizard because these states of failed and error dovetail into those in the wizard.\n * There may also be some crossing of wires in how error/failed are used.\n */\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'livenessReady': {\n const allowedStates = ['CAPTURING', 'FAILED', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'livenessChecking':\n return { ...state, requestState: 'IN_PROGRESS' }\n\n case 'livenessChecked': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n const faceLive = ['Live Face Detected', 'Approved'].includes(\n resultData.verificationResult,\n )\n const eyeCoveringDetected = resultData.eyeCovering === 'true'\n const maskDetected = resultData.faceMask === 'true'\n const headCoveringDetected = resultData.headCovering === 'true'\n const phoneDetected = resultData.cellPhone === 'true'\n\n const livenessCheckPassed =\n faceLive &&\n !eyeCoveringDetected &&\n !maskDetected &&\n !headCoveringDetected\n const requestState = livenessCheckPassed ? 'PASSED' : 'FAILED'\n\n let timesLivenessCheckFailed = state.timesLivenessCheckFailed\n if (livenessCheckPassed) {\n timesLivenessCheckFailed = 0\n } else {\n timesLivenessCheckFailed += 1\n }\n\n return {\n ...state,\n frame: action.payload.frame ?? null,\n face: action.payload.face ?? null,\n imageUrl: action.payload.imageUrl,\n requestState,\n faceLive,\n eyeCoveringDetected,\n maskDetected,\n headCoveringDetected,\n phoneDetected,\n timesLivenessCheckFailed,\n }\n }\n\n case 'livenessCheckFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type FaceLivenessCaptureClassNames = SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n}\n\nexport type FaceLivenessCaptureColors = SelfieCaptureColors\n\nexport type FaceLivenessCaptureVerbiage = SelfieCaptureVerbiage & {\n guidanceRemoveEyeCoveringsText?: CustomerSuppliedVerbiage\n guidanceRemoveHeadCoveringsText?: CustomerSuppliedVerbiage\n guidanceRemoveMaskText?: CustomerSuppliedVerbiage\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type FaceLivenessCaptureProps = {\n onCapture?: () => void\n onSuccess?: (faceCropImageUrl: string) => void\n onTimeout?: () => void\n onExit?: () => void\n timeoutDurationMs?: number\n silentFallback?: boolean\n classNames?: FaceLivenessCaptureClassNames\n colors?: FaceLivenessCaptureColors\n verbiage?: FaceLivenessCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const FaceLivenessCapture = ({\n onCapture,\n onSuccess,\n onTimeout,\n onExit,\n timeoutDurationMs = 15000,\n silentFallback = false,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode,\n}: FaceLivenessCaptureProps): ReactElement => {\n const { checkLiveness, submissionError } = useContext(SubmissionContext)\n const { error: modelError } = useContext(SelfieGuidanceModelsContext)\n const [state, dispatch] = useReducer(reducer, initialState)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n const theme = useTheme()\n\n const onSelfieCaptured = useCallback(\n (frame: ImageData, face: Face) => {\n onCapture?.()\n dispatch({ type: 'livenessReady', payload: { frame, face } })\n },\n [onCapture],\n )\n\n const { frame, face } = state\n const isReady = state.requestState === 'CAPTURED'\n const isPassed = state.requestState === 'PASSED'\n useEffect(\n function checkLivenessIfPossible() {\n if (!frame || !face || !isReady || submissionError) return\n dispatch({ type: 'livenessChecking' })\n ;(async () => {\n try {\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n const response = await checkLiveness(await dataUrlToBase64(imageUrl))\n\n dispatch({\n type: 'livenessChecked',\n payload: { frame, face, imageUrl, response },\n })\n } catch (e) {\n dispatch({\n type: 'livenessCheckFailed',\n payload: { error: e as Error },\n })\n }\n })()\n },\n [checkLiveness, face, frame, isReady, submissionError],\n )\n\n const onFallbackImageCaptured = useCallback(\n async (imageUrl: string) => {\n dispatch({ type: 'livenessChecking' })\n\n try {\n const imageData = await dataUrlToBase64(imageUrl)\n const response = await checkLiveness(imageData)\n // todo: JN - this feels dirty and is the reason for the todo around line 83 - but is necessary to handle fallback liveness validation\n if (response?.resultData?.verificationResult !== 'Live Face Detected') {\n onTimeout?.()\n }\n dispatch({\n type: 'livenessChecked',\n payload: { imageUrl, response },\n })\n } catch (e) {\n dispatch({\n type: 'livenessCheckFailed',\n payload: { error: e as Error },\n })\n }\n },\n [checkLiveness, onTimeout],\n )\n\n useEffect(\n function callSuccessIfAvailable() {\n if (isPassed && state.imageUrl) onSuccess?.(state.imageUrl)\n },\n [onSuccess, state.imageUrl, isPassed],\n )\n\n useEffect(\n function timeoutOnTooManyLivenessCheckFailures() {\n if (modelError) return\n\n const allowedFailures = 2\n if (state.timesLivenessCheckFailed >= allowedFailures) {\n onTimeout?.()\n }\n },\n [modelError, onTimeout, state.timesLivenessCheckFailed],\n )\n\n useTimeout(\n timeoutDurationMs,\n onTimeout,\n state.requestState === 'PASSED' || !!modelError,\n state.requestState === 'IN_PROGRESS',\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceRemoveEyeCoveringsText:\n 'Please remove your eye coverings (sunglasses, eye patch, etc.)...',\n guidanceRemoveHeadCoveringsText:\n 'Please remove your head coverings (hat, scarf, etc.)...',\n guidanceRemoveMaskText: 'Please remove your mask...',\n progressPreviewText: 'Processing...',\n })\n\n const guidanceMessage = state.eyeCoveringDetected\n ? verbiage.guidanceRemoveEyeCoveringsText\n : state.headCoveringDetected\n ? verbiage.guidanceRemoveHeadCoveringsText\n : state.maskDetected\n ? verbiage.guidanceRemoveMaskText\n : undefined\n\n if (modelError) {\n return (\n <SelfieCaptureFallback\n key={state.timesLivenessCheckFailed}\n onFinished={onFallbackImageCaptured}\n silentFallback={silentFallback}\n invalidSelfie={!!state.timesLivenessCheckFailed}\n guidanceMessage={guidanceMessage}\n />\n )\n }\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={timeoutDurationMs}\n guidanceMessage={guidanceMessage}\n guidanceSatisfied={guidanceMessage ? false : undefined}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n classNames={classNames.imagePreview}\n imageUrl={imageUrl}\n text={verbiage.progressPreviewText ?? ''}\n />\n )}\n </>\n )\n}\n","import React, { ReactElement, useContext, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { SelfieCaptureLoadingOverlayProps } from './SelfieCaptureLoadingOverlay'\nimport { MicrophoneAccessDeniedOverlay } from '../camera/MicrophoneAccessDeniedOverlay'\n\nexport const SelfieCaptureLoadingOverlayLegacy = ({\n onDismissed,\n onUserCancel,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: SelfieCaptureLoadingOverlayProps): ReactElement => {\n const { cameraReady, cameraAccessDenied, microphoneAccessDenied } =\n useContext(CameraStateContext)\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n assets.instructionImageUrl ||= `${DEFAULT_CDN_URL}/Selfie-Image-1.png`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your face',\n removeEyeCoveringsText: 'Remove Sunglasses & Hat',\n avoidExcessiveBacklightingText: 'Avoid Excessive Backlighting',\n continueText: 'Continue',\n cameraInitializingText: 'Camera initializing...',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Models warming up...',\n })\n\n const [dismissed, setDismissed] = useState(false)\n if (dismissed) return <></>\n\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n if (microphoneAccessDenied) {\n return (\n <MicrophoneAccessDeniedOverlay\n assets={assets.microphoneAccessDenied}\n classNames={classNames.microphoneAccessDenied}\n colors={colors.microphoneAccessDenied}\n verbiage={rawVerbiage.microphoneAccessDenied}\n />\n )\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <h3 className={classNames.heading}>{verbiage.headingText}</h3>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <StyledGuidanceMessage>\n {verbiage.removeEyeCoveringsText}\n <br />\n {verbiage.avoidExcessiveBacklightingText}\n </StyledGuidanceMessage>\n\n <OverlayImageContainer className={classNames.imageContainer}>\n <img\n className={classNames.image}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n />\n </OverlayImageContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <LoaderButton\n variant=\"positive\"\n disabled={!cameraReady || !modelsReady}\n finished={cameraReady && modelsReady}\n className={classNames.continueBtn}\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {cameraReady && modelsReady\n ? verbiage.continueText\n : modelsReady\n ? verbiage.cameraInitializingText\n : modelDownloadProgress >= 100\n ? `${verbiage.modelsWarmingUpText}`\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoaderButton>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 12px 24px;\n font-weight: normal;\n line-height: 1.5;\n margin-bottom: -30px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n flex-direction: column;\n padding-top: 25px;\n`\n","import React, { useEffect, useState } from 'react'\nimport { useTheme } from 'styled-components'\n\nexport function SelfieCaptureLoadingGraphic({\n width = 840,\n height = 740,\n className,\n}: {\n width?: number\n height?: number\n className?: string\n}) {\n const [frame, setFrame] = useState(1)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 10)\n }, 750)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.selfieCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n\n return (\n <svg\n width={width}\n height={height}\n className={className}\n viewBox=\"0 0 840 740\"\n fill=\"none\"\n preserveAspectRatio=\"xMidYMax slice\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_428_1188)\">\n <mask\n id=\"mask0_428_1188\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"840\"\n height=\"740\"\n >\n <rect width=\"840\" height=\"740\" fill=\"#D9D9D9\" />\n </mask>\n\n <g mask=\"url(#mask0_428_1188)\">\n <path\n d=\"M503.781 449.497C491.561 503.154 458.442 541.609 419.561 541.609C380.68 541.609 347.492 503.015 335.272 449.358L344.645 412.916L347.492 402.019H491.561L502.253 443.667L503.225 447.415L503.781 449.497Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M574.88 244.97C647.073 163.885 598.921 362.155 558.945 338.928C488.709 298.211 574.88 244.97 574.88 244.97Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M816.983 742.838C779.698 781.432 736.86 814.612 689.786 841.127C617.161 882.012 534.399 906.862 446.153 911.027C437.335 911.513 428.448 911.721 419.491 911.721C374.986 911.721 331.731 906.446 290.281 896.519C232.514 882.706 178.358 859.8 129.271 829.397C89.9033 805.033 53.9382 775.948 22 742.838L31.512 705.355C45.8842 649.061 90.2505 605.33 146.837 591.795L153.085 590.337L222.447 573.747L241.401 569.235C249.386 567.292 257.023 564.585 264.244 561.114C270.285 558.199 276.047 554.797 281.463 550.91C287.295 546.745 292.78 542.025 297.71 536.819C310.971 522.867 320.761 505.653 325.76 486.286L333.119 457.688L335.064 449.983L335.202 449.358L344.645 412.916L347.422 402.019H491.491L502.253 443.667L503.225 447.415L503.78 449.497V449.983L505.863 457.757L513.223 486.286C520.097 512.802 535.996 535.5 557.589 550.91C569.393 559.448 582.932 565.765 597.581 569.235L615.078 573.4L692.146 591.795C748.732 605.33 793.099 649.061 807.471 705.355L816.983 742.838Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M503.781 449.497C491.561 503.154 458.442 541.609 419.561 541.609C380.68 541.609 347.492 503.015 335.272 449.358L344.645 412.916L347.492 402.019H491.561L502.253 443.667L503.225 447.415L503.781 449.497Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M264.123 244.97C191.93 163.885 240.082 362.155 280.058 338.928C350.294 298.211 264.123 244.97 264.123 244.97Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M586.473 187.324C586.473 193.432 586.126 199.402 585.432 205.371C584.876 210.785 582.446 233.9 578.141 263.331C575.781 279.713 572.726 297.969 569.115 316.294C569.115 316.502 569.115 316.78 568.976 316.988C560.159 361.621 547.731 406.045 531.484 422.219C513.154 440.544 498.435 457.203 481.632 469.211C464.83 481.289 446.014 488.786 419.631 488.786C393.247 488.786 374.431 481.289 357.629 469.211C340.896 457.203 326.107 440.544 307.778 422.219C291.531 405.976 279.103 361.482 270.216 316.918C270.216 316.918 270.216 316.71 270.216 316.641C269.105 310.879 268.063 305.118 267.022 299.426C266.605 297.066 266.189 294.706 265.772 292.346C264.036 282.351 262.509 272.563 261.12 263.401C256.121 229.596 253.691 204.122 253.691 204.122C253.136 198.638 252.858 193.016 252.858 187.324C252.858 185.866 252.858 184.408 252.858 182.951C253.205 169.832 255.01 157.06 258.274 144.843C258.412 144.287 258.551 143.732 258.69 143.177C277.228 75.4294 337.425 24.8271 410.049 20.8011C413.243 20.5928 416.368 20.5234 419.631 20.5234C465.733 20.5234 507.461 39.1956 537.663 69.3904C563.769 95.4205 581.266 130.127 585.501 168.79C586.195 174.899 586.542 181.077 586.542 187.324H586.473Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M445.867 337.327C445.867 348.849 434.133 358.151 419.622 358.151C405.111 358.151 393.447 348.849 393.447 337.327C393.447 335.939 393.586 334.55 394.002 333.301C396.293 342.88 406.916 350.099 419.622 350.099C432.328 350.099 443.02 342.88 445.312 333.301C445.728 334.62 445.867 335.939 445.867 337.327Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M817.053 743.187C716.586 847.238 575.642 912 419.561 912C263.481 912 122.467 847.238 22.0698 743.118L31.5818 705.704C45.954 649.34 90.3203 605.61 146.906 592.074L222.655 574.027L241.471 569.515C249.942 567.502 258.135 564.517 265.772 560.699C304.237 601.653 358.879 627.267 419.561 627.267C480.244 627.267 534.886 601.653 573.351 560.699C580.988 564.448 589.111 567.502 597.651 569.515L614.106 573.471L692.216 592.074C748.802 605.61 793.168 649.34 807.471 705.704L817.053 743.187Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M614.106 573.471C597.165 594.018 534.886 659.058 419.561 663.639C286.671 668.984 226.266 579.441 222.655 574.027L241.471 569.515C249.942 567.502 258.134 564.517 265.772 560.699C304.236 601.653 358.879 627.267 419.561 627.267C480.244 627.267 534.886 601.653 573.35 560.699C580.988 564.448 589.111 567.502 597.651 569.515L614.106 573.471Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M249.898 196.144C249.898 249.777 270.317 315.623 270.317 315.623C270.317 315.623 266.862 205.572 314.892 164.108C347.514 135.946 374.019 167.565 417.115 167.565C456.137 167.565 492.558 136.481 525.436 164.108C578.852 208.994 568.738 315.623 568.738 315.623C568.738 315.623 589.157 250.557 589.157 196.144C589.157 76.4319 542.638 20 417.115 20C302.8 20 249.898 75.8365 249.898 196.144Z\"\n fill=\"#525252\"\n />\n </g>\n\n {frame >= 8 ? (\n <>\n <path\n d=\"M565.5 295C565.5 350.583 549.016 400.803 522.488 437.067C495.958 473.332 459.517 495.5 419.5 495.5C379.483 495.5 343.042 473.332 316.512 437.067C289.984 400.803 273.5 350.583 273.5 295C273.5 239.417 289.984 189.197 316.512 152.933C343.042 116.668 379.483 94.5 419.5 94.5C459.517 94.5 495.958 116.668 522.488 152.933C549.016 189.197 565.5 239.417 565.5 295Z\"\n stroke={accentColor}\n strokeWidth=\"5\"\n />\n <circle cx=\"518.5\" cy=\"438.5\" r=\"25.5\" fill={accentColor} />\n <path\n d=\"M504 440.5L512 448L531 427\"\n stroke=\"white\"\n strokeWidth=\"5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n ) : (\n <>\n {frame > 2 && (\n <>\n {frame > 3 && (\n <>\n {frame > 4 && (\n <>\n {frame > 5 && (\n <>\n <path\n d=\"M298.5 182.5L419 164.5L540 182\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <circle cx=\"419\" cy=\"165\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M565.5 295C565.5 350.583 549.016 400.803 522.488 437.067C495.958 473.332 459.517 495.5 419.5 495.5C379.483 495.5 343.042 473.332 316.512 437.067C289.984 400.803 273.5 350.583 273.5 295C273.5 239.417 289.984 189.197 316.512 152.933C343.042 116.668 379.483 94.5 419.5 94.5C459.517 94.5 495.958 116.668 522.488 152.933C549.016 189.197 565.5 239.417 565.5 295Z\"\n stroke=\"white\"\n strokeOpacity={\n frame > 7 ? 0.8 : frame > 5 ? 0.3 : 0.1\n }\n strokeWidth=\"5\"\n />\n <path\n d=\"M299.939 262.805L419 478.5L538.5 261.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M298.5 182.5L418.871 230.054L540 182\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M298.5 182.5L299.939 262.805\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M540.001 182L538.501 261.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n\n <circle cx=\"299.914\" cy=\"182\" r=\"7\" fill=\"white\" />\n <circle cx=\"540\" cy=\"182\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M418.828 230L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M300 263.001L419 342.501\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M538.5 261.5L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M301.5 409L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M536.5 410L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M300 263L419 230\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M538.5 261.5L419 230\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n\n <circle cx=\"419\" cy=\"229.971\" r=\"7\" fill=\"white\" />\n <circle cx=\"419\" cy=\"342.4\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M538.5 261.5L536.5 410\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 3 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M419 478.5L536.5 410\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 3 && frame < 7 ? 0.3 : 1}\n />\n <circle cx=\"537\" cy=\"263\" r=\"7\" fill=\"white\" />\n <circle cx=\"537\" cy=\"409\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n {frame > 1 && (\n <>\n <path\n d=\"M301.501 409L300.001 263\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 2 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M301.501 409L419.001 478.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 2 && frame < 7 ? 0.3 : 1}\n />\n <circle cx=\"419\" cy=\"477.576\" r=\"7\" fill=\"white\" />\n <circle cx=\"301.914\" cy=\"263\" r=\"7\" fill=\"white\" />\n <circle cx=\"301.444\" cy=\"409\" r=\"7\" fill=\"white\" />\n </>\n )}\n </>\n )}\n </g>\n <defs>\n <clipPath id=\"clip0_428_1188\">\n <rect width=\"840\" height=\"740\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n )\n}\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { OverlayContainer, OverlayImageContainer } from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { SelfieCaptureLoadingOverlayProps } from './SelfieCaptureLoadingOverlay'\nimport { SelfieCaptureLoadingGraphic } from './SelfieCaptureLoadingGraphic'\nimport { MicrophoneAccessDeniedOverlay } from '../camera/MicrophoneAccessDeniedOverlay'\n\nconst legacyInstructionImageUrl = `${DEFAULT_CDN_URL}/Selfie-Image-1.png`\n\nexport const SelfieCaptureLoadingOverlayDefault = ({\n onDismissed,\n onUserCancel,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: SelfieCaptureLoadingOverlayProps): ReactElement => {\n const { cameraReady, cameraAccessDenied, microphoneAccessDenied } =\n useContext(CameraStateContext)\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your face',\n removeEyeCoveringsText: 'Remove Sunglasses & Hat',\n avoidExcessiveBacklightingText: 'Avoid Excessive Backlighting',\n continueText: \"Let's Go!\",\n cameraInitializingText: 'Accessing camera...',\n cameraInitializedText: 'Camera ready',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Loading guided capture experience...',\n modelsReadyText: 'Guided capture experience ready',\n })\n\n const [headingTextIndex, setHeadingTextIndex] = useState(0)\n const headingText = [\n verbiage.headingText,\n verbiage.removeEyeCoveringsText,\n verbiage.avoidExcessiveBacklightingText,\n ][headingTextIndex]\n\n useEffect(() => {\n setInterval(() => {\n setHeadingTextIndex((n) => (n + 1) % 3)\n }, 3000)\n }, [])\n\n const [dismissed, setDismissed] = useState(false)\n if (dismissed) return <></>\n\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n if (microphoneAccessDenied) {\n return (\n <MicrophoneAccessDeniedOverlay\n assets={assets.microphoneAccessDenied}\n classNames={classNames.microphoneAccessDenied}\n colors={colors.microphoneAccessDenied}\n verbiage={rawVerbiage.microphoneAccessDenied}\n />\n )\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <OverlayHeader className={classNames.headingContainer}>\n <StyledGuidanceMessage className={classNames.heading}>\n {headingText}\n </StyledGuidanceMessage>\n </OverlayHeader>\n\n <StyledOverlayImageContainer className={classNames.imageContainer}>\n {assets?.instructionImageUrl &&\n assets.instructionImageUrl !== legacyInstructionImageUrl ? (\n <CustomLoadingGraphic\n className={classNames.image}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n />\n ) : (\n <SelfieCaptureLoadingGraphic className={classNames.image} />\n )}\n </StyledOverlayImageContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <ProgressContainer className={classNames.progressContainer}>\n <ProgressBarBackground className={classNames.progressBackground} />\n <ProgressBar\n $progress={modelDownloadProgress}\n className={classNames.progressBar}\n >\n <ProgressIndicator className={classNames.progressIndicator} />\n </ProgressBar>\n </ProgressContainer>\n\n <LoadingListContainer className={classNames.loadingListContainer}>\n <LoadingList className={classNames.loadingList}>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n cameraReady ? 'done' : 'running'\n }`}\n >\n {cameraReady\n ? verbiage.cameraInitializedText\n : verbiage.cameraInitializingText}\n </LoadingListItem>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n modelsReady ? 'done' : 'running'\n }`}\n >\n {modelsReady\n ? verbiage.modelsReadyText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoadingListItem>\n </LoadingList>\n </LoadingListContainer>\n\n <ContinueButtonContainer className={classNames.continueBtnContainer}>\n {modelsReady && cameraReady && (\n <ContinueButton\n finished\n className={classNames.continueBtn}\n variant=\"positive\"\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {verbiage.continueText}\n </ContinueButton>\n )}\n </ContinueButtonContainer>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst OverlayInner = styled.div`\n height: 100dvh;\n display: flex;\n flex-direction: column;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.backgroundColor ?? '#ecedf3'};\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.textColor ?? 'black'};\n`\n\nconst OverlayHeader = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n padding-bottom: 0;\n`\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 16px 24px;\n margin-top: 16px;\n font-size: 18px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n display: flex;\n flex-direction: row;\n padding: 15px 25px;\n height: 100px;\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarTextColor ??\n 'white'};\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100dvw;\n box-sizing: border-box;\n`\n\nconst StyledOverlayImageContainer = styled(OverlayImageContainer)`\n padding: 0;\n\n & > svg {\n height: 100%;\n }\n`\n\nconst LoadingListContainer = styled.div`\n display: flex;\n position: relative;\n z-index: 2;\n`\n\nconst LoadingList = styled.ul`\n display: block;\n margin: auto;\n list-style: none;\n padding: 0;\n`\n\nconst LoadingListItem = styled.li`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n padding: 2px 1.25rem 2px 0;\n line-height: 1rem;\n\n &::before {\n content: '';\n display: inline-block;\n height: 1rem;\n min-width: 1rem;\n vertical-align: middle;\n background-size: cover;\n background-repeat: no-repeat;\n margin: auto 0.5rem auto 0;\n }\n\n &.done::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzg1KSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyNEMxOC42Mjc0IDI0IDI0IDE4LjYyNzQgMjQgMTJDMjQgNS4zNzI1OCAxOC42Mjc0IDAgMTIgMEM1LjM3MjU4IDAgMCA1LjM3MjU4IDAgMTJDMCAxOC42Mjc0IDUuMzcyNTggMjQgMTIgMjRaTTE5LjU2NDMgOC4yNzg1MkMxOS45NTQ5IDcuODg3OTkgMTkuOTU0OSA3LjI1NDgzIDE5LjU2NDMgNi44NjQzQzE5LjE3MzggNi40NzM3OCAxOC41NDA2IDYuNDczNzggMTguMTUwMSA2Ljg2NDNMOS40Mjg2NiAxNS41ODU4TDUuODUwMDUgMTIuMDA3MkM1LjQ1OTUzIDExLjYxNjYgNC44MjYzNiAxMS42MTY2IDQuNDM1ODQgMTIuMDA3MkM0LjA0NTMxIDEyLjM5NzcgNC4wNDUzMSAxMy4wMzA5IDQuNDM1ODQgMTMuNDIxNEw4LjcyMTU1IDE3LjcwNzFDOS4xMTIwOCAxOC4wOTc2IDkuNzQ1MjQgMTguMDk3NiAxMC4xMzU4IDE3LjcwNzFMMTkuNTY0MyA4LjI3ODUyWiIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF80OV8zODUiPjxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=');\n }\n\n &.running::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzcwKSI+PG1hc2sgaWQ9InBhdGgtMS1pbnNpZGUtMV80OV8zNzAiIGZpbGw9IndoaXRlIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMuNTE0NzIgMjAuNDg1NUM4LjIwMTAxIDI1LjE3MTggMTUuNzk5IDI1LjE3MTggMjAuNDg1MyAyMC40ODU1QzI1LjE3MTYgMTUuNzk5MiAyNS4xNzE2IDguMjAxMTkgMjAuNDg1MyAzLjUxNDlDMTUuNzk5IC0xLjE3MTM5IDguMjAxMDEgLTEuMTcxMzkgMy41MTQ3MiAzLjUxNDlDLTEuMTcxNTcgOC4yMDExOSAtMS4xNzE1NyAxNS43OTkyIDMuNTE0NzIgMjAuNDg1NVoiLz48L21hc2s+PHBhdGggZD0iTTYuMzk4MTQgMTEuNDU5QzUuODQ1ODYgMTEuNDU5IDUuMzk4MTQgMTEuOTA2NyA1LjM5ODE0IDEyLjQ1OUM1LjM5ODE0IDEzLjAxMTIgNS44NDU4NiAxMy40NTkgNi4zOTgxNCAxMy40NTlWMTEuNDU5Wk0xNy42MDE5IDEzLjQ1OUMxOC4xNTQxIDEzLjQ1OSAxOC42MDE5IDEzLjAxMTIgMTguNjAxOSAxMi40NTlDMTguNjAxOSAxMS45MDY3IDE4LjE1NDEgMTEuNDU5IDE3LjYwMTkgMTEuNDU5VjEzLjQ1OVpNNi4zOTgxNCAxMy40NTlIMTcuNjAxOVYxMS40NTlINi4zOTgxNFYxMy40NTlaTTMuNTE0NzIgMjAuNDg1NUw0LjkyODkzIDE5LjA3MTNMNC45Mjg5MyAxOS4wNzEzTDMuNTE0NzIgMjAuNDg1NVpNMjAuNDg1MyAzLjUxNDlMMTkuMDcxMSA0LjkyOTEyTDE5LjA3MTEgNC45MjkxMkwyMC40ODUzIDMuNTE0OVpNMy41MTQ3MiAzLjUxNDlMNC45Mjg5MyA0LjkyOTEyTDQuOTI4OTMgNC45MjkxMkwzLjUxNDcyIDMuNTE0OVpNMTkuMDcxMSAxOS4wNzEzQzE1LjE2NTggMjIuOTc2NSA4LjgzNDE3IDIyLjk3NjUgNC45Mjg5MyAxOS4wNzEzTDIuMTAwNTEgMjEuODk5N0M3LjU2Nzg0IDI3LjM2NyAxNi40MzIyIDI3LjM2NyAyMS44OTk1IDIxLjg5OTdMMTkuMDcxMSAxOS4wNzEzWk0xOS4wNzExIDQuOTI5MTJDMjIuOTc2MyA4LjgzNDM2IDIyLjk3NjMgMTUuMTY2IDE5LjA3MTEgMTkuMDcxM0wyMS44OTk1IDIxLjg5OTdDMjcuMzY2OCAxNi40MzIzIDI3LjM2NjggNy41NjgwMyAyMS44OTk1IDIuMTAwNjlMMTkuMDcxMSA0LjkyOTEyWk00LjkyODkzIDQuOTI5MTJDOC44MzQxNyAxLjAyMzg3IDE1LjE2NTggMS4wMjM4NyAxOS4wNzExIDQuOTI5MTJMMjEuODk5NSAyLjEwMDY5QzE2LjQzMjIgLTMuMzY2NjUgNy41Njc4NCAtMy4zNjY2NSAyLjEwMDUxIDIuMTAwNjlMNC45Mjg5MyA0LjkyOTEyWk00LjkyODkzIDE5LjA3MTNDMS4wMjM2OSAxNS4xNjYgMS4wMjM2OSA4LjgzNDM2IDQuOTI4OTMgNC45MjkxMkwyLjEwMDUxIDIuMTAwNjlDLTMuMzY2ODMgNy41NjgwMyAtMy4zNjY4MyAxNi40MzIzIDIuMTAwNTEgMjEuODk5N0w0LjkyODkzIDE5LjA3MTNaIiBmaWxsPSJ3aGl0ZSIgbWFzaz0idXJsKCNwYXRoLTEtaW5zaWRlLTFfNDlfMzcwKSIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImNsaXAwXzQ5XzM3MCI+PHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==');\n }\n`\n\nconst ProgressContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n`\n\nconst ProgressBarBackground = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarBackgroundColor ??\n 'var(--idm-color-positive-600)'};\n opacity: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarBackgroundOpacity ??\n 0.75};\n`\n\nconst ProgressBar = styled.span<{ $progress: number }>`\n display: block;\n width: ${(props) => props.$progress}%;\n height: 100%;\n`\n\nconst ProgressIndicator = styled.span`\n display: block;\n height: 100%;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarIndicatorColor ??\n 'var(--idm-color-positive-600)'};\n animation: progressBar 3s ease-in-out;\n animation-fill-mode: both;\n\n @keyframes progressBar {\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n }\n`\n\nconst CustomLoadingGraphic = styled.img``\n\nconst ContinueButtonContainer = styled.div`\n display: flex;\n`\n\nconst ContinueButton = styled(LoaderButton)`\n margin: auto;\n white-space: nowrap;\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.continueBtnBorder\n ? `border: ${props.theme?.selfieCapture?.loadingOverlay?.continueBtnBorder};`\n : ''}\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {\n FaceLivenessCapture,\n FaceLivenessCaptureClassNames,\n FaceLivenessCaptureColors,\n FaceLivenessCaptureVerbiage,\n} from './FaceLivenessCapture'\nimport {\n FaceLivenessSuccess,\n FaceLivenessSuccessClassNames,\n FaceLivenessSuccessColors,\n FaceLivenessSuccessVerbiage,\n} from './FaceLivenessSuccess'\nimport {\n FaceLivenessFailure,\n FaceLivenessFailureAssets,\n FaceLivenessFailureClassNames,\n FaceLivenessFailureColors,\n FaceLivenessFailureVerbiage,\n} from './FaceLivenessFailure'\nimport {\n LivenessCheckRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport {\n SelfieCaptureLoadingOverlayMode,\n SelfieCaptureLoadingOverlay,\n SelfieCaptureLoadingOverlayAssets,\n SelfieCaptureLoadingOverlayClassNames,\n SelfieCaptureLoadingOverlayColors,\n SelfieCaptureLoadingOverlayVerbiage,\n} from '../selfie_capture/SelfieCaptureLoadingOverlay'\nimport { PageContainer } from '../common/Page'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\n\ntype CaptureState = 'LOADING' | 'CAPTURING' | 'SUCCESS' | 'FAILED'\n\nexport type FaceLivenessAssets = {\n loadingOverlay?: SelfieCaptureLoadingOverlayAssets\n failure?: FaceLivenessFailureAssets\n}\n\nexport type FaceLivenessClassNames = {\n loadingOverlay?: SelfieCaptureLoadingOverlayClassNames\n capture?: FaceLivenessCaptureClassNames\n success?: FaceLivenessSuccessClassNames\n failure?: FaceLivenessFailureClassNames\n}\n\nexport type FaceLivenessColors = FaceLivenessCaptureColors & {\n loadingOverlay?: SelfieCaptureLoadingOverlayColors\n success?: FaceLivenessSuccessColors\n failure?: FaceLivenessFailureColors\n}\n\nexport type FaceLivenessVerbiage = FaceLivenessCaptureVerbiage & {\n loadingOverlay?: SelfieCaptureLoadingOverlayVerbiage\n success?: FaceLivenessSuccessVerbiage\n failure?: FaceLivenessFailureVerbiage\n}\n\nexport type FaceLivenessWizardProps = {\n onSuccess?: (resp: SubmissionResponse, req: LivenessCheckRequest) => void\n onComplete?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onTimeout?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onExitCapture?: () => void\n onExitAfterFailure?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: SelfieCaptureLoadingOverlayMode\n timeoutDurationMs?: number\n modelLoadTimeoutMs?: number\n maxRetries?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n renderCameraFeed?: boolean\n releaseCameraAccessOnExit?: boolean\n silentFallback?: boolean\n\n assets?: FaceLivenessAssets\n classNames?: FaceLivenessClassNames\n colors?: FaceLivenessColors\n verbiage?: FaceLivenessVerbiage\n debugMode?: boolean\n}\n\nexport const FaceLivenessWizard = ({\n onComplete,\n onSuccess,\n onTimeout,\n onExitCapture,\n onExitAfterFailure,\n onUserCancel,\n loadingOverlayMode = 'default',\n timeoutDurationMs = 15000,\n maxRetries = 2,\n skipSuccessScreen = false,\n renderCameraFeed = true,\n releaseCameraAccessOnExit = true,\n silentFallback = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: FaceLivenessWizardProps): ReactElement => {\n const {\n submissionResponse,\n livenessCheckRequest,\n setSelfieImage,\n logSelfieCaptureAttempt,\n } = useContext(SubmissionContext)\n const { cameraAccessDenied, releaseCameraAccess } =\n useContext(CameraStateContext)\n const [faceCropImageUrl, setFaceCropImageUrl] = useState('')\n const [retryCount, setRetryCount] = useState(0)\n const [captureState, setCaptureState] = useState<CaptureState>('LOADING')\n const captureStartedAt = useRef<Date>()\n const captureEndedAt = useRef<Date>()\n const operationStartedAt = useRef<Date>()\n const { start, stop } = useContext(SelfieGuidanceModelsContext)\n\n useEffect(() => {\n operationStartedAt.current = new Date()\n }, [])\n\n useEffect(() => {\n if (captureState !== 'CAPTURING') return\n captureStartedAt.current = new Date()\n start()\n return () => {\n stop()\n }\n }, [captureState, start, stop])\n\n const onCapture = useCallback(() => {\n captureEndedAt.current = new Date()\n }, [])\n\n const logCaptureMetadata = useCallback(() => {\n logSelfieCaptureAttempt({\n autoCapture: 'Y',\n captureTime:\n (captureEndedAt.current ?? new Date()).getTime() -\n (captureStartedAt.current ?? new Date()).getTime(),\n operationTime:\n new Date().getTime() -\n (operationStartedAt.current ?? new Date()).getTime(),\n })\n\n operationStartedAt.current = new Date()\n }, [logSelfieCaptureAttempt])\n\n const onSuccessCallback = useCallback(\n async (faceCropImageUrl: string) => {\n if (!livenessCheckRequest || !submissionResponse) return\n setCaptureState('SUCCESS')\n setFaceCropImageUrl(faceCropImageUrl)\n setSelfieImage(await dataUrlToBase64(faceCropImageUrl))\n onSuccess?.(submissionResponse, livenessCheckRequest)\n },\n [onSuccess, setSelfieImage, livenessCheckRequest, submissionResponse],\n )\n\n // todo: JN - how this is being used, it would make sense to rename the prop as well, but that would be a breaking change - discuss\n const onFailureOrTimeout = useCallback(() => {\n setCaptureState('FAILED')\n onTimeout?.(submissionResponse, livenessCheckRequest)\n }, [onTimeout, livenessCheckRequest, submissionResponse])\n\n const [attempt, setAttempt] = useState(0)\n const onExitCallback = useCallback(() => {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n onExitCapture?.()\n }, [onExitCapture])\n\n const onDoneCallback = useCallback(() => {\n logCaptureMetadata()\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onComplete?.(submissionResponse, livenessCheckRequest)\n }, 0)\n }, [\n logCaptureMetadata,\n onComplete,\n releaseCameraAccess,\n releaseCameraAccessOnExit,\n livenessCheckRequest,\n submissionResponse,\n ])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n captureState === 'SUCCESS',\n onDoneCallback,\n )\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n }\n }, [cameraAccessDenied])\n\n return (\n <>\n <PageContainer className={`flex ${classNames.capture?.container ?? ''}`}>\n {renderCameraFeed && (\n <CameraVideoTag className={classNames.capture?.cameraFeed} />\n )}\n\n {captureState !== 'LOADING' &&\n (() => {\n switch (captureState) {\n case 'CAPTURING':\n return (\n <FaceLivenessCapture\n key={`capture${attempt}`}\n onCapture={onCapture}\n onSuccess={onSuccessCallback}\n onTimeout={onFailureOrTimeout}\n onExit={onExitCallback}\n timeoutDurationMs={timeoutDurationMs}\n silentFallback={silentFallback}\n classNames={classNames.capture}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n )\n\n case 'SUCCESS':\n if (!showSuccessScreen) return null\n return (\n <FaceLivenessSuccess\n key=\"success\"\n imageUrl={faceCropImageUrl}\n classNames={classNames.success}\n colors={colors.success}\n verbiage={verbiage.success}\n onDoneClick={onDoneCallback}\n onRetryClick={() => {\n logCaptureMetadata()\n setCaptureState('CAPTURING')\n }}\n />\n )\n\n case 'FAILED':\n return (\n <FaceLivenessFailure\n key=\"failure\"\n assets={assets.failure}\n classNames={classNames.failure}\n colors={colors.failure}\n verbiage={verbiage.failure}\n canRetry={maxRetries > -1 && retryCount < maxRetries}\n onRetryClick={() => {\n logCaptureMetadata()\n setRetryCount((c) => c + 1)\n setCaptureState('CAPTURING')\n }}\n onExitClick={() => {\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onExitAfterFailure?.(\n submissionResponse,\n livenessCheckRequest,\n )\n }, 0)\n }}\n />\n )\n\n default:\n return null\n }\n })()}\n </PageContainer>\n\n <SelfieCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onUserCancel={onUserCancel}\n onDismissed={() => {\n setCaptureState('CAPTURING')\n }}\n />\n </>\n )\n}\n","import React, { ReactElement, ReactNode, useCallback, useState } from 'react'\nimport {\n GuideOrientationContext,\n GuideOrientationState,\n} from '../contexts/GuideOrientationContext'\nimport useResizeObserver from 'use-resize-observer'\n\nexport const GuideOrientationProvider = ({\n children,\n}: {\n children: ReactNode\n}): ReactElement => {\n const setDimensions = useState({ width: 1, height: 1 })[1]\n const [imageAspectRatio, setImageAspectRatio] = useState(1)\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const wrapperAspectRatio = wrapperWidth / wrapperHeight\n\n const onImageLoaded = useCallback((e: React.SyntheticEvent) => {\n const img = e.target as HTMLImageElement\n setImageAspectRatio(img.naturalWidth / img.naturalHeight)\n }, [])\n\n const orientation = 'landscape' //width > height ? 'landscape' : 'portrait'\n const value: GuideOrientationState = {\n orientation,\n wrapperWidth,\n wrapperHeight,\n wrapperAspectRatio,\n imageAspectRatio,\n setDimensions,\n wrapperRef,\n onImageLoaded,\n }\n\n return (\n <GuideOrientationContext.Provider value={value}>\n {children}\n </GuideOrientationContext.Provider>\n )\n}\n","import React, { ReactElement, useContext, useMemo, useState } from 'react'\nimport { SubmissionContext } from './SubmissionProvider'\n\nexport const SubmissionSuccess = (): ReactElement => {\n const { submissionRequest, submissionResponse } =\n useContext(SubmissionContext)\n const [showRequestBody, setShowRequestBody] = useState(false)\n const [truncateImages, setTruncateImages] = useState(true)\n\n const requestBodyDisplay = useMemo(() => {\n const body = JSON.parse(JSON.stringify(submissionRequest))\n if (truncateImages) {\n if (body?.customerData?.idData?.idImageFront)\n body.customerData.idData.idImageFront = truncate(\n body.customerData.idData.idImageFront,\n 200,\n )\n if (body?.customerData?.idData?.idImageBack)\n body.customerData.idData.idImageBack = truncate(\n body.customerData.idData.idImageBack,\n 200,\n )\n if (body?.customerData?.biometricData?.selfie)\n body.customerData.biometricData.selfie = truncate(\n body.customerData.biometricData.selfie,\n 200,\n )\n }\n return JSON.stringify(body, null, 2)\n }, [submissionRequest, truncateImages])\n\n return (\n <>\n <h3>Submission completed!</h3>\n\n <button\n onClick={() => {\n setShowRequestBody(!showRequestBody)\n }}\n >\n {showRequestBody ? 'Hide' : 'Show'} request body\n </button>\n\n {showRequestBody && (\n <>\n <button\n style={{ marginLeft: 8 }}\n onClick={() => {\n setTruncateImages(!truncateImages)\n }}\n >\n {truncateImages ? 'Display full images' : 'Truncate images'}\n </button>\n\n <h5>Request Body</h5>\n <pre>{requestBodyDisplay}</pre>\n </>\n )}\n\n <h5>Response Body</h5>\n <pre>{JSON.stringify(submissionResponse, null, 2)}</pre>\n </>\n )\n}\n\nfunction truncate(str: string, max_chars: number): string {\n let truncated = str.split('').splice(0, max_chars).join('')\n if (truncated.length < str.length) truncated += '...'\n return truncated\n}\n","import React, { ReactElement, useRef, useState } from 'react'\nimport {\n contentDispositionFromDataUrl,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { ButtonsRow } from '../common/ButtonsRow'\n\nexport type AdditionalDocument = {\n name: string\n description?: string\n skip?: () => Promise<boolean>\n}\n\nexport type UploadedDocument = {\n documentName: string\n additionalDocument: string | Record<string, string>\n}\n\nexport type AdditionalDocumentCaptureClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n buttonsRow?: string\n captureBtn?: string\n nextBtn?: string\n}\n\nexport type AdditionalDocumentCaptureVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n nextBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type AdditionalDocumentCaptureProps = {\n document: AdditionalDocument\n onComplete?: (uploadedDocument: UploadedDocument) => void\n classNames?: AdditionalDocumentCaptureClassNames\n verbiage?: AdditionalDocumentCaptureVerbiage\n}\n\nexport const AdditionalDocumentCapture = ({\n document,\n onComplete,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: AdditionalDocumentCaptureProps): ReactElement => {\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [file, setFile] = useState<File | null>(null)\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Additional document capture',\n captureBtnText: 'Capture',\n nextBtnText: 'Next',\n })\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0]\n if (file) setFile(file)\n }\n\n function onNextClicked() {\n if (!file) return\n\n const fileReader = new FileReader()\n fileReader.onloadend = () => {\n if (!fileReader.result) return\n const fileContent = fileReader.result.toString()\n onComplete?.({\n documentName: document.name,\n additionalDocument: {\n name: file.name,\n fileContent: dataUrlToBase64Sync(fileContent),\n type: contentDispositionFromDataUrl(fileContent),\n fileUploadType: 'Y',\n isImageControlData: 'Y',\n fieldId: '',\n },\n })\n }\n fileReader.readAsDataURL(file)\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <Inner className={classNames.inner}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}: {document.name}\n </Heading>\n\n {document.description && (\n <Description className={classNames.description}>\n {document.description}\n </Description>\n )}\n\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*,.pdf\"\n onChange={onFileSelected}\n hidden\n />\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n {file ? (\n <LoaderButton\n variant=\"positive\"\n className={classNames.nextBtn}\n disabled={!file}\n finished\n onClick={onNextClicked}\n >\n {verbiage.nextBtnText}\n </LoaderButton>\n ) : (\n <LoaderButton\n variant=\"primary\"\n className={classNames.captureBtn}\n finished\n onClick={() => {\n fileInput.current?.click()\n }}\n >\n {verbiage.captureBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </Inner>\n </OverlayContainer>\n )\n}\n\nconst Inner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, { ReactElement, useEffect, useState } from 'react'\nimport {\n AdditionalDocument,\n AdditionalDocumentCapture,\n AdditionalDocumentCaptureClassNames,\n AdditionalDocumentCaptureVerbiage,\n UploadedDocument,\n} from './AdditionalDocumentCapture'\n\nexport type AdditionalDocumentCaptureWizardClassNames =\n AdditionalDocumentCaptureClassNames\n\nexport type AdditionalDocumentCaptureWizardVerbiage =\n AdditionalDocumentCaptureVerbiage\n\nexport type AdditionalDocumentCaptureWizardProps = {\n documents: AdditionalDocument[]\n onComplete?: (uploadedDocuments: UploadedDocument[]) => void\n classNames?: AdditionalDocumentCaptureWizardClassNames\n verbiage?: AdditionalDocumentCaptureWizardVerbiage\n}\n\nexport const AdditionalDocumentCaptureWizard = ({\n documents,\n onComplete,\n classNames = {},\n verbiage = {},\n}: AdditionalDocumentCaptureWizardProps): ReactElement => {\n const [uploadedDocuments, setUploadedDocuments] = useState<\n (UploadedDocument | null)[]\n >([])\n const documentIndex = uploadedDocuments.length\n const currentDocument = documents[documentIndex]\n const isComplete = documentIndex >= documents.length\n\n useEffect(() => {\n if (!currentDocument?.skip) return\n ;(async () => {\n if (await currentDocument.skip?.()) {\n setUploadedDocuments((f) => [...f, null])\n }\n })()\n }, [currentDocument])\n\n useEffect(() => {\n if (isComplete) {\n onComplete?.(uploadedDocuments.filter((d) => !!d) as UploadedDocument[])\n }\n }, [isComplete, onComplete, uploadedDocuments])\n\n if (isComplete) return <>Thanks, your documents have been received.</>\n\n return (\n <AdditionalDocumentCapture\n key={documentIndex}\n document={currentDocument}\n classNames={classNames}\n verbiage={verbiage}\n onComplete={(data) => {\n setUploadedDocuments((f) => [...f, data])\n }}\n />\n )\n}\n","import ReactSignatureCanvas from 'react-signature-canvas'\nimport { dataUrlToBase64Sync } from '../../lib/utils/dataUrlToBase64'\n\nexport type SignatureData = {\n clickX_simple: number[][]\n clickY_simple: number[][]\n time_simple: string[][]\n pressure: string\n fileContent: string\n}\n\nexport function signatureDataToIdmissionFormat(\n signatureCanvas: ReactSignatureCanvas,\n): SignatureData {\n const dataURL = signatureCanvas.toDataURL() ?? null\n\n const signatureData: SignatureData = {\n clickX_simple: [],\n clickY_simple: [],\n time_simple: [],\n pressure: '',\n fileContent: dataURL ? dataUrlToBase64Sync(dataURL) : '',\n }\n\n signatureCanvas.toData().forEach((stroke) => {\n const xs: number[] = []\n const ys: number[] = []\n const times: string[] = []\n stroke.forEach((d) => {\n xs.push(d.x)\n ys.push(d.y)\n times.push(new Date(d.time).toString())\n })\n signatureData.clickX_simple.push(xs)\n signatureData.clickY_simple.push(ys)\n signatureData.time_simple.push(times)\n })\n\n return signatureData\n}\n","import styled from 'styled-components'\nimport { ButtonsRow } from './ButtonsRow'\n\nexport const SignaturePaperBacking = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n ${(props) =>\n props.theme.signatureCapture?.background\n ? `background: ${props.theme.signatureCapture?.background};`\n : ``}\n ${(props) =>\n props.theme.signatureCapture?.backgroundSize\n ? `background-size: ${props.theme.signatureCapture?.backgroundSize};`\n : ``}\n ${(props) =>\n props.theme.signatureCapture?.backgroundPosition\n ? `background-position: ${props.theme.signatureCapture?.backgroundPosition};`\n : ``}\n`\n\nexport const SignatureCanvasContainer = styled.div`\n position: absolute;\n top: 25%;\n left: 15%;\n width: 70%;\n height: 50%;\n\n @media (max-width: 800px) {\n top: 15%;\n left: 2%;\n width: 96%;\n height: 70%;\n }\n`\n\nexport const SignaturePad = styled.div`\n position: relative;\n background: ${(props) =>\n props.theme.signatureCapture?.canvas?.background ??\n 'rgba(255, 255, 255, 0.5)'};\n border: ${(props) =>\n props.theme.signatureCapture?.canvas?.border ?? `1px solid #dedede`};\n border-radius: ${(props) =>\n props.theme.signatureCapture?.canvas?.borderRadius ?? '16px'};\n flex-grow: 1;\n z-index: 100;\n height: 100%;\n`\n\nexport const SignatureButtonsContainer = styled(ButtonsRow)`\n flex-grow: 0;\n padding-top: 12px;\n display: flex;\n z-index: 1000;\n position: relative;\n`\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport { Camera } from './Camera'\nimport log from '../utils/logger'\n\nexport const useVideoRecorder = (\n camera: Camera | null,\n audioStream?: MediaStream | null,\n mergeAVStreams = false,\n) => {\n const videoRecorder = useRef<MediaRecorder | null>(null)\n const audioRecorder = useRef<MediaRecorder | null>(null)\n const videoChunks = useRef<BlobPart[]>([])\n const audioChunks = useRef<BlobPart[]>([])\n const [videoUrl, setVideoUrl] = useState<string | null>(null)\n const [audioUrl, setAudioUrl] = useState<string | null>(null)\n const [isRecordingVideo, setIsRecordingVideo] = useState(false)\n const [isRecordingAudio, setIsRecordingAudio] = useState(false)\n\n const [videoRecordingStopped, setVideoRecordingStopped] = useState(false)\n const [audioRecordingStopped, setAudioRecordingStopped] = useState(false)\n const [\n videoRecordingIntentionallyStopped,\n setVideoRecordingIntentionallyStopped,\n ] = useState(false)\n const [\n audioRecordingIntentionallyStopped,\n setAudioRecordingIntentionallyStopped,\n ] = useState(false)\n\n const getVideoStream = useCallback(() => {\n if (!mergeAVStreams) return camera?.stream\n const videoTracks = camera?.stream?.getTracks() ?? []\n const audioTracks = audioStream?.getTracks() ?? []\n return new MediaStream([...videoTracks, ...audioTracks])\n }, [audioStream, camera?.stream, mergeAVStreams])\n\n const processVideo = useCallback(() => {\n const videoBlob = new Blob(videoChunks.current, { type: 'video/mp4' })\n videoChunks.current = []\n setVideoUrl(URL.createObjectURL(videoBlob))\n setIsRecordingVideo(false)\n camera?.release()\n }, [camera])\n\n const processAudio = useCallback(() => {\n const audioBlob = new Blob(audioChunks.current, {\n type: 'audio/ogg; codecs=opus',\n })\n audioChunks.current = []\n setAudioUrl(URL.createObjectURL(audioBlob))\n setIsRecordingAudio(false)\n audioStream?.stop?.()\n }, [audioStream])\n\n const startRecordingVideo = useCallback(() => {\n const videoStream = getVideoStream()\n if (!videoStream) return\n\n videoChunks.current = []\n setIsRecordingVideo(true)\n setVideoRecordingStopped(false)\n setVideoRecordingIntentionallyStopped(false)\n\n videoRecorder.current = new MediaRecorder(videoStream, {\n videoBitsPerSecond: 270000,\n audioBitsPerSecond: 32000,\n })\n\n videoRecorder.current.ondataavailable = (e) => {\n videoChunks.current.push(e.data)\n }\n\n videoRecorder.current.onstop = () => {\n setVideoRecordingStopped(true)\n }\n\n videoRecorder.current.start(1000)\n\n setTimeout(() => {\n if (videoRecorder.current?.state === 'inactive') {\n log('media recorder is inactive!')\n // TODO: figure out what to do here\n }\n }, 100)\n }, [getVideoStream])\n\n const startRecordingAudio = useCallback(() => {\n if (mergeAVStreams) return\n if (!audioStream) return\n\n audioChunks.current = []\n setIsRecordingAudio(true)\n setAudioRecordingStopped(false)\n setAudioRecordingIntentionallyStopped(false)\n\n audioRecorder.current = new MediaRecorder(audioStream, {\n audioBitsPerSecond: 32000,\n })\n\n audioRecorder.current.ondataavailable = (e) => {\n audioChunks.current.push(e.data)\n }\n\n audioRecorder.current.onstop = () => {\n setAudioRecordingStopped(true)\n }\n\n audioRecorder.current.start(1000)\n }, [audioStream, mergeAVStreams])\n\n const stopRecordingVideo = useCallback(() => {\n setVideoRecordingIntentionallyStopped(true)\n if (videoRecorder.current?.state !== 'inactive') {\n videoRecorder.current?.stop() // if you call this while state === 'inactive', an exception is thrown.\n }\n }, [])\n\n const stopRecordingAudio = useCallback(() => {\n setAudioRecordingIntentionallyStopped(true)\n if (audioRecorder.current?.state !== 'inactive') {\n audioRecorder.current?.stop() // if you call this while state === 'inactive', an exception is thrown.\n }\n }, [])\n\n useEffect(() => {\n if (videoRecordingStopped && videoRecordingIntentionallyStopped) {\n processVideo()\n }\n }, [processVideo, videoRecordingIntentionallyStopped, videoRecordingStopped])\n\n useEffect(() => {\n if (audioRecordingStopped && audioRecordingIntentionallyStopped) {\n processAudio()\n }\n }, [audioRecordingIntentionallyStopped, audioRecordingStopped, processAudio])\n\n return {\n isRecordingVideo,\n isRecordingAudio,\n startRecordingVideo,\n startRecordingAudio,\n stopRecordingVideo,\n stopRecordingAudio,\n videoRecordingUnintentionallyStopped:\n videoRecordingStopped && !videoRecordingIntentionallyStopped,\n audioRecordingUnintentionallyStopped:\n audioRecordingStopped && !audioRecordingIntentionallyStopped,\n videoUrl,\n audioUrl,\n }\n}\n","import React, { useContext, useEffect, useRef, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useVideoRecorder } from '../../lib/camera/useVideoRecorder'\nimport {\n SignatureData,\n signatureDataToIdmissionFormat,\n} from '../signature_capture/data'\nimport SignatureCanvas from 'react-signature-canvas'\nimport useResizeObserver from 'use-resize-observer'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport { PageContainer } from '../common/Page'\nimport {\n SignatureButtonsContainer,\n SignatureCanvasContainer,\n SignaturePad,\n} from '../common/signature'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { DebugStatsPane } from '../common/debug'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { LoaderButton } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\n\nexport type VideoSignatureCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guidanceMessageContainer?: string\n guidanceMessage?: string\n canvasContainer?: string\n canvasInner?: string\n canvas?: string\n buttonsRow?: string\n acceptBtn?: string\n clearBtn?: string\n exitCaptureBtn?: string\n}\n\nexport type VideoSignatureCaptureColors = {\n guidanceMessageBackgroundColor?: string\n guidanceMessageTextColor?: string\n}\n\nexport type VideoSignatureCaptureVerbiage = {\n guidanceMessageText?: CustomerSuppliedVerbiage\n acceptBtnText?: CustomerSuppliedVerbiage\n clearBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type VideoSignatureCaptureProps = {\n onVideoCaptured?: (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => void\n onFaceNotDetected?: () => void\n onExit?: () => void\n classNames?: VideoSignatureCaptureClassNames\n colors?: VideoSignatureCaptureColors\n verbiage?: VideoSignatureCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const VideoSignatureCapture = ({\n onVideoCaptured,\n onFaceNotDetected,\n onExit,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: VideoSignatureCaptureProps): React.ReactElement => {\n const { cameraRef, videoRef } = useContext(CameraStateContext)\n const { ref, width, height } = useResizeObserver()\n const signaturePad = useRef<SignatureCanvas | null>(null)\n const signatureRecorder = useRef<MediaRecorder | null>(null)\n const recordedChunks = useRef<BlobPart[]>([])\n const { onPredictionMade } = useContext(SelfieGuidanceModelsContext)\n\n const {\n isRecordingVideo,\n startRecordingVideo,\n stopRecordingVideo,\n videoUrl,\n } = useVideoRecorder(cameraRef.current)\n const [signatureData, setSignatureData] = useState<SignatureData | null>(null)\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [signatureVideoData, setSignatureVideoData] = useState<Blob | null>(\n null,\n )\n\n colors.guidanceMessageBackgroundColor ||= '#ccc'\n colors.guidanceMessageTextColor ||= 'black'\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceMessageText: 'Please sign the box below',\n acceptBtnText: 'Accept',\n clearBtnText: 'Clear',\n })\n\n const outputCanvas = useRef<HTMLCanvasElement>(null)\n const recordingLock = useRef(false)\n\n useEffect(() => {\n if (recordingLock.current) return\n recordingLock.current = true\n ;(async () => {\n if (!outputCanvas.current) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (outputCanvas.current) {\n clearInterval(interval)\n resolve(null)\n }\n }, 10)\n })\n }\n\n startRecordingVideo()\n\n const stream = outputCanvas.current!.captureStream(24 /* fps */)\n signatureRecorder.current = new MediaRecorder(stream, {\n videoBitsPerSecond: 270000,\n })\n\n signatureRecorder.current.start()\n\n signatureRecorder.current.ondataavailable = function (event) {\n recordedChunks.current.push(event.data)\n if (signatureRecorder.current?.state === 'recording') {\n signatureRecorder.current.stop()\n }\n }\n\n signatureRecorder.current.onstop = function () {\n const blob = new Blob(recordedChunks.current, { type: 'video/mp4' })\n setSignatureVideoData(blob)\n }\n })()\n }, [isRecordingVideo, startRecordingVideo, videoUrl])\n\n useEffect(() => {\n if (signatureVideoData && signatureData && signatureDataUrl) {\n onVideoCaptured?.(signatureVideoData, signatureData, signatureDataUrl)\n }\n }, [onVideoCaptured, signatureData, signatureDataUrl, signatureVideoData])\n\n const animationFrame = useRef(0)\n useEffect(() => {\n if (\n !signaturePad.current ||\n !videoRef.current ||\n !outputCanvas.current ||\n !cameraRef.current ||\n !isRecordingVideo\n )\n return\n\n let [w, h] = [cameraRef.current.width, cameraRef.current.height]\n const isPortrait =\n typeof window !== 'undefined' && window.innerWidth < window.innerHeight\n const cameraIsLandscape = w > h\n if (isPortrait && cameraIsLandscape) [w, h] = [h, w]\n outputCanvas.current.width = w\n outputCanvas.current.height = h\n\n const ctx = outputCanvas.current.getContext('2d')\n if (!ctx) return\n\n animationFrame.current = requestAnimationFrame(async function runFrame() {\n if (!signaturePad.current || !videoRef.current || !outputCanvas.current) {\n cancelAnimationFrame(animationFrame.current)\n return\n }\n\n const rect: [number, number, number, number] = [\n w * (isPortrait ? 0.02 : 0.15),\n h * (isPortrait ? 0.15 : 0.25),\n w * (isPortrait ? 0.96 : 0.7),\n h * (isPortrait ? 0.7 : 0.5),\n ]\n\n ctx.drawImage(videoRef.current, 0, 0, w, h)\n\n ctx.beginPath()\n ctx.fillStyle = 'rgba(255,255,255,0.5)'\n ctx.roundRect(...rect, 16)\n ctx.fill()\n\n ctx.drawImage(signaturePad.current.getCanvas(), ...rect)\n\n animationFrame.current = requestAnimationFrame(runFrame)\n })\n\n return () => {\n cancelAnimationFrame(animationFrame.current)\n }\n }, [cameraRef, isRecordingVideo, onFaceNotDetected, videoRef])\n\n const [numFramesWithoutFaces, setNumFramesWithoutFaces] = useState(0)\n useEffect(() => {\n onPredictionMade((faces) => {\n setNumFramesWithoutFaces((n) => (faces.length === 0 ? n + 1 : 0))\n })\n }, [onPredictionMade])\n\n useEffect(() => {\n if (numFramesWithoutFaces >= 2) {\n onFaceNotDetected?.()\n }\n }, [numFramesWithoutFaces, onFaceNotDetected])\n\n function onAcceptClicked() {\n if (!signaturePad.current) return\n\n const signatureData = signatureDataToIdmissionFormat(signaturePad.current)\n setSignatureData(signatureData)\n setSignatureDataUrl(signaturePad.current.toDataURL())\n stopRecordingVideo()\n signatureRecorder.current?.stop()\n }\n\n return (\n <PageContainer className={`flex ${classNames.container ?? ''}`}>\n {verbiage.guidanceMessageText && (\n <GuidanceMessageContainer\n $top=\"5vh\"\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n className={classNames.guidanceMessage}\n $background={colors.guidanceMessageBackgroundColor}\n $textColor={colors.guidanceMessageTextColor}\n >\n {verbiage.guidanceMessageText}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n <SignatureCanvasContainer className={classNames.canvasContainer}>\n <SignaturePad ref={ref} className={classNames.canvasInner}>\n <SignatureCanvas\n ref={signaturePad}\n canvasProps={{ width, height, className: classNames.canvas }}\n />\n </SignaturePad>\n\n <SignatureButtonsContainer className={classNames.buttonsRow}>\n <LoaderButton\n variant=\"secondary\"\n className={classNames.clearBtn}\n onClick={signaturePad.current?.clear}\n finished\n >\n {verbiage.clearBtnText}\n </LoaderButton>\n\n <AcceptBtn\n variant=\"positive\"\n className={classNames.acceptBtn}\n style={{ marginLeft: 'auto' }}\n onClick={onAcceptClicked}\n finished\n >\n {verbiage.acceptBtnText}\n </AcceptBtn>\n </SignatureButtonsContainer>\n </SignatureCanvasContainer>\n\n {debugMode && (\n <DebugStatsPane>\n Video: {cameraRef.current?.width}x{cameraRef.current?.height}\n </DebugStatsPane>\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.exitCaptureBtn}\n />\n\n <InvisibleCanvas ref={outputCanvas} />\n </PageContainer>\n )\n}\n\nconst AcceptBtn = styled(LoaderButton)`\n margin-left: auto;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {\n VideoSignatureCapture,\n VideoSignatureCaptureClassNames,\n VideoSignatureCaptureColors,\n VideoSignatureCaptureVerbiage,\n} from './VideoSignatureCapture'\nimport {\n FaceLivenessCapture,\n FaceLivenessCaptureClassNames,\n} from '../face_liveness/FaceLivenessCapture'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { SignatureData } from '../signature_capture/data'\nimport {\n VideoSignatureSuccess,\n VideoSignatureSuccessClassNames,\n VideoSignatureSuccessColors,\n VideoSignatureSuccessVerbiage,\n} from './VideoSignatureSuccess'\nimport {\n FaceLivenessColors,\n FaceLivenessVerbiage,\n} from '../face_liveness/FaceLivenessWizard'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport {\n SelfieCaptureLoadingOverlay,\n SelfieCaptureLoadingOverlayAssets,\n SelfieCaptureLoadingOverlayClassNames,\n SelfieCaptureLoadingOverlayColors,\n SelfieCaptureLoadingOverlayMode,\n SelfieCaptureLoadingOverlayVerbiage,\n} from '../selfie_capture/SelfieCaptureLoadingOverlay'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { PageContainer } from '../common/Page'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\n\ntype CaptureState =\n | 'LOADING'\n | 'CHECKING_LIVENESS'\n | 'CAPTURING_SIGNATURE'\n | 'SUCCESS'\n | 'FAILED'\n\nexport type VideoSignatureAssets = {\n loadingOverlay?: SelfieCaptureLoadingOverlayAssets\n}\n\nexport type VideoSignatureClassNames = VideoSignatureCaptureClassNames & {\n loadingOverlay?: SelfieCaptureLoadingOverlayClassNames\n faceLiveness?: FaceLivenessCaptureClassNames\n success?: VideoSignatureSuccessClassNames\n}\n\nexport type VideoSignatureColors = VideoSignatureCaptureColors & {\n faceLiveness?: FaceLivenessColors\n loadingOverlay?: SelfieCaptureLoadingOverlayColors\n success?: VideoSignatureSuccessColors\n}\n\nexport type VideoSignatureVerbiage = VideoSignatureCaptureVerbiage & {\n loadingOverlay?: SelfieCaptureLoadingOverlayVerbiage\n faceLiveness?: FaceLivenessVerbiage\n success?: VideoSignatureSuccessVerbiage\n}\n\nexport type VideoSignatureWizardProps = {\n onComplete?: () => void\n onVideoCaptured?: (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => void\n onRetryClicked?: () => void\n onExitCapture?: () => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: SelfieCaptureLoadingOverlayMode\n modelLoadTimeoutMs?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n\n assets?: VideoSignatureAssets\n classNames?: VideoSignatureClassNames\n colors?: VideoSignatureColors\n verbiage?: VideoSignatureVerbiage\n debugMode?: boolean\n}\n\nexport const VideoSignatureWizard = ({\n onComplete,\n onVideoCaptured,\n onRetryClicked,\n onExitCapture,\n onUserCancel,\n loadingOverlayMode = 'default',\n skipSuccessScreen = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: VideoSignatureWizardProps): ReactElement => {\n const {\n selfieImage,\n signatureVideoUrl,\n setSelfieImage,\n setSignatureData,\n setSignatureVideoUrl,\n logSelfieCaptureAttempt,\n } = useContext(SubmissionContext)\n const { cameraAccessDenied } = useContext(CameraStateContext)\n const [captureState, setCaptureState] = useState<CaptureState>('LOADING')\n const operationStartedAt = useRef<Date>()\n const captureStartedAt = useRef<Date>()\n const captureEndedAt = useRef<Date>()\n const { start, stop } = useContext(SelfieGuidanceModelsContext)\n\n useEffect(() => {\n operationStartedAt.current = new Date()\n }, [])\n\n useEffect(() => {\n if (captureState !== 'CHECKING_LIVENESS') return\n captureStartedAt.current = new Date()\n }, [captureState])\n\n const shouldRun = ['CHECKING_LIVENESS', 'CAPTURING_SIGNATURE'].includes(\n captureState,\n )\n useEffect(() => {\n if (!shouldRun) return\n start()\n return () => {\n stop()\n }\n }, [shouldRun, start, stop])\n\n const logCaptureMetadata = useCallback(() => {\n logSelfieCaptureAttempt({\n autoCapture: 'Y',\n captureTime:\n (captureEndedAt.current ?? new Date()).getTime() -\n (captureStartedAt.current ?? new Date()).getTime(),\n operationTime:\n new Date().getTime() -\n (operationStartedAt.current ?? new Date()).getTime(),\n })\n\n operationStartedAt.current = new Date()\n }, [logSelfieCaptureAttempt])\n\n const onLoadingOverlayDismissed = useCallback(() => {\n setCaptureState('CHECKING_LIVENESS')\n }, [])\n\n const onFaceCaptureSuccess = useCallback(\n async (faceCropImageUrl: string) => {\n setCaptureState('CAPTURING_SIGNATURE')\n logCaptureMetadata()\n if (!selfieImage) {\n setSelfieImage(await dataUrlToBase64(faceCropImageUrl))\n }\n },\n [logCaptureMetadata, selfieImage, setSelfieImage],\n )\n\n const onSignatureCaptureCompleted = useCallback(\n (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => {\n setSignatureData(signatureData)\n setSignatureVideoUrl(URL.createObjectURL(videoData))\n setCaptureState('SUCCESS')\n onVideoCaptured?.(videoData, signatureData, signatureImageData)\n },\n [onVideoCaptured, setSignatureData, setSignatureVideoUrl],\n )\n\n const onSignatureCaptureFacesNotDetected = useCallback(() => {\n setCaptureState('CHECKING_LIVENESS')\n }, [])\n\n const [attempt, setAttempt] = useState(0)\n const onExit = useCallback(() => {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n onExitCapture?.()\n }, [onExitCapture])\n const onRetry = useCallback(() => {\n onRetryClicked?.()\n onExit()\n }, [onExit, onRetryClicked])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n captureState === 'SUCCESS',\n onComplete,\n )\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n }\n }, [cameraAccessDenied])\n\n return (\n <>\n <PageContainer className={`flex ${classNames?.container ?? ''}`}>\n <CameraVideoTag className={classNames.cameraFeed} />\n\n {captureState !== 'LOADING' &&\n (() => {\n switch (captureState) {\n case 'CHECKING_LIVENESS':\n return (\n <FaceLivenessCapture\n onSuccess={onFaceCaptureSuccess}\n onExit={onExit}\n classNames={classNames.faceLiveness}\n colors={colors.faceLiveness}\n verbiage={verbiage.faceLiveness}\n debugMode={debugMode}\n />\n )\n\n case 'CAPTURING_SIGNATURE':\n return (\n <VideoSignatureCapture\n onVideoCaptured={onSignatureCaptureCompleted}\n onFaceNotDetected={onSignatureCaptureFacesNotDetected}\n onExit={onExit}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n )\n\n case 'SUCCESS':\n if (!showSuccessScreen) return\n return (\n <VideoSignatureSuccess\n videoUrl={signatureVideoUrl ?? ''}\n onDoneClick={onComplete}\n onRetryClick={onRetry}\n classNames={classNames.success}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )\n\n default:\n return null\n }\n })()}\n </PageContainer>\n\n <SelfieCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onDismissed={onLoadingOverlayDismissed}\n onUserCancel={onUserCancel}\n />\n </>\n )\n}\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport styled from 'styled-components'\n\nexport type IdVideoCaptureFlipIdPromptAssets = {\n frontImageUrl?: string\n backImageUrl?: string\n}\n\nexport type IdVideoCaptureFlipIdPromptProps = {\n className?: string\n imageWidth?: number\n imageHeight?: number\n borderWidth?: number\n assets?: IdVideoCaptureFlipIdPromptAssets\n}\n\nexport const IdVideoCaptureFlipIdPrompt = ({\n className,\n imageWidth,\n imageHeight,\n borderWidth = 4,\n assets = {},\n}: IdVideoCaptureFlipIdPromptProps): ReactElement => {\n const { cameraRef } = useContext(CameraStateContext)\n\n assets.frontImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const isMirrored = !cameraRef.current?.isRearFacing\n\n const [transitionTime, setTransitionTime] = useState(1)\n const [rotationAngle, setRotationAngle] = useState(0)\n const frontTransforms = [`rotateY(${rotationAngle}deg)`]\n if (isMirrored) frontTransforms.push('scaleX(-1)')\n const backTransforms = [`rotateY(${180 - rotationAngle}deg)`]\n if (isMirrored) backTransforms.push('scaleX(-1)')\n\n useEffect(() => {\n let timeout: NodeJS.Timeout\n\n function doFlip() {\n setTransitionTime(1)\n setRotationAngle(180)\n\n timeout = setTimeout(() => {\n setTransitionTime(0)\n setRotationAngle(0)\n }, 1500)\n }\n\n const interval = setInterval(doFlip, 2500)\n timeout = setTimeout(doFlip, 250)\n\n return () => {\n clearInterval(interval)\n clearTimeout(timeout)\n }\n }, [])\n\n return (\n <>\n <FlipImage\n src={assets.frontImageUrl}\n alt=\"\"\n className={className}\n $transforms={frontTransforms.join(' ')}\n $transitionTime={transitionTime}\n $borderWidth={borderWidth}\n $imageWidth={imageWidth!}\n $imageHeight={imageHeight!}\n />\n\n <FlipImage\n src={assets.backImageUrl}\n alt=\"\"\n className={className}\n $transforms={backTransforms.join(' ')}\n $transitionTime={transitionTime}\n $borderWidth={borderWidth}\n $imageWidth={imageWidth!}\n $imageHeight={imageHeight!}\n $isBack\n />\n </>\n )\n}\n\nconst FlipImage = styled.img<{\n $transforms: string\n $transitionTime: number\n $borderWidth: number\n $imageWidth: number\n $imageHeight: number\n $isBack?: boolean\n}>`\n backface-visibility: hidden;\n transition: transform ${(props) => props.$transitionTime}s;\n transform: ${(props) => props.$transforms};\n transform-style: preserve-3d;\n position: ${(props) => (props.$isBack ? 'absolute' : 'relative')};\n display: block;\n top: ${(props) => -props.$borderWidth / 2}px;\n width: ${(props) => props.$imageWidth}px;\n height: ${(props) => props.$imageHeight + props.$borderWidth}px;\n`\n","import React, { ReactElement, useContext, useRef, useState } from 'react'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { IdVideoCaptureFlipIdPrompt } from './IdVideoCaptureFlipIdPrompt'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport styled, { useTheme } from 'styled-components'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\n\nexport type Action = 'SHOW_ID_FRONT' | 'FLIP_ID' | 'SHOW_ID_BACK' | 'READ_TEXT'\n\nexport type IdVideoCaptureGuidesAssets = {\n frontImageUrl?: string\n backImageUrl?: string\n}\n\nexport type IdVideoCaptureGuidesClassNames = {\n container?: string\n faceGuide?: string\n idCardGuideContainer?: string\n idCardGuideInstructionsContainer?: string\n idCardGuideInstructions?: string\n idCardGuideImageContainer?: string\n idCardGuideImage?: string\n flipIdPromptImage?: string\n}\n\nexport type IdVideoCaptureGuidesVerbiage = {\n idFrontInstructionText?: CustomerSuppliedVerbiage\n idBackInstructionText?: CustomerSuppliedVerbiage\n flipIdInstructionText?: CustomerSuppliedVerbiage\n}\n\nexport type IdVideoCaptureGuidesProps = {\n requestedAction?: Action\n satisfied?: boolean\n faceGuideBorderWidth?: number\n faceGuideBorderColor?: string\n idCardGuideBorderWidth?: number\n idCardGuideBorderColor?: string\n assets?: IdVideoCaptureGuidesAssets\n classNames?: IdVideoCaptureGuidesClassNames\n verbiage?: IdVideoCaptureGuidesVerbiage\n}\n\nexport const IdVideoCaptureGuides = ({\n requestedAction = 'SHOW_ID_FRONT',\n satisfied = false,\n faceGuideBorderWidth,\n faceGuideBorderColor,\n idCardGuideBorderWidth,\n idCardGuideBorderColor,\n assets = {},\n classNames = {},\n verbiage: rawVerbiage = {},\n}: IdVideoCaptureGuidesProps): ReactElement => {\n const { cameraRef } = useContext(CameraStateContext)\n const imageRef = useRef<HTMLImageElement | null>(null)\n const [imageWidth, setImageWidth] = useState(0)\n const [imageHeight, setImageHeight] = useState(0)\n assets.frontImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const verbiage = useTranslations(rawVerbiage, {\n idFrontInstructionText: 'Display the front of your ID card...',\n idBackInstructionText: 'Display the back of your ID card...',\n flipIdInstructionText: 'Please flip your ID card...',\n })\n\n const instructionText =\n requestedAction === 'SHOW_ID_FRONT'\n ? verbiage.idFrontInstructionText\n : requestedAction === 'FLIP_ID'\n ? verbiage.flipIdInstructionText\n : verbiage.idBackInstructionText\n\n const theme = useTheme()\n if (faceGuideBorderWidth === undefined)\n faceGuideBorderWidth = theme.idVideoCapture?.faceGuides?.borderWidth ?? 4\n if (faceGuideBorderColor === undefined)\n faceGuideBorderColor =\n (satisfied\n ? theme.idVideoCapture?.faceGuides?.satisfiedColor\n : theme.idVideoCapture?.faceGuides?.unsatisfiedColor) ?? 'white'\n\n if (idCardGuideBorderWidth === undefined)\n idCardGuideBorderWidth =\n theme.idVideoCapture?.idCardGuides?.borderWidth ?? 4\n if (idCardGuideBorderColor === undefined)\n idCardGuideBorderColor =\n (satisfied\n ? theme.idVideoCapture?.idCardGuides?.satisfiedColor\n : theme.idVideoCapture?.idCardGuides?.unsatisfiedColor) ?? 'white'\n\n const captureImageSize = () => {\n if (!imageWidth) setImageWidth(imageRef.current?.width ?? 0)\n if (!imageHeight) setImageHeight(imageRef.current?.height ?? 0)\n }\n\n return (\n <Container className={classNames.container}>\n <FaceGuide\n className={classNames.faceGuide}\n $borderWidth={faceGuideBorderWidth}\n $borderColor={faceGuideBorderColor}\n />\n\n <IdCardGuideContainer className={classNames.idCardGuideContainer}>\n <IdCardGuideInstructionsContainer\n className={classNames.idCardGuideInstructionsContainer}\n >\n <IdCardGuideInstructions\n className={classNames.idCardGuideInstructions}\n $textColor={\n theme.idVideoCapture?.idCardGuides?.instructionsTextColor\n }\n $background={\n theme.idVideoCapture?.idCardGuides?.instructionsBackgroundColor\n }\n >\n {instructionText}\n </IdCardGuideInstructions>\n </IdCardGuideInstructionsContainer>\n\n <IdCardGuideImageContainer\n $borderWidth={idCardGuideBorderWidth}\n $borderColor={idCardGuideBorderColor}\n className={classNames.idCardGuideImageContainer}\n >\n {requestedAction === 'FLIP_ID' ? (\n <IdVideoCaptureFlipIdPrompt\n assets={assets}\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n borderWidth={idCardGuideBorderWidth}\n className={classNames.flipIdPromptImage}\n />\n ) : (\n <IdCardGuideImage\n ref={imageRef}\n src={\n requestedAction === 'SHOW_ID_BACK'\n ? assets.backImageUrl\n : assets.frontImageUrl\n }\n alt=\"\"\n className={classNames.idCardGuideImage}\n $isMirrored={!cameraRef.current?.isRearFacing}\n onLoad={captureImageSize}\n onResize={captureImageSize}\n />\n )}\n </IdCardGuideImageContainer>\n </IdCardGuideContainer>\n </Container>\n )\n}\n\nconst Container = styled.div`\n position: fixed;\n z-index: 1000;\n width: 100dvw;\n height: 100dvh;\n display: flex;\n flex-direction: column;\n font-family: ${(props) => props.theme?.fontFamily};\n`\n\nconst FaceGuide = styled.div<{ $borderWidth?: number; $borderColor?: string }>`\n border-width: ${(props) => props.$borderWidth ?? 0}px;\n border-color: ${(props) => props.$borderColor ?? 'white'};\n border-style: solid;\n border-radius: 50%;\n aspect-ratio: 1 / 1.618;\n height: 50%;\n min-height: 33dvh;\n margin: 4% auto auto;\n`\n\nconst IdCardGuideContainer = styled.div`\n height: 50%;\n padding: 0 40px;\n display: flex;\n flex-flow: column nowrap;\n margin: 2% auto;\n`\n\nexport const IdCardGuideInstructionsContainer = styled.div`\n width: 100%;\n text-align: center;\n color: white;\n display: flex;\n flex-direction: column;\n justify-content: end;\n`\n\nexport const IdCardGuideInstructions = styled(GuidanceMessage)`\n align-content: center;\n margin-top: 12px;\n margin-bottom: 12px;\n padding: 8px 12px;\n font-weight: bold;\n`\n\nconst IdCardGuideImageContainer = styled.div<{\n $borderWidth?: number\n $borderColor?: string\n}>`\n position: relative;\n border: ${(props) => props.$borderWidth}px solid\n ${(props) => props.$borderColor};\n`\n\nconst IdCardGuideImage = styled.img<{ $isMirrored?: boolean }>`\n width: 100%;\n max-height: 100%;\n ${(props) => (props.$isMirrored ? 'transform: scaleX(-1);' : '')}\n`\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { LoaderButton } from '../common/LoaderButton'\nimport {\n CustomerSuppliedVerbiage,\n useTranslations,\n useVerbiage,\n} from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\n\nexport type ReadTextPromptClassNames = {\n container?: string\n heading?: string\n prompt?: string\n buttonsRow?: string\n timeRemaining?: string\n doneBtn?: string\n}\n\nexport type ReadTextPromptVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type ReadTextPromptProps = {\n text: CustomerSuppliedVerbiage\n onComplete?: () => void\n startedAt?: Date\n durationMs?: number\n minReadingMs?: number\n classNames?: ReadTextPromptClassNames\n verbiage?: ReadTextPromptVerbiage\n}\n\nexport const ReadTextPrompt = ({\n text,\n onComplete,\n durationMs = 15000,\n minReadingMs = 10000,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: ReadTextPromptProps) => {\n text = useVerbiage(text, '')\n const countdownTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)\n const [countdownRemaining, setCountdownRemaining] = useState(\n durationMs / 1000,\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Please read the following text aloud',\n doneBtnText: 'Done',\n })\n\n const manualCountdown = useCallback((remainingTime: number) => {\n if (remainingTime > 0) {\n const nextCycle = remainingTime - 1\n setCountdownRemaining(nextCycle)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(nextCycle),\n 1000,\n )\n }\n }, [])\n\n useEffect(() => {\n setCountdownRemaining(countdownRemaining)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(countdownRemaining),\n 1000,\n )\n\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [countdownRemaining, manualCountdown])\n\n const [minReadingTimeElapsed, setMinReadingTimeElapsed] = useState(false)\n\n useEffect(\n function trackReadingTime() {\n const timeout = setTimeout(() => {\n setMinReadingTimeElapsed(true)\n }, minReadingMs)\n\n return () => {\n clearTimeout(timeout)\n }\n },\n [minReadingMs],\n )\n\n return (\n <ReadTextPromptContainer className={classNames.container}>\n <ReadTextPromptHeading className={classNames.heading}>\n {verbiage.headingText}\n </ReadTextPromptHeading>\n\n <ReadTextPromptText className={classNames.prompt}>\n {text}\n </ReadTextPromptText>\n\n <ReadTextPromptButtonsRow className={classNames.buttonsRow}>\n <ReadTextPromptTimeRemaining className={classNames.timeRemaining}>\n {countdownRemaining}\n </ReadTextPromptTimeRemaining>\n\n <DoneButton\n variant=\"positive\"\n className={classNames.doneBtn}\n onClick={minReadingTimeElapsed ? onComplete : undefined}\n disabled={!minReadingTimeElapsed}\n finished\n >\n {verbiage.doneBtnText}\n </DoneButton>\n </ReadTextPromptButtonsRow>\n </ReadTextPromptContainer>\n )\n}\n\nconst ReadTextPromptContainer = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n`\n\nconst ReadTextPromptHeading = styled.div`\n padding: 20px;\n font-weight: bold;\n margin: auto auto 32px;\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.borderRadius};`\n : ``};\n`\n\nconst ReadTextPromptText = styled.div`\n margin: 0 auto;\n text-align: center;\n padding: 50px;\n font-size: 24px;\n max-width: ${typeof window !== 'undefined' &&\n window.innerWidth > window.innerHeight\n ? '40%'\n : '90%'};\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.borderRadius};`\n : ``};\n`\n\nconst ReadTextPromptButtonsRow = styled(ButtonsRow)`\n margin: 32px auto auto;\n gap: 20px;\n`\n\nconst ReadTextPromptTimeRemaining = styled.div`\n padding: 20px;\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.borderRadius};`\n : ``};\n`\n\nconst DoneButton = styled(LoaderButton)`\n margin: auto 0;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { PageContainer } from '../common/Page'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport {\n DebugBoundingBoxOverlay,\n DebugStatsPane,\n IdCaptureDetectedObjectDebugBox,\n ObjectDetectionDebugOverlayDiv,\n SelfieCaptureFaceDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport useResizeObserver from 'use-resize-observer'\nimport { IdCaptureModelsContext } from '../id_capture/IdCaptureModelsProvider'\nimport {\n IdVideoCaptureGuides,\n IdVideoCaptureGuidesAssets,\n IdVideoCaptureGuidesClassNames,\n IdVideoCaptureGuidesVerbiage,\n} from './IdVideoCaptureGuides'\nimport { useVideoRecorder } from '../../lib/camera/useVideoRecorder'\nimport {\n CustomerSuppliedVerbiage,\n useTranslations,\n useVerbiage,\n} from '../../lib/locales'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport {\n ReadTextPrompt,\n ReadTextPromptClassNames,\n ReadTextPromptVerbiage,\n} from '../read_text_prompt/ReadTextPrompt'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport styled, { useTheme } from 'styled-components'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { DetectedObject } from '../../lib/models/DocumentDetection'\nimport { Face } from '../../lib/models/FaceDetection'\n\nexport type Action = 'SHOW_ID_FRONT' | 'FLIP_ID' | 'SHOW_ID_BACK' | 'READ_TEXT'\n\nconst edgeBoundary = 0.05\n\nexport type IdVideoCaptureAssets = {\n guides?: IdVideoCaptureGuidesAssets\n}\n\nexport type IdVideoCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guides?: IdVideoCaptureGuidesClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n readTextPrompt?: ReadTextPromptClassNames\n countdownContainer?: string\n countdown?: string\n captureBtnContainer?: string\n captureBtn?: string\n}\n\nexport type IdVideoCaptureColors = {\n guidesSatisfiedColor?: string\n guidesUnsatisfiedColor?: string\n readTextDoneBtn?: LoaderButtonColors\n}\n\nexport type IdVideoCaptureVerbiage = {\n guides?: IdVideoCaptureGuidesVerbiage\n readTextPrompt?: ReadTextPromptVerbiage\n faceNotCenteredText?: CustomerSuppliedVerbiage\n searchingForIdCardText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type IdVideoCaptureProps = {\n onComplete?: (videoUrl: string, audioUrl: string | null) => void\n onIdFrontImageCaptured?: (imageUrl: string) => void\n onIdBackImageCaptured?: (imageUrl: string) => void\n onFaceNotDetected?: () => void\n onRecordingFailed?: () => void\n\n idCaptureModelsEnabled?: boolean\n idCardFrontDelay?: number\n idCardFrontDetectionThreshold?: number\n idCardBackDetectionThreshold?: number\n idCardFrontFocusThreshold?: number\n idCardBackFocusThreshold?: number\n goodIdCardFrontFramesThreshold?: number\n goodIdCardBackFramesThreshold?: number\n skipShowIdCardBack?: boolean | (() => Promise<boolean>)\n captureCountdownSeconds?: number\n readTextPrompt?: CustomerSuppliedVerbiage\n readTextTimeoutDurationMs?: number\n readTextMinReadingMs?: number\n disableFaceDetectionWhileAudioCapture: boolean\n disableFaceDetectionWhileAudioCaptureMsDelay: number\n mergeAVStreams?: boolean\n\n assets?: IdVideoCaptureAssets\n classNames?: IdVideoCaptureClassNames\n colors?: IdVideoCaptureColors\n verbiage?: IdVideoCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const IdVideoCapture = ({\n onComplete,\n onIdFrontImageCaptured,\n onIdBackImageCaptured,\n onFaceNotDetected,\n onRecordingFailed,\n\n idCaptureModelsEnabled = true,\n idCardFrontDelay = 1000,\n idCardFrontDetectionThreshold = 0.6,\n idCardFrontFocusThreshold = 0,\n goodIdCardFrontFramesThreshold = 1,\n idCardBackDetectionThreshold = 0.6,\n idCardBackFocusThreshold = 0,\n goodIdCardBackFramesThreshold = 1,\n skipShowIdCardBack = false,\n captureCountdownSeconds = 3,\n readTextPrompt,\n readTextTimeoutDurationMs = 15000,\n readTextMinReadingMs = 10000,\n disableFaceDetectionWhileAudioCapture = false,\n disableFaceDetectionWhileAudioCaptureMsDelay = 2000,\n mergeAVStreams = false,\n\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: IdVideoCaptureProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const {\n cameraRef,\n videoRef,\n videoLoaded,\n cameraReady,\n microphoneReady,\n audioStream,\n setVideoLoaded,\n takePhoto,\n } = useContext(CameraStateContext)\n const [detectedObjects, setDetectedObjects] = useState<DetectedObject[]>([])\n const [faces, setFaces] = useState<Face[]>([])\n const {\n ready: idModelsReady,\n start: startIdModels,\n stop: stopIdModels,\n onPredictionMade: onIdPredictionMade,\n setThresholds,\n bestFrameDetails,\n resetBestFrame,\n modelError: idModelError,\n } = useContext(IdCaptureModelsContext)\n const [videoStartsAt, setVideoStartsAt] = useState<Date | null>(null)\n const { setIdCaptureVideoAudioStartsAt, setExpectedAudioText } =\n useContext(SubmissionContext)\n const { onPredictionMade: onSelfiePredictionMade, error: selfieModelError } =\n useContext(SelfieGuidanceModelsContext)\n const {\n isRecordingVideo,\n startRecordingVideo,\n startRecordingAudio,\n stopRecordingVideo,\n stopRecordingAudio,\n videoRecordingUnintentionallyStopped,\n audioRecordingUnintentionallyStopped,\n videoUrl,\n audioUrl,\n } = useVideoRecorder(cameraRef.current, audioStream, mergeAVStreams)\n const countdownTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)\n const [countdownRemaining, setCountdownRemaining] = useState(0)\n\n useEffect(() => {\n if (!isRecordingVideo && !videoUrl) {\n startRecordingVideo()\n setVideoStartsAt(new Date())\n }\n\n // if the mergeAVStreams flag is present, the audio stream is on the video\n // stream, so we won't wait for a separate data url containing audio only.\n const needsAudio = !!readTextPrompt && !mergeAVStreams\n const audioReady = !needsAudio || audioUrl\n if (videoUrl && audioReady) {\n setVideoLoaded(false)\n onComplete?.(videoUrl, audioUrl)\n }\n }, [\n audioUrl,\n isRecordingVideo,\n mergeAVStreams,\n onComplete,\n readTextPrompt,\n setVideoLoaded,\n startRecordingVideo,\n videoUrl,\n ])\n\n useEffect(() => {\n if (\n videoRecordingUnintentionallyStopped ||\n audioRecordingUnintentionallyStopped\n ) {\n onRecordingFailed?.()\n }\n }, [\n audioRecordingUnintentionallyStopped,\n onRecordingFailed,\n videoRecordingUnintentionallyStopped,\n ])\n\n const shouldCaptureFrames = useRef(false)\n\n useEffect(() => {\n shouldCaptureFrames.current =\n videoLoaded &&\n cameraReady &&\n idModelsReady &&\n !idModelError &&\n (!readTextPrompt || microphoneReady)\n }, [\n cameraReady,\n idModelError,\n idModelsReady,\n microphoneReady,\n readTextPrompt,\n videoLoaded,\n ])\n\n const [requestedAction, setRequestedAction] =\n useState<Action>('SHOW_ID_FRONT')\n\n useEffect(\n function startModelsWhenCapturing() {\n if (\n !shouldCaptureFrames.current &&\n requestedAction !== 'SHOW_ID_FRONT' &&\n requestedAction !== 'SHOW_ID_BACK'\n )\n return\n\n startIdModels()\n return () => {\n stopIdModels()\n }\n },\n [requestedAction, startIdModels, stopIdModels],\n )\n\n useEffect(() => {\n setThresholds({\n idCard:\n requestedAction === 'SHOW_ID_FRONT'\n ? idCardFrontDetectionThreshold\n : requestedAction === 'SHOW_ID_BACK'\n ? idCardBackDetectionThreshold\n : 1,\n passport: 1,\n focus: {\n idCard: {\n mobile:\n requestedAction === 'SHOW_ID_FRONT'\n ? idCardFrontFocusThreshold\n : requestedAction === 'SHOW_ID_BACK'\n ? idCardBackFocusThreshold\n : 0,\n },\n },\n })\n }, [\n idCardBackDetectionThreshold,\n idCardBackFocusThreshold,\n idCardFrontDetectionThreshold,\n idCardFrontFocusThreshold,\n requestedAction,\n setThresholds,\n ])\n\n const [currentDetectionScore, setCurrentDetectionScore] = useState(0)\n const [currentFocusScore, setCurrentFocusScore] = useState(0)\n const [goodFramesCount, setGoodFramesCount] = useState(0)\n const goodFramesThreshold =\n requestedAction === 'SHOW_ID_FRONT'\n ? goodIdCardFrontFramesThreshold\n : goodIdCardBackFramesThreshold\n const goodFramesThresholdMet = goodFramesCount >= goodFramesThreshold\n useEffect(() => {\n if (!idCaptureModelsEnabled || idModelError) return\n onIdPredictionMade((prediction) => {\n setDetectedObjects(prediction.detectedObjects)\n setCurrentDetectionScore(prediction.detectionScore)\n setCurrentFocusScore(prediction.focusScore)\n\n if (prediction.detectionThresholdMet && prediction.focusThresholdMet) {\n setGoodFramesCount((n) => n + 1)\n } else {\n setGoodFramesCount(0)\n }\n })\n }, [\n idCaptureModelsEnabled,\n idCardFrontDetectionThreshold,\n onIdPredictionMade,\n idModelError,\n ])\n\n const [idFrontCaptureStartedAt, setFirstGoodFrameTime] = useState<\n number | null\n >(null)\n\n useEffect(() => {\n if (goodFramesCount === 1) setFirstGoodFrameTime(new Date().getTime())\n }, [goodFramesCount])\n\n const delaySatisfied =\n requestedAction !== 'SHOW_ID_FRONT' ||\n (idFrontCaptureStartedAt !== null &&\n new Date().getTime() > idFrontCaptureStartedAt + idCardFrontDelay)\n\n const translatedText = useVerbiage(readTextPrompt, '')\n const onIdBackCaptureComplete = useCallback(() => {\n if (translatedText) {\n setRequestedAction('READ_TEXT')\n startRecordingAudio()\n setIdCaptureVideoAudioStartsAt(\n new Date().getTime() - (videoStartsAt?.getTime() ?? 0),\n )\n setExpectedAudioText(translatedText)\n } else {\n stopRecordingVideo()\n }\n }, [\n setExpectedAudioText,\n setIdCaptureVideoAudioStartsAt,\n startRecordingAudio,\n stopRecordingVideo,\n translatedText,\n videoStartsAt,\n ])\n\n const frameWidth = videoRef.current?.videoWidth ?? 0\n const frameHeight = videoRef.current?.videoHeight ?? 0\n const faceBox = faces?.[0]?.box\n const faceCentered =\n !faceBox ||\n !frameWidth ||\n (faceBox.xMin > frameWidth * edgeBoundary &&\n faceBox.yMin > frameHeight * edgeBoundary &&\n faceBox.xMax < frameWidth * (1 - edgeBoundary) &&\n faceBox.yMax < frameHeight * (1 - edgeBoundary))\n\n const [countdownStartedAt, setCountdownStartedAt] = useState<Date>()\n\n const frameLock = useRef(false)\n const captureFrame = useCallback(async () => {\n if (frameLock.current) return\n frameLock.current = true\n\n const frame = await takePhoto()\n if (!frame) {\n frameLock.current = false\n return\n }\n\n try {\n const frameBase64 =\n frame &&\n (await new Promise<string>((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.readAsDataURL(frame)\n }))\n\n if (requestedAction == 'SHOW_ID_FRONT') {\n if (onIdFrontImageCaptured) {\n frameBase64 && onIdFrontImageCaptured(frameBase64)\n }\n\n if (skipShowIdCardBack) {\n if (skipShowIdCardBack === true) {\n return onIdBackCaptureComplete()\n } else if (await skipShowIdCardBack()) {\n return onIdBackCaptureComplete()\n }\n }\n\n setRequestedAction('FLIP_ID')\n setTimeout(() => {\n setRequestedAction('SHOW_ID_BACK')\n }, 6000)\n } else if (requestedAction == 'SHOW_ID_BACK') {\n if (onIdBackImageCaptured) {\n frameBase64 && onIdBackImageCaptured(frameBase64)\n }\n\n onIdBackCaptureComplete()\n }\n } finally {\n setDetectedObjects([])\n setCurrentDetectionScore(0)\n setCurrentFocusScore(0)\n setGoodFramesCount(0)\n setCountdownStartedAt(undefined)\n resetBestFrame()\n frameLock.current = false\n if (countdownTimeoutRef.current) {\n clearTimeout(countdownTimeoutRef.current)\n }\n }\n }, [\n onIdBackCaptureComplete,\n onIdBackImageCaptured,\n onIdFrontImageCaptured,\n requestedAction,\n resetBestFrame,\n skipShowIdCardBack,\n takePhoto,\n ])\n\n const stopRecording = useCallback(() => {\n stopRecordingVideo()\n stopRecordingAudio()\n }, [stopRecordingAudio, stopRecordingVideo])\n\n const satisfied = goodFramesThresholdMet && faceCentered && delaySatisfied\n\n useEffect(() => {\n if (satisfied && !countdownStartedAt) {\n setCountdownStartedAt(new Date())\n }\n }, [countdownStartedAt, satisfied])\n\n useEffect(() => {\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [])\n\n const manualCountdown = useCallback(\n (remainingTime: number) => {\n if (remainingTime > 0) {\n const nextCycle = remainingTime - 1\n setCountdownRemaining(nextCycle)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(nextCycle),\n 1000,\n )\n return\n }\n if (countdownStartedAt) {\n captureFrame()\n }\n },\n [captureFrame, countdownStartedAt, countdownTimeoutRef],\n )\n\n useEffect(() => {\n if (!countdownStartedAt) return\n setCountdownRemaining(captureCountdownSeconds)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(captureCountdownSeconds),\n 1000,\n )\n\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [\n captureCountdownSeconds,\n captureFrame,\n countdownStartedAt,\n manualCountdown,\n ])\n\n const { timeoutStartedAt } = useTimeout(\n readTextTimeoutDurationMs,\n stopRecording,\n requestedAction !== 'READ_TEXT',\n false,\n requestedAction === 'READ_TEXT',\n )\n\n const [numFramesWithoutFaces, setNumFramesWithoutFaces] = useState(0)\n useEffect(() => {\n if (!selfieModelError) {\n onSelfiePredictionMade((faces) => {\n setFaces(faces)\n setNumFramesWithoutFaces((n) => (faces.length === 0 ? n + 1 : 0))\n })\n }\n }, [onSelfiePredictionMade, selfieModelError])\n\n useEffect(() => {\n const ignoreMissingFaces =\n disableFaceDetectionWhileAudioCapture &&\n timeoutStartedAt?.getTime() &&\n new Date().getTime() - timeoutStartedAt?.getTime() >\n disableFaceDetectionWhileAudioCaptureMsDelay\n if (!ignoreMissingFaces && numFramesWithoutFaces >= 2) {\n onFaceNotDetected?.()\n }\n }, [\n disableFaceDetectionWhileAudioCapture,\n disableFaceDetectionWhileAudioCaptureMsDelay,\n numFramesWithoutFaces,\n onFaceNotDetected,\n timeoutStartedAt,\n ])\n\n const theme = useTheme()\n\n const { captureBtnText, faceNotCenteredText, searchingForIdCardText } =\n useTranslations(rawVerbiage, {\n faceNotCenteredText: 'Please move your face to the center...',\n searchingForIdCardText: 'Searching for ID card...',\n captureBtnText: 'Capture',\n })\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: width,\n pageHeight: height,\n videoWidth: videoRef.current?.videoWidth ?? 0,\n videoHeight: videoRef.current?.videoHeight ?? 0,\n })\n\n const capturingId = ['SHOW_ID_FRONT', 'SHOW_ID_BACK'].includes(\n requestedAction,\n )\n\n const searchingForIdCard =\n idCaptureModelsEnabled && capturingId && !goodFramesThresholdMet\n const guidanceText = !faceCentered\n ? faceNotCenteredText\n : searchingForIdCard\n ? searchingForIdCardText\n : undefined\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n {requestedAction === 'READ_TEXT' ? (\n <ReadTextPrompt\n text={readTextPrompt}\n startedAt={timeoutStartedAt || undefined}\n durationMs={readTextTimeoutDurationMs}\n minReadingMs={readTextMinReadingMs}\n classNames={classNames.readTextPrompt}\n verbiage={rawVerbiage.readTextPrompt}\n onComplete={stopRecording}\n />\n ) : (\n <>\n <IdVideoCaptureGuides\n assets={assets.guides}\n classNames={classNames.guides}\n verbiage={rawVerbiage.guides}\n requestedAction={requestedAction}\n satisfied={satisfied}\n faceGuideBorderColor={\n satisfied\n ? colors.guidesSatisfiedColor\n : colors.guidesUnsatisfiedColor\n }\n idCardGuideBorderColor={\n satisfied\n ? colors.guidesSatisfiedColor\n : colors.guidesUnsatisfiedColor\n }\n />\n\n {debugMode && capturingId && (\n <>\n <ObjectDetectionDebugOverlayDiv\n $flipX={!cameraRef.current?.isRearFacing}\n >\n {detectedObjects.map((obj, i) => (\n <IdCaptureDetectedObjectDebugBox\n key={i}\n obj={obj}\n scaling={debugScalingDetails}\n color=\"blue\"\n flipX={!cameraRef.current?.isRearFacing}\n />\n ))}\n </ObjectDetectionDebugOverlayDiv>\n\n <DebugBoundingBoxOverlay>\n {faces.map((face, i) => (\n <SelfieCaptureFaceDebugBox\n key={i}\n face={face}\n scaling={debugScalingDetails}\n />\n ))}\n </DebugBoundingBoxOverlay>\n </>\n )}\n </>\n )}\n\n {guidanceText && idCaptureModelsEnabled && !idModelError && (\n <GuidanceMessageContainer\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n className={classNames.guidanceMessage}\n $background={\n theme.guidanceMessages?.negative?.backgroundColor ?? 'red'\n }\n $textColor={theme.guidanceMessages?.negative?.textColor ?? 'white'}\n >\n {guidanceText}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {isRecordingVideo ? '✅ Recording' : '❌ Not recording'}\n <br />\n {goodFramesThresholdMet ? '✅' : '❌'} Good Frame Count:{' '}\n {goodFramesCount}/{goodFramesThreshold}\n <br />\n Detection Score: {currentDetectionScore}\n <br />\n Focus Score: {currentFocusScore}\n <br />\n Best Frame Detection Score: {bestFrameDetails?.detectionScore ?? 0}\n <br />\n Best Frame Focus Score: {bestFrameDetails?.focusScore ?? 0}\n </DebugStatsPane>\n )}\n\n {!!countdownRemaining && capturingId && (\n <CountdownContainer className={classNames.countdownContainer}>\n <Countdown className={classNames.countdown}>\n {countdownRemaining}\n </Countdown>\n </CountdownContainer>\n )}\n\n {(!idCaptureModelsEnabled || idModelError) && capturingId && (\n <CaptureButtonContainer className={classNames.captureBtnContainer}>\n <CaptureButton\n finished\n onClick={() => {\n setCountdownStartedAt(new Date())\n }}\n disabled={!!countdownStartedAt || frameLock.current}\n className={classNames.captureBtn}\n >\n {captureBtnText}\n </CaptureButton>\n </CaptureButtonContainer>\n )}\n </PageContainer>\n )\n}\n\nconst CountdownContainer = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n width: 100dvw;\n height: 100dvh;\n z-index: 99999;\n display: flex;\n`\n\nconst Countdown = styled.div`\n color: white;\n font-size: 64px;\n font-weight: bold;\n margin: auto;\n`\n\nconst CaptureButtonContainer = styled.div`\n position: fixed;\n bottom: 0;\n width: 100dvw;\n display: flex;\n z-index: 100000;\n`\n\nconst CaptureButton = styled(LoaderButton)`\n margin: 0 auto 25px;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport {\n IdCaptureSubmission,\n IdCaptureWizard,\n IdCaptureWizardProps,\n} from './id_capture/IdCaptureWizard'\nimport {\n FaceLivenessWizard,\n FaceLivenessWizardProps,\n} from './face_liveness/FaceLivenessWizard'\nimport { IdCaptureModelsProvider } from './id_capture/IdCaptureModelsProvider'\nimport { CameraProvider } from './camera/CameraProvider'\nimport { GuideOrientationProvider } from './GuideOrientationProvider'\nimport {\n SubmissionContext,\n SubmissionProvider,\n} from './submission/SubmissionProvider'\nimport {\n LivenessCheckRequest,\n SubmissionAction,\n SubmissionResponse,\n SubmissionStatus,\n} from '../contexts/SubmissionContext'\nimport { SubmissionSuccess } from './submission/SubmissionSuccess'\nimport { Spinner } from './common/spinner'\nimport {\n AdditionalDocumentCaptureWizard,\n AdditionalDocumentCaptureWizardProps,\n} from './additional_document_capture/AdditionalDocumentCaptureWizard'\nimport {\n SignatureCapture,\n SignatureCaptureProps,\n} from './signature_capture/SignatureCapture'\nimport { SelfieGuidanceModelsProvider } from './selfie_capture/SelfieGuidanceModelsProvider'\nimport {\n VideoSignatureWizard,\n VideoSignatureWizardProps,\n} from './video_signature_capture/VideoSignatureWizard'\nimport { SignatureData } from './signature_capture/data'\nimport { UploadedDocument } from './additional_document_capture/AdditionalDocumentCapture'\nimport { PageContainer } from './common/Page'\nimport {\n VideoIdWizard,\n VideoIdWizardProps,\n} from './video_id/IdVideoCaptureWizard'\nimport { IdCaptureStateProvider } from './id_capture/IdCaptureStateProvider'\nimport { AuthProvider } from '../contexts/AuthStateContext'\n\nexport type CompositeWizardCheck =\n | 'IdCapture'\n | 'FaceLiveness'\n | 'SignatureCapture'\n | 'VideoSignatureCapture'\n | 'AdditionalDocumentCapture'\n | 'VideoIdCapture'\n\nexport type CompositeWizardComponentProps = {\n checks: CompositeWizardCheck[]\n\n idCaptureProps?: IdCaptureWizardProps\n faceLivenessProps?: FaceLivenessWizardProps\n additionalDocumentCaptureProps?: AdditionalDocumentCaptureWizardProps\n signatureCaptureProps?: SignatureCaptureProps\n videoSignatureCaptureProps?: VideoSignatureWizardProps\n videoIdCaptureProps?: VideoIdWizardProps\n captureSignature?: boolean | (() => Promise<boolean>)\n captureSignatureVideo?: boolean | (() => Promise<boolean>)\n\n onCameraAccessDenied?: () => void\n onMicrophoneAccessDenied?: () => void\n\n debugMode?: boolean\n}\n\nexport type CompositeWizardProps = CompositeWizardComponentProps & {\n sessionId: string\n submissionAction?: SubmissionAction\n submissionUrl?: string\n authUrl?: string\n onComplete?: (submissionResponse: SubmissionResponse) => void\n}\n\nexport const CompositeWizard = (props: CompositeWizardProps): ReactElement => (\n <AuthProvider authUrl={props.authUrl} sessionId={props.sessionId}>\n <SubmissionProvider\n action={props.submissionAction ?? SubmissionAction.VALIDATE}\n submissionUrl={props.submissionUrl}\n onResponseReceived={props.onComplete}\n >\n <CompositeWizardComponent {...props} />\n </SubmissionProvider>\n </AuthProvider>\n)\n\nexport const CompositeWizardComponent = ({\n checks: userChecks,\n idCaptureProps = {},\n faceLivenessProps = {},\n additionalDocumentCaptureProps,\n signatureCaptureProps = {},\n videoSignatureCaptureProps = {},\n videoIdCaptureProps = {},\n captureSignature = false,\n captureSignatureVideo = false,\n onCameraAccessDenied,\n onMicrophoneAccessDenied,\n debugMode = false,\n}: CompositeWizardComponentProps): ReactElement => {\n const { submit, submissionStatus, setSignatureData, setAdditionalDocuments } =\n useContext(SubmissionContext)\n const [checkIndex, setCheckIndex] = useState(0)\n const checks = useMemo(() => {\n const checks = [...userChecks]\n if (captureSignature && captureSignatureVideo) {\n throw new Error(\n 'captureSignature and captureSignatureVideo cannot be used together',\n )\n }\n if (captureSignature) {\n checks.push('SignatureCapture')\n }\n if (captureSignatureVideo) {\n checks.push('VideoSignatureCapture')\n // remove face liveness because video signature already has it.\n if (checks.includes('FaceLiveness'))\n checks.splice(checks.indexOf('FaceLiveness'), 1)\n }\n if (additionalDocumentCaptureProps?.documents?.length ?? 0 > 0) {\n checks.push('AdditionalDocumentCapture')\n }\n return checks\n }, [\n additionalDocumentCaptureProps?.documents?.length,\n captureSignature,\n captureSignatureVideo,\n userChecks,\n ])\n const currentCheck = checks[checkIndex]\n const isComplete = checkIndex >= checks.length\n\n useEffect(() => {\n if (\n currentCheck === 'SignatureCapture' &&\n typeof captureSignature === 'function'\n ) {\n captureSignature().then((shouldProceed) => {\n if (!shouldProceed) {\n setCheckIndex((i) => i + 1)\n }\n })\n } else if (\n currentCheck === 'VideoSignatureCapture' &&\n typeof captureSignatureVideo === 'function'\n ) {\n captureSignatureVideo().then((shouldProceed) => {\n if (!shouldProceed) {\n setCheckIndex((i) => i + 1)\n }\n })\n }\n }, [captureSignature, captureSignatureVideo, currentCheck])\n\n useEffect(() => {\n if (isComplete) submit()\n }, [isComplete, submit])\n\n const onIdCaptureSuccessProp = idCaptureProps.onSuccess\n const onIdCaptureSuccess = useCallback(\n (submission: IdCaptureSubmission) => {\n onIdCaptureSuccessProp?.(submission)\n setCheckIndex((i) => i + 1)\n },\n [onIdCaptureSuccessProp],\n )\n\n const onVideoIdCaptureCompleteProp = videoIdCaptureProps.onComplete\n const onVideoIdCaptureComplete = useCallback(() => {\n onVideoIdCaptureCompleteProp?.()\n setCheckIndex((i) => i + 1)\n }, [onVideoIdCaptureCompleteProp])\n\n const onFaceLivenessCompleteProp = faceLivenessProps.onComplete\n const onFaceLivenessComplete = useCallback(\n (resp: SubmissionResponse | null, req: LivenessCheckRequest | null) => {\n onFaceLivenessCompleteProp?.(resp, req)\n setCheckIndex((i) => i + 1)\n },\n [onFaceLivenessCompleteProp],\n )\n\n const onSignatureCaptureSuccess = useCallback(\n (signatureData: SignatureData) => {\n setSignatureData(signatureData)\n setCheckIndex((i) => i + 1)\n },\n [setSignatureData],\n )\n\n const onVideoSignatureCompleteProp = videoSignatureCaptureProps.onComplete\n const onVideoSignatureComplete = useCallback(() => {\n onVideoSignatureCompleteProp?.()\n setCheckIndex((i) => i + 1)\n }, [onVideoSignatureCompleteProp])\n const [videoSignatureAttempts, setVideoSignatureAttempts] = useState(0)\n const onVideoSignatureRetryProp = videoSignatureCaptureProps.onRetryClicked\n const onVideoSignatureRetry = useCallback(() => {\n onVideoSignatureRetryProp?.()\n setVideoSignatureAttempts((n) => n + 1)\n }, [onVideoSignatureRetryProp])\n\n const onAdditionalDocumentCaptureCompleteProp =\n additionalDocumentCaptureProps?.onComplete\n const onAdditionalDocumentCaptureComplete = useCallback(\n (uploadedDocuments: UploadedDocument[]) => {\n setAdditionalDocuments(uploadedDocuments)\n onAdditionalDocumentCaptureCompleteProp?.(uploadedDocuments)\n setCheckIndex((i) => i + 1)\n },\n [onAdditionalDocumentCaptureCompleteProp, setAdditionalDocuments],\n )\n\n const documents = useMemo(\n () => additionalDocumentCaptureProps?.documents ?? [],\n [additionalDocumentCaptureProps?.documents],\n )\n\n if (isComplete) {\n switch (submissionStatus) {\n case SubmissionStatus.SUBMITTING:\n return (\n <PageContainer className=\"flex\">\n <Spinner />\n </PageContainer>\n )\n\n case SubmissionStatus.SUBMITTED:\n return <SubmissionSuccess />\n\n case SubmissionStatus.FAILED:\n return <>Submission failed!</>\n\n default:\n return <>Complete!!</>\n }\n }\n\n switch (checks[checkIndex]) {\n case 'IdCapture':\n return (\n <CameraProvider\n key=\"IdCaptureCamera\"\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <IdCaptureModelsProvider\n autoStart={false}\n documentDetectionModelUrl={\n idCaptureProps.assets?.documentDetectionModelUrl ?? ''\n }\n focusModelUrl={idCaptureProps.assets?.focusModelUrl ?? ''}\n onModelError={idCaptureProps.onModelError}\n modelLoadTimeoutMs={idCaptureProps.modelLoadTimeoutMs}\n >\n <IdCaptureStateProvider>\n <GuideOrientationProvider>\n <IdCaptureWizard\n {...idCaptureProps}\n onSuccess={onIdCaptureSuccess}\n />\n </GuideOrientationProvider>\n </IdCaptureStateProvider>\n </IdCaptureModelsProvider>\n </CameraProvider>\n )\n\n case 'VideoIdCapture':\n return (\n <VideoIdWizard\n {...videoIdCaptureProps}\n onComplete={onVideoIdCaptureComplete}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n />\n )\n\n case 'FaceLiveness':\n return (\n <CameraProvider\n key=\"FaceLivenessCamera\"\n preferFrontFacingCamera={true}\n preferContinuityCamera={false}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <SelfieGuidanceModelsProvider\n autoStart={false}\n onModelError={faceLivenessProps.onModelError}\n modelLoadTimeoutMs={faceLivenessProps.modelLoadTimeoutMs}\n >\n <FaceLivenessWizard\n {...faceLivenessProps}\n onComplete={onFaceLivenessComplete}\n />\n </SelfieGuidanceModelsProvider>\n </CameraProvider>\n )\n\n case 'SignatureCapture':\n return (\n <SignatureCapture\n {...signatureCaptureProps}\n onAccept={onSignatureCaptureSuccess}\n />\n )\n\n case 'VideoSignatureCapture':\n return (\n <CameraProvider\n key={`SignatureKycCamera-${videoSignatureAttempts}`}\n preferContinuityCamera={false}\n preferFrontFacingCamera={true}\n maxVideoWidth={1280}\n maxFps={30}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <SelfieGuidanceModelsProvider\n autoStart={false}\n throttleMs={250}\n onModelError={videoSignatureCaptureProps.onModelError}\n modelLoadTimeoutMs={videoSignatureCaptureProps.modelLoadTimeoutMs}\n >\n <VideoSignatureWizard\n {...videoSignatureCaptureProps}\n onComplete={onVideoSignatureComplete}\n onRetryClicked={onVideoSignatureRetry}\n />\n </SelfieGuidanceModelsProvider>\n </CameraProvider>\n )\n\n case 'AdditionalDocumentCapture':\n return (\n <AdditionalDocumentCaptureWizard\n {...additionalDocumentCaptureProps}\n documents={documents}\n onComplete={onAdditionalDocumentCaptureComplete}\n />\n )\n\n default:\n return <></>\n }\n}\n","import React, { ReactNode, useEffect } from 'react'\nimport {\n DefaultTheme,\n ThemeProvider as ScThemeProvider,\n} from 'styled-components'\nimport { Color } from './color'\n\nexport interface Theme {\n isFullscreen?: boolean\n fontFamily?: string\n background?: string\n padding?: string\n textAlign?: string\n textColor?: string\n\n colors?: {\n primary?: Color\n secondary?: Color\n positive?: Color\n negative?: Color\n warning?: Color\n }\n\n buttons?: {\n style?: 'bootstrap' | 'none'\n primary?: {\n backgroundColor?: string\n textColor?: string\n }\n secondary?: {\n backgroundColor?: string\n textColor?: string\n }\n positive?: {\n backgroundColor?: string\n textColor?: string\n }\n negative?: {\n backgroundColor?: string\n textColor?: string\n }\n warning?: {\n backgroundColor?: string\n textColor?: string\n }\n loading?: {\n backgroundColor?: string\n textColor?: string\n }\n }\n\n guidanceMessages?: {\n default?: {\n backgroundColor?: string\n textColor?: string\n }\n positive?: {\n backgroundColor?: string\n textColor?: string\n }\n negative?: {\n backgroundColor?: string\n textColor?: string\n }\n }\n\n idCapture?: {\n loadingOverlay?: {\n backgroundColor?: string\n textColor?: string\n loadingGraphicAccentColor?: string\n loadingGraphicAccentOpacity?: number\n progressBarBackgroundColor?: string\n progressBarBackgroundOpacity?: number\n progressBarIndicatorColor?: string\n progressBarTextColor?: string\n progressBarFontSize?: string\n continueBtnBorder?: string\n }\n guideOverlay?: {\n backgroundColor?: string\n textColor?: string\n }\n guideBox?: {\n unsatisfiedColor?: string\n satisfiedColor?: string\n borderWidth?: number\n desktopPadding?: number\n mobilePadding?: number\n imagePadding?: number\n }\n capturePreview?: {\n disabled?: boolean\n }\n success?: {\n imageBorderColor?: string\n }\n }\n\n selfieCapture?: {\n loadingOverlay?: {\n backgroundColor?: string\n textColor?: string\n loadingGraphicAccentColor?: string\n progressBarBackgroundOpacity?: number\n progressBarBackgroundColor?: string\n progressBarIndicatorColor?: string\n progressBarTextColor?: string\n progressBarFontSize?: string\n continueBtnBorder?: string\n }\n guides?: {\n unsatisfiedColor?: string\n satisfiedColor?: string\n }\n capturePreview?: {\n disabled?: boolean\n }\n }\n\n signatureCapture?: {\n background?: string\n backgroundSize?: string\n backgroundPosition?: string\n\n canvas?: {\n background?: string\n border?: string\n borderRadius?: string\n }\n }\n\n idVideoCapture?: {\n faceGuides?: {\n borderWidth?: number\n unsatisfiedColor?: string\n satisfiedColor?: string\n }\n\n idCardGuides?: {\n borderWidth?: number\n unsatisfiedColor?: string\n satisfiedColor?: string\n instructionsTextColor?: string\n instructionsBackgroundColor?: string\n }\n\n readTextPrompt?: {\n heading?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n prompt?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n timeRemaining?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n }\n }\n\n documentCapture?: {\n guideBox?: {\n borderWidth?: number\n mobilePadding?: number\n desktopPadding?: number\n maskColor?: string\n }\n instructions?: {\n maxHeight?: number\n }\n }\n}\n\nconst noneTheme = {} satisfies Theme\nconst defaultTheme = {\n fontFamily: `Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif`,\n isFullscreen: true,\n background: 'white',\n textColor: 'black',\n textAlign: 'center',\n padding: '25px',\n\n colors: {\n primary: {\n '50': '#eef8ff',\n '100': '#d8eeff',\n '200': '#b9e0ff',\n '300': '#89cfff',\n '400': '#52b4ff',\n '500': '#2a91ff',\n '600': '#0d6efd', // default\n '700': '#0c5ae9',\n '800': '#1149bc',\n '900': '#144194',\n '950': '#11295a',\n },\n secondary: {\n '50': '#f6f6f6',\n '100': '#e7e7e7',\n '200': '#d1d1d1',\n '300': '#b0b0b0',\n '400': '#888888',\n '500': '#666666', // default\n '600': '#5d5d5d',\n '700': '#4f4f4f',\n '800': '#454545',\n '900': '#3d3d3d',\n '950': '#262626',\n },\n positive: {\n '50': '#f1fcf9',\n '100': '#cef9eb',\n '200': '#9df2d8',\n '300': '#65e3c2',\n '400': '#4fd4ad',\n '500': '#1cb090',\n '600': '#16a085', // default\n '700': '#147160',\n '800': '#155a4f',\n '900': '#164b42',\n '950': '#062d28',\n },\n negative: {\n '50': '#fff1f2',\n '100': '#ffe4e6',\n '200': '#fecdd3',\n '300': '#fda4af',\n '400': '#fb7185',\n '500': '#f43f5e', // default\n '600': '#e11d48',\n '700': '#be123c',\n '800': '#9f1239',\n '900': '#881337',\n '950': '#4c0519',\n },\n warning: {\n '50': '#fdf5ef',\n '100': '#fbe7d9',\n '200': '#f6cdb2',\n '300': '#f0ab81',\n '400': '#ea8557', // default\n '500': '#e35e2c',\n '600': '#d54621',\n '700': '#b1341d',\n '800': '#8d2b1f',\n '900': '#72261c',\n '950': '#3d100d',\n },\n },\n\n buttons: {\n style: 'bootstrap',\n\n primary: {\n backgroundColor: 'var(--idm-color-primary-600)',\n textColor: 'white',\n },\n secondary: {\n backgroundColor: 'var(--idm-color-secondary-500)',\n textColor: 'white',\n },\n positive: {\n backgroundColor: 'var(--idm-color-positive-600)',\n textColor: 'white',\n },\n negative: {\n backgroundColor: 'var(--idm-color-negative-400)',\n textColor: 'white',\n },\n warning: {\n backgroundColor: 'var(--idm-color-warning-400)',\n textColor: 'white',\n },\n loading: {\n backgroundColor: 'gray',\n textColor: 'white',\n },\n },\n\n guidanceMessages: {\n default: {\n backgroundColor: 'var(--idm-color-secondary-200)',\n textColor: 'black',\n },\n positive: {\n backgroundColor: 'var(--idm-color-positive-700)',\n textColor: 'white',\n },\n negative: {\n backgroundColor: 'var(--idm-color-negative-600)',\n textColor: 'white',\n },\n },\n\n idCapture: {\n loadingOverlay: {\n backgroundColor: '#ecedf3',\n textColor: 'black',\n loadingGraphicAccentColor: 'var(--idm-color-positive-600)',\n loadingGraphicAccentOpacity: 0.2,\n progressBarBackgroundColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundOpacity: 0.75,\n progressBarIndicatorColor: 'var(--idm-color-positive-600)',\n progressBarTextColor: 'white',\n continueBtnBorder: '2px solid white',\n },\n guideOverlay: {\n backgroundColor: '#708090',\n textColor: 'white',\n },\n guideBox: {\n unsatisfiedColor: 'white',\n satisfiedColor: 'var(--idm-color-positive-500)',\n borderWidth: 4,\n desktopPadding: 50,\n mobilePadding: 0,\n imagePadding: 25,\n },\n },\n\n selfieCapture: {\n loadingOverlay: {\n backgroundColor: '#ecedf3',\n textColor: 'black',\n loadingGraphicAccentColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundOpacity: 0.75,\n progressBarIndicatorColor: 'var(--idm-color-positive-600)',\n progressBarTextColor: 'white',\n continueBtnBorder: '2px solid white',\n },\n guides: {\n unsatisfiedColor: 'white',\n satisfiedColor: 'var(--idm-color-positive-500)',\n },\n },\n\n signatureCapture: {\n background:\n 'radial-gradient(#444cf7 0.5px, transparent 0.5px), radial-gradient(#444cf7 0.5px, #e5e5f7 0.5px)',\n backgroundSize: '20px 20px',\n backgroundPosition: '0 0, 10px 10px',\n },\n\n idVideoCapture: {\n readTextPrompt: {\n heading: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '8px',\n },\n prompt: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '8px',\n },\n timeRemaining: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '4px',\n },\n },\n },\n} satisfies Theme\n\nexport const themes = {\n default: defaultTheme,\n none: noneTheme,\n}\n\nexport type ThemeInput = keyof typeof themes | Theme\n\nexport const resolveTheme = (input: ThemeInput): DefaultTheme => {\n if (typeof input === 'string') {\n if (input in themes) return themes[input]\n return themes.none\n }\n\n return input\n}\n\nexport const ThemeProvider = ({\n children,\n theme: themeInput,\n}: {\n children: ReactNode\n theme: ThemeInput\n}) => {\n const theme = resolveTheme(themeInput)\n const colors = theme.colors\n\n useEffect(() => {\n for (const name in colors) {\n const variants = colors[name as keyof typeof colors]\n for (const num in variants) {\n const color = variants[num as keyof typeof variants]\n document.documentElement.style.setProperty(\n `--idm-color-${name}-${num}`,\n color,\n )\n }\n }\n }, [colors])\n\n return <ScThemeProvider theme={theme}>{children}</ScThemeProvider>\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\nconst ALLOWED_RETRIES = 0\n\ntype IdentificationState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'VERIFYING'\n | 'VERIFIED'\n | 'REJECTED'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n imageUrl: string | null\n requestState: IdentificationState\n requestError: Error | null\n unverifiedTimes: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n imageUrl: null,\n requestState: 'CAPTURING',\n requestError: null,\n unverifiedTimes: 0,\n}\n\ntype Action =\n | {\n type: 'verificationReady'\n payload: { frame: ImageData; face: Face }\n }\n | { type: 'verifying'; payload: { imageUrl: string } }\n | {\n type: 'verificationCompleted'\n payload: { response: SubmissionResponse }\n }\n | { type: 'verificationFailed'; payload: { error: Error } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'verificationReady': {\n const allowedStates = ['CAPTURING', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'verifying':\n return {\n ...state,\n requestState: 'VERIFYING',\n imageUrl: action.payload.imageUrl,\n }\n\n case 'verificationCompleted': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n let { requestState, unverifiedTimes } = state\n const customerMatched = resultData.verificationResultCode === '00'\n if (customerMatched) {\n requestState = 'VERIFIED'\n } else {\n if (unverifiedTimes < ALLOWED_RETRIES) {\n requestState = 'CAPTURING'\n unverifiedTimes += 1\n } else {\n requestState = 'REJECTED'\n }\n }\n\n return { ...state, requestState, unverifiedTimes }\n }\n\n case 'verificationFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type CustomerVerificationCaptureClassNames = SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n}\n\nexport type CustomerVerificationCaptureColors = SelfieCaptureColors\n\nexport type CustomerVerificationCaptureVerbiage = SelfieCaptureVerbiage & {\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type CustomerVerificationCaptureProps = {\n onCustomerMatched?: (resp: SubmissionResponse, req: SubmissionRequest) => void\n onCustomerNotMatched?: (\n resp: SubmissionResponse,\n req: SubmissionRequest,\n ) => void\n onCaptureGuidanceTimeout?: () => void\n onExit?: () => void\n captureGuidanceTimeoutDurationMs?: number\n classNames?: CustomerVerificationCaptureClassNames\n colors?: CustomerVerificationCaptureColors\n verbiage?: CustomerVerificationCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const CustomerVerificationCapture = ({\n onCustomerMatched,\n onCustomerNotMatched,\n onCaptureGuidanceTimeout,\n onExit,\n captureGuidanceTimeoutDurationMs,\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: CustomerVerificationCaptureProps): ReactElement => {\n const [state, dispatch] = useReducer(reducer, initialState)\n const { frame, face } = state\n const {\n submit,\n submissionRequest,\n submissionResponse,\n submissionError,\n selfieImage,\n setSelfieImage,\n } = useContext(SubmissionContext)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n\n const onSelfieCaptured = useCallback((frame: ImageData, face: Face) => {\n dispatch({ type: 'verificationReady', payload: { frame, face } })\n }, [])\n\n const isReady = state.requestState === 'CAPTURED'\n useEffect(() => {\n if (!frame || !face || submissionError) return\n\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n dataUrlToBase64(imageUrl).then((img) => {\n setSelfieImage(img)\n })\n }, [face, frame, setSelfieImage, submissionError])\n\n useEffect(() => {\n if (!isReady || !selfieImage || submissionError) return\n ;(async () => {\n try {\n dispatch({ type: 'verifying', payload: { imageUrl: selfieImage } })\n const submissionResponse = await submit()\n if (!submissionResponse) throw new Error('submission failed!')\n\n dispatch({\n type: 'verificationCompleted',\n payload: { response: submissionResponse },\n })\n } catch (e) {\n dispatch({\n type: 'verificationFailed',\n payload: { error: e as Error },\n })\n }\n })()\n }, [\n isReady,\n onCustomerMatched,\n onCustomerNotMatched,\n selfieImage,\n state.requestState,\n submissionError,\n submit,\n ])\n\n useEffect(() => {\n if (!submissionRequest || !submissionResponse) return\n if (state.requestState === 'VERIFIED') {\n onCustomerMatched?.(submissionResponse, submissionRequest)\n } else if (state.requestState === 'REJECTED') {\n onCustomerNotMatched?.(submissionResponse, submissionRequest)\n }\n }, [\n onCustomerMatched,\n onCustomerNotMatched,\n state.requestState,\n submissionRequest,\n submissionResponse,\n ])\n\n useTimeout(\n captureGuidanceTimeoutDurationMs,\n onCaptureGuidanceTimeout,\n ['VERIFIED', 'REJECTED'].includes(state.requestState),\n state.requestState === 'VERIFYING',\n )\n\n const progressPreviewText = useVerbiage(\n verbiage.progressPreviewText,\n 'Processing...',\n )\n\n const theme = useTheme()\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={captureGuidanceTimeoutDurationMs}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n imageUrl={imageUrl}\n text={progressPreviewText}\n classNames={classNames.imagePreview}\n />\n )}\n </>\n )\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\nconst ALLOWED_RETRIES = 0\n\ntype IdentificationState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'IDENTIFYING'\n | 'FOUND'\n | 'NOT_FOUND'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n imageUrl: string | null\n requestState: IdentificationState\n requestError: Error | null\n notFoundTimes: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n imageUrl: null,\n requestState: 'CAPTURING',\n requestError: null,\n notFoundTimes: 0,\n}\n\ntype Action =\n | {\n type: 'identificationReady'\n payload: { frame: ImageData; face: Face }\n }\n | { type: 'identifying'; payload: { imageUrl: string } }\n | {\n type: 'identificationCompleted'\n payload: { response: SubmissionResponse }\n }\n | { type: 'identificationFailed'; payload: { error: Error } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'identificationReady': {\n const allowedStates = ['CAPTURING', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'identifying':\n return {\n ...state,\n requestState: 'IDENTIFYING',\n imageUrl: action.payload.imageUrl,\n }\n\n case 'identificationCompleted': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n let { requestState, notFoundTimes } = state\n const customerMatched = resultData.verificationResultCode === '46'\n if (customerMatched) {\n requestState = 'FOUND'\n } else if (notFoundTimes < ALLOWED_RETRIES) {\n requestState = 'CAPTURING'\n notFoundTimes += 1\n } else {\n requestState = 'NOT_FOUND'\n }\n\n return { ...state, requestState, notFoundTimes }\n }\n\n case 'identificationFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type CustomerIdentificationCaptureClassNames =\n SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n }\n\nexport type CustomerIdentificationCaptureColors = SelfieCaptureColors\n\nexport type CustomerIdentificationCaptureVerbiage = SelfieCaptureVerbiage & {\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type CustomerIdentificationCaptureProps = {\n onCustomerMatched?: (resp: SubmissionResponse, req: SubmissionRequest) => void\n onCustomerNotMatched?: (\n resp: SubmissionResponse,\n req: SubmissionRequest,\n ) => void\n onCaptureGuidanceTimeout?: () => void\n onExit?: () => void\n captureGuidanceTimeoutDurationMs?: number\n classNames?: CustomerIdentificationCaptureClassNames\n colors?: CustomerIdentificationCaptureColors\n verbiage?: CustomerIdentificationCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const CustomerIdentificationCapture = ({\n onCustomerMatched,\n onCustomerNotMatched,\n onCaptureGuidanceTimeout,\n onExit,\n captureGuidanceTimeoutDurationMs,\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: CustomerIdentificationCaptureProps): ReactElement => {\n const [state, dispatch] = useReducer(reducer, initialState)\n const {\n submit,\n submissionRequest,\n submissionResponse,\n submissionError,\n selfieImage,\n setSelfieImage,\n } = useContext(SubmissionContext)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n\n const onSelfieCaptured = useCallback((frame: ImageData, face: Face) => {\n dispatch({ type: 'identificationReady', payload: { frame, face } })\n }, [])\n\n const { frame, face } = state\n const isReady = state.requestState === 'CAPTURED'\n useEffect(() => {\n if (!frame || !face || submissionError) return\n\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n dataUrlToBase64(imageUrl).then((img) => {\n setSelfieImage(img)\n })\n }, [face, frame, setSelfieImage, submissionError])\n\n useEffect(() => {\n if (!isReady || !selfieImage || submissionError) return\n ;(async () => {\n try {\n dispatch({ type: 'identifying', payload: { imageUrl: selfieImage } })\n const submissionResponse = await submit()\n if (!submissionResponse) throw new Error('submission failed!')\n\n dispatch({\n type: 'identificationCompleted',\n payload: { response: submissionResponse },\n })\n } catch (e) {\n dispatch({\n type: 'identificationFailed',\n payload: { error: e as Error },\n })\n }\n })()\n }, [\n isReady,\n onCustomerMatched,\n onCustomerNotMatched,\n selfieImage,\n state.requestState,\n submissionError,\n submit,\n ])\n\n useEffect(() => {\n if (!submissionRequest || !submissionResponse) return\n if (state.requestState === 'FOUND') {\n onCustomerMatched?.(submissionResponse, submissionRequest)\n } else if (state.requestState === 'NOT_FOUND') {\n onCustomerNotMatched?.(submissionResponse, submissionRequest)\n }\n }, [\n onCustomerMatched,\n onCustomerNotMatched,\n state.requestState,\n submissionRequest,\n submissionResponse,\n ])\n\n useTimeout(\n captureGuidanceTimeoutDurationMs,\n onCaptureGuidanceTimeout,\n ['FOUND', 'NOT_FOUND'].includes(state.requestState),\n state.requestState === 'IDENTIFYING',\n )\n\n const progressPreviewText = useVerbiage(\n verbiage.progressPreviewText,\n 'Processing...',\n )\n\n const theme = useTheme()\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={captureGuidanceTimeoutDurationMs}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n text={progressPreviewText}\n imageUrl={imageUrl}\n classNames={classNames.imagePreview}\n />\n )}\n </>\n )\n}\n","import React, { FC, PropsWithChildren, ReactNode } from 'react'\nimport * as ReactDOM from 'react-dom/client'\nimport {\n IdValidation,\n IdValidationProps,\n} from './components/customer_flows/IdValidation'\nimport {\n FaceValidation,\n FaceValidationProps,\n} from './components/customer_flows/FaceValidation'\nimport {\n IdAndFaceValidation,\n IdAndFaceValidationProps,\n} from './components/customer_flows/IdAndFaceValidation'\nimport {\n CustomerEnrollmentProps,\n CustomerIdAndBiometricsEnrollment,\n} from './components/customer_flows/CustomerIdAndBiometricsEnrollment'\nimport {\n CustomerVerification,\n CustomerVerificationProps,\n} from './components/customer_flows/CustomerVerification'\nimport {\n CustomerIdentification,\n CustomerIdentificationProps,\n} from './components/customer_flows/CustomerIdentification'\nimport {\n SignatureKYC,\n SignatureKYCProps,\n} from './components/customer_flows/SignatureKYC'\nimport {\n VideoIdValidation,\n VideoIdValidationProps,\n} from './components/customer_flows/VideoIdValidation'\nimport { preloadModels } from './lib/models/preloadModels'\nimport { initializeI18n } from './lib/locales'\nimport {\n CustomerBiometricsEnrollment,\n CustomerBiometricsEnrollmentProps,\n} from './components/customer_flows/CustomerBiometricsEnrollment'\nimport { OverlayContainer } from './components/common/overlay'\nimport { webSdkVersion } from './version'\nimport { Theme, themes } from './themes'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from './contexts/SubmissionContext'\nimport {\n DocumentCapture,\n DocumentCaptureProps,\n} from './components/customer_flows/DocumentCapture'\nimport { CapturedDocumentImg } from './components/common/CapturedDocumentImg'\nimport { defaultSubmissionUrl } from './components/submission/SubmissionProvider'\nimport { defaultAuthUrl, allowedAuthUrls } from './contexts/AuthStateContext'\n\ninitializeI18n()\n\ntype TargetElement = Element | DocumentFragment | string | undefined\n\nfunction renderElement(\n component: ReactNode,\n targetElement?: TargetElement,\n): Element | DocumentFragment {\n if (typeof targetElement === 'string') {\n const result = document.querySelector(targetElement)\n if (!result) throw new Error(`targetElement ${targetElement} not found`)\n targetElement = result\n } else if (!targetElement) {\n targetElement = document.createElement('div')\n document.body.append(targetElement)\n }\n\n const root = ReactDOM.createRoot(targetElement)\n root.render(<OverlayContainer>{component}</OverlayContainer>)\n\n if ('remove' in targetElement) {\n const originalRemove = targetElement.remove\n targetElement.remove = () => {\n try {\n root.unmount()\n originalRemove()\n } catch (e) {}\n }\n }\n\n return targetElement\n}\n\nfunction renderComponent<T extends PropsWithChildren>(\n Component: FC<T>,\n targetElement: TargetElement | T,\n options?: T,\n): Element | DocumentFragment {\n if (!options) {\n options = targetElement as T\n targetElement = undefined\n }\n\n return renderElement(\n <Component {...options} />,\n targetElement as TargetElement,\n )\n}\n\nexport const renderIdValidation = (\n optionsOrTargetElement: TargetElement | IdValidationProps,\n options?: IdValidationProps,\n) => renderComponent(IdValidation, optionsOrTargetElement, options)\n\nexport const renderFaceValidation = (\n optionsOrTargetElement: TargetElement | FaceValidationProps,\n options?: FaceValidationProps,\n) => renderComponent(FaceValidation, optionsOrTargetElement, options)\n\nexport const renderIdAndFaceValidation = (\n optionsOrTargetElement: TargetElement | IdAndFaceValidationProps,\n options?: IdAndFaceValidationProps,\n) => renderComponent(IdAndFaceValidation, optionsOrTargetElement, options)\n\nexport const renderCustomerIdAndBiometricsEnrollment = (\n optionsOrTargetElement: TargetElement | CustomerEnrollmentProps,\n options?: CustomerEnrollmentProps,\n) =>\n renderComponent(\n CustomerIdAndBiometricsEnrollment,\n optionsOrTargetElement,\n options,\n )\n\nexport const renderCustomerBiometricsEnrollment = (\n optionsOrTargetElement: TargetElement | CustomerBiometricsEnrollmentProps,\n options?: CustomerBiometricsEnrollmentProps,\n) =>\n renderComponent(CustomerBiometricsEnrollment, optionsOrTargetElement, options)\n\nexport const renderCustomerVerification = (\n optionsOrTargetElement: TargetElement | CustomerVerificationProps,\n options?: CustomerVerificationProps,\n) => renderComponent(CustomerVerification, optionsOrTargetElement, options)\n\nexport const renderCustomerIdentification = (\n optionsOrTargetElement: TargetElement | CustomerIdentificationProps,\n options?: CustomerIdentificationProps,\n) => renderComponent(CustomerIdentification, optionsOrTargetElement, options)\n\nexport const renderSignatureKYC = (\n optionsOrTargetElement: TargetElement | SignatureKYCProps,\n options?: SignatureKYCProps,\n) => renderComponent(SignatureKYC, optionsOrTargetElement, options)\n\nexport const renderVideoIdValidation = (\n optionsOrTargetElement: TargetElement | VideoIdValidationProps,\n options?: VideoIdValidationProps,\n) => renderComponent(VideoIdValidation, optionsOrTargetElement, options)\n\nexport const renderDocumentCapture = (\n optionsOrTargetElement: TargetElement | DocumentCaptureProps,\n options?: DocumentCaptureProps,\n) => renderComponent(DocumentCapture, optionsOrTargetElement, options)\n\nexport type IDmissionSDK = {\n renderIdValidation: typeof renderIdValidation\n renderFaceValidation: typeof renderFaceValidation\n renderIdAndFaceValidation: typeof renderIdAndFaceValidation\n renderCustomerIdAndBiometricsEnrollment: typeof renderCustomerIdAndBiometricsEnrollment\n renderCustomerBiometricsEnrollment: typeof renderCustomerBiometricsEnrollment\n renderCustomerVerification: typeof renderCustomerVerification\n renderCustomerIdentification: typeof renderCustomerIdentification\n renderSignatureKYC: typeof renderSignatureKYC\n renderVideoIdValidation: typeof renderVideoIdValidation\n renderDocumentCapture: typeof renderDocumentCapture\n\n preloadModels: typeof preloadModels\n themes: typeof themes\n version: string\n ready: boolean\n authMode?: 'session'\n allowedAuthUrls?: string[]\n defaultAuthUrl?: string\n defaultSubmissionUrl?: string\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var IDmissionSDK: IDmissionSDK\n}\n\nglobalThis.IDmissionSDK = {\n renderIdValidation,\n renderFaceValidation,\n renderIdAndFaceValidation,\n renderCustomerIdAndBiometricsEnrollment,\n renderCustomerBiometricsEnrollment,\n renderCustomerVerification,\n renderCustomerIdentification,\n renderSignatureKYC,\n renderVideoIdValidation,\n renderDocumentCapture,\n preloadModels,\n themes,\n version: webSdkVersion,\n ready: true,\n authMode: 'session',\n allowedAuthUrls,\n defaultAuthUrl,\n defaultSubmissionUrl,\n}\n\nexport {\n preloadModels,\n themes,\n Theme,\n IdValidation,\n FaceValidation,\n IdAndFaceValidation,\n CustomerIdAndBiometricsEnrollment,\n CustomerBiometricsEnrollment,\n CustomerVerification,\n CustomerIdentification,\n SignatureKYC,\n VideoIdValidation,\n DocumentCapture,\n SubmissionRequest,\n SubmissionResponse,\n CapturedDocumentImg,\n allowedAuthUrls,\n defaultAuthUrl,\n defaultSubmissionUrl,\n}\n"],"names":["useTranslation","__awaiter","useState","global","this","logError","useCallback","useRef","React","templateObject_1","__makeTemplateObject","useTheme","styled","templateObject_2","templateObject_3","__assign","useContext","useMemo","__spreadArray"],"mappings":"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KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,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CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAE,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,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,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACt6D,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CA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AAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACtuB,SAAS,EAAE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EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC;AACtc,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC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AAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAC,C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AAE,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACr4C,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAC;AACjxB,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,GAAG,OAAO,iBAAiB,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;AAC9e,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mKAAmK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,uJAAuJ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,sCAAsC;AAC1iB,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/gB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC1f,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAC,CAAE,IAAI,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;AACtwB,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvM,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,QAAQ,GAAG,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,WAAW,GAAG,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,MAAM,KAAK,CAAC,+DAA+D,CAAC,CAAC;AAC7hB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AACzQ,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,8BAA8B,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,sCAAsC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AACpgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpf,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,OAAO,aAAa,CAAC,MAAM,KAAK,CAAC,+DAA+D,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACtf,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,GAAG,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,iEAAiE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;AAC1Z,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;AAC/e,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;AAC7F,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AACvf,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC;AAC7Q,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC;AAC3a,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,oBAAoB,GAAE,CAAC,CAAC;AAC9c,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,WAAW,GAAG,OAAO,gBAAgB;AACtgB,CAAC,YAAY,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAW,CAAC,KAAI,WAAW,GAAG,OAAO,gBAAgB,EAAE,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACvf,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrf,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;AACrgB,MAAM,QAAQ,MAAM,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjI,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE;AACpgB,CAAC,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO;AAC9f,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7U,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAM,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,YAAY,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACnQ,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,GAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAE,CAAC;AAC5f,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,cAAc,CAAC,+BAA+B,CAAC,cAAc,CAAC,0FAA0F,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACvqB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,cAAc,CAAC,qBAAqB,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,QAAQ,GAAG,OAAO,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,iEAAiE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAClhB,YAAY,GAAG,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,cAAc,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,+CAA+C,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrf,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,+BAA+B,CAAC,8BAA8B,CAAC,CAAC,CAAC,eAAe,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,CAAC,0FAA0F,CAAC,wFAAwF,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAC,CAAC,CAAC;AAC7f,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;AAClf,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACrf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACpf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACrf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACtf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpf,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACpf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACrf,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACtf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,CAACC,cAAI,CAAC;;;;;QChI9R,sDAAO;QACP,YAAM,KAAA,IAAA,OAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,MAAA,QAAG,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,kBAAH,KAAA,IAAA,OAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,MAAA;QACN,sDAAO;QACP;oBACM,KAAA,IAAA,OAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,MAAA,CAAE,wCAAG;;;;;;6CC2BgB;;;;;;;;;;;;;4BAkB7B;;;;;;;;sBAOc,mBAAmB,CAAC;;yBAOjB;;;;;;;;;;;gCAWZ;;;;;;;;;MAkBC;;;;;;;EAGA,IAAA,EAAA;IAAC;;;aAKI;QAEL,6BACE;MAGJ;KAEF,oBAAoB,CACrB;;MAME,wBAAwB;;8BAazB,2CACA,sBAAsB;uBAMtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uDC5HgB,CAAA;;mBAAA;;;;;;6BAYjB;;;;;;;;;;;;;;;;;;GA0BqB;;UACb;IAAK;;;;;;;;WAEG;;;;;;;;uCASf;4BACE,WAAW;;wBAGb,GAAG,CAAC;;;;;;;;;6BA0BY;qBACX,qBAAqB;;gBAC1B,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;sFAlBlB;;+CAES;;;;;;;;4BAOX;;sBAIM;;;;;;;;;;;;;;;;;;;;;;;uBAwCL;4DAE2C,CAAA;;;;;;;;;;;;;;;;;;wCAVxC;;;;;;;;;;;;;oEAuCA;;;;;;;;;;;;;gCAU0B;;4CAG7B;;;;;;;;uEAUW,WAAE;;cAGd;;;;;;;wCAvBI,WAAW;;;;;;;;;;;;;;;;;;;;;;;8BA+CX,UAAU,2BACd;;;qBAQiB,CAAA,OACf,UAAC;;;;;;;;;;;;;;ICrKU;;;;;;;;SA0CsB;;;;;;;;;;;;UAM/B,eAAQ;+DAEwB;+BAIhC;;;;;;;;+CAW8B;;;;;;cAGD;;0BACjB,EAAA,cAAA;;;;;;;;;;;;;;;;;gCAiBkB;;gCAIhC;;yCACgB;;;;;;;;;;;WAsDMF;;;;;;;;;;MAmBpB,uBAAmB;;yBAIF,0CACZ;MACJ;;cAKH;KACC,qBAAmB;;KACiC,CACpD;;;;MAUD;MACA,mGAGC;;KAIH;2BAGW;;GAEV,EAED,WAAa;;;IAIM;;;;;;;;;;;;;;qBA8DV,SAAS;mBAAc,IAAI,UAAU,EAAE,GAAG;kBACvC,QAAQ,MAAM;mBAAoB,eAAe;;;;;;QAE7D;QACAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1UI,SAAU,YAAY;MAIpB,EAAA,GAAA,EAAA,CAAA;IAAA;qBAAQ;qCAAA,GAAA,EAAA;EAER,IAAA,EAAA;;IAAU,UAAS,GAAA,EAAA,CAAA,CAAA;YAGvB,eAAS;MACP;uCAGmB,GAAA;;;;;;;;;;;;;;kCAIjB;;;;;;;;;;;MAMF;;;MAQD;IAGH;QACE;MAGI,IAAI,GAAGC,iBAAW,CAAC,YAAA;sBACT;;KAEf,EAAE;;;;MAOC;KAEF;;;;;;;;;;ICoEwB,OAAA;;uBACT;IAAQ,OAAA;;;;+BAKR;sBAC2C,SAAA,qBAAA;;;kBACpD;;;IAKC,OAAA;;;;;;eAMsC;;;;;;aAS3C,GAAA,EAAA,KAAA,KAAA,CAAA;;;;;;;;;;;;;;MAcA,oBAAoB,GAAGC;4BACHA,YAAM;WAE5BL;IADG;;EAKC,IAAA,EAAA;;oBAAgC,GAAA,EAAA,CAAA,CAAA;EACpC,IAAA,EAAA;;mBAA8B,GAAA,EAAA,CAAA,CAAA;;IAC3B;;MAEC;EAEJ,IAAA,EAAA,GACF;;;;;;;IADc;yBAAa,GAAA,EAAA,CAAA,qBAAA;IAAL;;EAUlB,IAAA,EAAA,GAAkB;;;;;;;cAGlB,qCAIF;;mCAQ6B;;;;iBASY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC8DxC,6DAA4C;;;IAIpC,OAAA;;QACP,SAAA,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA6CL,GAAA,EAAA,CAAA,qCAAA;IAGC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+DC7TQ;;;gBCqBM;4BAGU;;WACjB,2BAA2B,CAAC;;;;;;;;;;;;;qBCuS3B;;;YAKJ;;;;oBAKM;oBACF;;;;YAOJ;gBAEE;;gBAII;;;gBAMF;;;;+BA8CiB;4BAC2C;qCACnC;;;;;;;;;;;;6BAsBhB;wBACP;;iBAGH;;;;;;;gBAwBD;;mBAIK;;;;;;;;4EA2HuC;IAE3C;iCAMR;;;IASC;;;;;YAEM;;;;+CAKJ;YAEC;UACC;gBAAU;;;;iCAWiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MCnmBzB;MAGF;;qDAI2B;AAajC;8jBAmB4D,CAAA,CAAA,CAAA,CAAA;;;;;0TAqDb,4CAAhC;;EAAe,OAAA,mBAAA,oBAAA,gBAAiB;AAAjB,CAAiB;;;;;;;IAIxC,kdAQU;;;aAEX;;;;;;;+BA4CC;;;;;cAkBE,GAAA,EAAA,CAAA,UAAA;eACC,GAAA,EAAA,CAAA,WAAA;;;;;aAYD,GAAG,CAAC;iBACA;IAGX;;MAgBI;QACJ,cAAI;QAMF,UAAU;;QAWkD;QAE1D;;;IAKJ;;eAES,EAAA,SAAA;gBACC,EAAA,UAAA;;;;;;aAKH,EAAA;;KAEN;;IAUS,mCAAA;;;;EAuCH,IAAA,EAAA,oBACQ,EAAE,CAAA,CAAA;;;;;sBAIjBM,yBAAA,CAAA,aAAA;MACI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5SN,oBAAe,EAAE;;ACAjB,oBAAe;+CAIb;;;;yBAKqB;;;;wCAWrB;8PAIA;4CAGA;0QAGA;0CAEA;oQAGA;;;;;;;;;;wCAyBA;wDAIA;sCAGA;;;;;;8DAeA;QAGI,EAAE;;iDAON;;;qCASA;sCAEA;;;;uEASA;6DAIA;;8CAOA;;sCAIA;;;;;;+BAoBA;;;qDAQA,iCAAiC;EAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC7IK;;;IACJ;IAAI;;;;8BAKA,0CACA,8BAAiB;;IAGjB;;;;IAGA,KAAO;;mBACC;;;;;;kBAKR,YAAA;;;;yBAcmB,EACG,CAAA;;;;;;kCAsDP;;;;;;;;;;;;;;;;;;;;;;;;;;;;6DC7FW,GAAI,CAAAC,kBAAA,KAAAA,kBAAA,GAAAC,0BAAA,CAAA,CAAA,uCAAA,EAAA,QAAA,EAAA,4DAAA,CAAA,EAAA,kDAalC;;;GAAA;;;;AAQK;EAmBN;;;;;;;;;;;;;;ACnDM;;ICyOA,qBAAA;;;;yCACQ;sCACgB;8BAAX,GAAA,EAAA,KAAA,KAAA,CAAA,GAAG,QAAQ,GAAA,EAAA;;;;iDAEJ;;;;;;6BAEN,GAAA,EAAA,KAAA,KAAA,CAAA;;;;;;;;qBASN,GAAA,EAAA,CAAA,iBAAA;;;;;;;;;;;;;;OASR,GAAA,EAAA,CAAA,GAAA;;;;;;;;;EAGH,IAAA,EAAA;;;oBAGY,GAAA,EAAA,CAAA,gBAAA;iBACH,GAAA,EAAA,CAAA,aAAA;;;;IAOX;UACM;aAEK;;;QAML;;;;;IAYN;;;;;;;;;QAQI;UAAY,MAAM;;;;;;IAetB;;YAQQ;;;;;YA2BC;;;iBAEwB,OAAO;;;;gBAAU;;oBAErC,CACJ,UAAC;;;;;;;kBAIK,KAAA,IAAA,gBAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,eAAA;;;;kBAIN,YAAA;sBAEU;;YACM;;oBACN,YAAY;;;;YAEb;;;;;;;;gBAML,uBAAA;;;;;;;sCAIsB,SAAS;0BAGrB;;;;;oBAEN;;kBACA,MAAM;;;;;IAevB;MAAW,IAAI;MAAmB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7YpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACDA;;;gCCmBG;MAON,QAAU;;;uCAWJ;;;;;6BAKD;;;;;;;yBAiBC;oBAAW;;;;;;;cA6BXC;;;;;;;cAkDA;;;;;YAiDA;;;;;YAsCA;sDAKK,SACD;gBAMF;YAUF;;;;GAmBC;;QAcD;;;;;MAe0B,UAAtB;;;IAGJ,CAAC;IACL;SACM;;;;OAOI;SACG;YAGE,SACjB;;;;IAgBK;kBAEDH,yBAAA,CAAA,aAAA,CAAA,MAAA,EAAA;;;;OA6BE;;;OAgBA;;;OAgBA;;mBAuBFA,yBAAA,CAAA,aAAA,CAAA,MAAA,EAAA;;;mBAoCAA,yBAAA,CAAA,aAAA,CAAA,MAAA,EAAA;;;;OAiBE;;;;;;OAkCA;;;OAgBA;;;;IAcF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCjeJ,GAAA,EAAA,KAAA,KAAA,CAAA;;;;UAEA,GAAA,EAAA,KAAA,KAAA,CAAA;;;EAIA,IAAA,EAAA;;;8CAS4B;eALrB,GAAA,EAAA,CAAA,WAAA;;;;EAOH,IAAA,EAAA;;gBAAyC,GAAA,EAAA,CAAA,CAAA;QAEhC,+BAAA;MAEb,QACE;;IASJ;IACA,eAAe,EAAE;;;;;;IAQjB;kBAGM,YAAA;oCACG;;;;;;;;;;cA2DD;;wBAMI;;;4BAYM;;;;;gBAiBV;;4IASmB;4CAGH;;IAoBpB,aAAa;iBAAa,uBAAA,CAAA,MAAA;;;;;;;;;yBAsCG;;IAwB/B;KAEG;;;MAqBc;;gFAmCmB;;;OAUpC;;;;aAcW;oBAqBQ;IAKf,qBAAc;;yBAGb,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IC9UN;IAKO,yCAAA;;;gBAED,GAAA,EAAA,CAAA,YAAA;;;;;UAIN,GAAA,EAAA,KAAA,KAAA,CAAA;;;;UAGI,GAAA,EAAA,KAAA,KAAA,CAAA;;;EAGF,IAAA,EAAA;eAAoB,GAAA,EAAA,CAAA,KAAA;;EAWpB,IAAA,EAAA;IACJ;;;;;;;QAUI,oBAAC,WAAD,oBAAC;;;0DAekB;;;;;;kBAkCjB,YAAA;;;;;kBAYM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ICpJU,+BAAA;;;;0CAUc;OADhC,GAAA,EAAA,CAAA,CAAA,CAAA;kBACgC;EAKlC,IAAA,EAAA;IAAC,OAAM,GAAA,EAAA,CAAA,CAAA,CAAA;;;gCAIG;;0BASI;;;oCAGS,QAAQ,aAAc,CAAC;;;EAWjD;;;;;;;;;;;;;;;;;;;;;;;;;;;yBCsBiCI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzE3B;;;EAUD,IAAA,EAAA;;;IAA8B;;wDAGE,GAAA;;;WAM3B,YAAA;MAEL;KAEF;;kBAQA;kBAIgB;KAElB,CAAC;iBAeU;;;;;;;;;;;;;;;;;;;;;;;;ACtDP,SAAU,oBAAoB;EAApC,IAAA,KAAA,GAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACFM,SAAU,mBAAmB;;;;iBASpB,KAAK,GAAG;;4BAGH;;yBAIH,CAAC;;SAGJ;;;;;;;;;;;;;;;;;;;;;;0BC6BLA;AA4BF,mBAAuB,GAAGA,0BAAM,CAAC,GAAG,CAAAC,kBAAA,KAAAA,kBAAA,GAAAH,0BAAA,CAAA,CAAA,wFAAA,CAAA,EAAA,CAAA;+CAgGP,IAAI,CAAAI,kBAAA,KAAAA,kBAAA,GAAAJ,0BAAA,CAAA,CAAA,2NAAA,CAAA,EAAA,CAAA;IAgBjB;;0BAgBhB,CAAC,6CAEN,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,gNAEA;;;2OAGgD;;;;eAEhC,aAAa,cAAA,CAAA,MAAA,OAAqB;;uCAS7C;mDAyBM,iNAuCP;;GAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBC5KqB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;SAmItB,uCAAA;EAAS,wCAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IC5JP,6BAAA,oBAmBU,EAAA;;;;;;;;;;;;;cALT,GAAA,EAAA,CAAA,UAAA;;;kBAEI,GAAA,EAAA,KAAA,KAAA,CAAA;;cAEN,GAAA,EAAA,KAAA,KAAA,CAAA;;cAE0C;;;IAAjB,gBAAgB,GAAA,EAAA,CAAA,gBAAA;;eAClC;kDAQ0B;;;;;oCAFf,MAEe;;sEAIpB,iHAAiC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA;;WAI7C,aAAY,GACf,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,+JACA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA;;;eAKK;;;uCAOQ;;iBAIV,CAAC,YAAA;;QAGJ;QAIA,SAAS;mCACgB;;gBAErB;;;;;;;QAMF;IAEF,IAAA,EAAA,+DAGW;;;;;QAIX;;;;QAOE;+CAKe;;;;;;;IAyCf,IAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBC9KY;;;;;;;kBAIX,GAAA,EAAA,KAAA,KAAA,CAAA,GAAG;;;;;;UAIb,GAAA,EAAA,KAAA,KAAA,CAAA;;UAEE,GAAA,EAAA,KAAA,KAAA,CAAA;oBAEkB;oCAAA,GAAA,EAAA;;;cA0CZ;qBACG,sBAAC;;iBAKH;;yBAQQ;yBACA,sDAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBC5ElB;cADG,GAAA,EAAA,KAAA,KAAA,CAAA,KACH,GAAA,EAAA;;;;EAmCN,IAAA,EAAA,iBAAU;;aAAK,GAAA,EAAA,CAAA,CAAA;EAIT,IAAA,EAAA;;;;IAIN,kCACmB;;kBAGP;;;IAKZ;;;0BAiBK;;;;;IAqBqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCCgDH;;sBAGT;;aAET;;;;;;;wBAQa;mBAAQ,OAAO;;;;qFAuDN;oFAWN,EAAA;;;;;;;;mBAOR;6DAEe;;;QAK1B;;QAEA;QACA;QACA;QACA;;IAIF;oDAEQ,CAAA,EAAA;mBACG;gBACL;gBACA;;;;;;;;;;;;;;;YAcF;;;;;;;eAMG;;;;0CAGe,MAAoB;YACtC,KAAK;;kCACiB;uBACb;;;;;YAMP;2BACa,kBAAkB,gBAAgB;;;;;oBAMzC,GAAAK,cAAA,CAAA,EAAA,QAAe;;2BAGd;6CACW;;;;;eAIf;0GACgC,CAAC,SAAS,CAAA;;;;IAWnD;;0CAEK;;QAOD;eAIO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECvST,IAAA,EAAA;;;;;IAIE;;IAFG;IAAK;;cAWJJ;sFAEqB,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,mDAAY;;2KAGG,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAA,0BAC3C;;kBAKG,YAAA;cACE;;QAGR;2BACmB;;QAGnB;cAAe;;;;;;mDAQ+B;IAG9C,IAAA,EAAA;;;;;mCAUyB;UACvB,WAAW;;;QAIb;QACA;;QAEA;QACA,SAAS;;;;IAOX;QAMI;IAKA,aAAa,GAAG;IAMhB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBC7BjB;oCAAA,GAAA,EAAA;;;;;;;;;;;;YAqCI,GAAA,EAAA,CAAA,CAAA;;;;;;;;;+CAsEsB;;;IADA;gDACA;;yBAUE,GAAA,EAAA,CAAA,CAAA,CAAA;;;;EAgB1B,gBAAgB;;EAIhB;;EAUA,sBAAsB;;EAMtB,+EAA0B,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClR1B,SAAU,YAAY,GAAA;EACpB,IAAA,EAAA;QAAkB,GAAA,EAAA,CAAA,CAAA,CAAA;;uDAIG,EAAA;;yBAEjB,CAAC;;;;IAUL,iBAAwB,EAAA;;;;EAK5B,IAAA,EAAA;OAAM,GAAA,EAAA,CAAA,CAAA,CAAA;;;QAGN,OAAO;;QAEN;IACH;;;IAEA,OAAO;WACF,YAAA;MACJ;;MAGG;;IAOI;;;;;;;;;;;;;;;;2BAmBS;;;;;;6BAMP;;kBAGe,cAAe;;iBAK/B;;;;;;;;iBAeF,CAAC;4BAIN;;UACA;;aAEA,aACE;;UAGF;;;;;;;;;;;;;;;;;;;;;qDC2CiB,EAAA;;;;;;cAJb,GAAA,EAAA,KAAA,KAAA,CAAA;;;oBAEgB;oCAAA,GAAA,EAAA;0BACJ;0CAAA,GAAA,EAAA;;MAIZ,wBACJ;EACE,IAAA,EAAA;IAAC;;EACD,IAAA,EAAA;IAAC;IAAmB;EAIpB,IAAA,EAAA;;;MACF,oBAAoB;MACpB,qBAAqB;;;;EAGjB,IAAA;;;;;mBAME,GAAA,EAAA,CAAA,CAAA;+CAGW,wHASjB;4JAc0C;uDA+BzB;6GAUF;;6CAKc;;wBAEf,EAAA,oBAAA;;;6BAcD;6DAUU;IAQrB,WAAW;IAIX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCCmFiB;;;;;;;;;;;;;;iDAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAgBrBK,gBAAU,mBAAY,CAAC;;iDAAA;EAEnB,IAAA,GAAA;;;EACF,IAAA,GAAA;;IAaF;;;4BAcyB,GAAA,GAAA,CAAA,wBAAA;;EAmCpB,IAAA,GAAA;IAAC;;;;;;6BAoBoB;;0BAWG,EAAA,kBAAA;;;;;MAUxB,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IC9Zb,OAAA;;;;;;IAEW,OAAA;;;;;;;;;;;;;;;;;;;IA2BpB;;;MAEA,yBACG;MACL;EAEA,IAAA,EAAA;;;;;IAAK;;;EAGL,IAAA,EAAA;;;;;UAEA,oBAMA,gBACC;;;;;;;;;;;;;;;;;;;;;;;;;;SATM,GAAA,EAAA,CAAA,KAAA;;;;;;;;;;;;;;;;;;;;;;;+CC7G6B,6CAIlB;;;;EAGpB,IAAA,EAAA;YAAW,GAAA,EAAA,CAAA,CAAA,CAAA;eAAa,GAAA,EAAA,CAAA,CAAA;;;;;;;IAO1B,YAAc;;;;;;;kBAUV,YAAA;QACF,CAAC,QAAQ;QAET;;;;;;;;;;;;;;;;;IC+EK,iCAAA;;;;cAID,GAAA,EAAA,KAAA,KAAA,CAAA;;UACF,GAAA,EAAA,KAAA,KAAA,CAAA;;eAEc,GAAA,EAAA,KAAA,KAAA,CAAA;;;;;2BAIF;sCAAT,SAAS,GAAA,EAAA;EACd,IAAA,EAAA,GAAmBd;;IAAX;MACR,kBAAkB,GAAEK;;EAIpB,IAAA,EAAA;;cAAoB,GAAA,EAAA,CAAA,CAAA;EACpB,IAAA,EAAA,kBAA2D;IAA1D,oBAAoB,GAAA,EAAA,CAAA,CAAA,CAAA;;;;;;;;;;iDAYuB;;cAEtC;;sEAEE;;;MAMT;MAKG;;;oBAkBU;;;wBAUE;;;;;;;;;;;;iCA4BC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA;;sCAMN;;;;;kCAUS,CAAC;;;;;;;wBAUP;;+DAKY,cAEC,CACA;;IAMvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBCjGE;;;;;;;;qBAYS;;aAEV;;;EAeN;wBA4CyB;;;gBAyBlB;;;;;;IASN;;;gBAIM,OAAO;;;IAKP;;QAIJ,SAAS;;;;SAKR;;;QAID;qBACW;;IAEb;;QAEU,IAAA;;;;sBAGJ;;;4BAGM,KAAK,CAAC;;;;oBAKN;oBAON;oBACA;;;cAEF,GAAE;UACF,UAAY,oBAAoB;UAE9B,cACJ,iBAAiB;UAKjB,gBAAkB;UAClB;sCAEY;;;UAOR;UAEJ;UACA,kBAAoB;UACpB,uBAAuB;UACvB,iDAAiD;;wBAIP;YAGxC;UACF;yBACa;eACV;4BACW;;;;UAOZ,eAAe,EAAA,eAAA;UACjB;;;UAKE;UAEA;UAKC,eAAe,EAAA;SAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBChPd;gBACI;YAEN,IAAI;YACJ;;;;;;;;;;iCAiFS;;gBACD,CAAC;IACX;;6BAIa;yBACM,CAAC,2BAA2B,CAAA;UAC3C,OAAAQ,cAAA,CAAAA,cAAA,CAAA,EAAA,EACG;;yBAEU,QAAQ,CAAC;;;;;;;;;oBAIH;OAAe,CAAA;;;+BAQ1B;;oBAAW,GAAA,EAAA,CAAA,UAAA;;;;kCAGX;;;;;;4CAMY,EAAE;;;;;+BAQC;;;;;;;;;;4BAMjB,QAAQ;;sBAEd,EAAA,YAAA;;;sBAGA,EAAA,YAAA;8BACM,EAAA,oBAAA;;;;;;;sBAOJ;;;;;;;;;;;;UA8EH,GAAA,EAAA,CAAA,MAAA;IASN,EAAA,GAAA,EAAA,CAAA;IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCCrU6C,6CAAA;;;;UAG1C,GAAA,EAAA,KAAA,KAAA,CAAA;;;;UAEA,GAAA,EAAA,KAAA,KAAA,CAAA;;eACe,GAAA,EAAA,KAAA,KAAA,CAAA;WAIXC;;;;EACF,IAAA,EAAA;IAAS;;;MAcX,QACE;;IASJ;kEAEwC;;4BAGjB;;yBAQL;;;;gBAKX,GAAA,EAAA,CAAA,CAAA;;;;;kBAqBK,UAAU,CAAC;oBACT;;;;4BAYc;IAOxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCrHE,GAAA,EAAA,KAAA,KAAA,CAAA;;EASJ,IAAA,EAAA;IAAC;;;IAIH;;;;;;;;;cAwCQL;;;;;;;;uBAkDY;;;;;;;;;;;;;;;;;;GAoEC;;;;;;;;;;;;;;IAqGf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1QR,IAAM;IASF,8CAAA;iBACoD,GAAA,EAAA,CAAA,WAAA;;;UAKpD,GAAA,EAAA,KAAA,KAAA,CAAA;;;;UAEA,GAAA,EAAA,KAAA,KAAA,CAAA;;;EAGA,IAAA,EAAA;;;;EAEA,IAAA,EAAA;;;MAKI,WAAW;iBACN;;;;IAKX;;;;IAIA;IAEM;EACS,IAAA,EAAA;;;MAEX,sEAWJ;iBAWO,CACL,YAAA;;qCAEqB,EAAA;;;YAOjB;;;;;;;;cA8BE;kBACE;;2BAOO,CAAC;;;;6FAiBT,EAAA;;;;;;;;;;;;;;oBAkELH,yBAAA,CAAA,aAAA,CAAC;;;;iBAgB6B,CAMV;;gFA0Cc;;;OAUpC;;;;eA6BmC;;eAEG;;;;;;;;MAYtC,eAEIA,yBAAA,CAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BCrBE;;;kBAZE,GAAA,EAAA,CAAA,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ICzRN,oCAAA;;;;;;EASE,IAAA,EAAA;;;EACA,IAAA,EAAA;cACO,GAAA,EAAA,CAAA,GAAA;;;;;MAKX;MAEA,aAAa,qBAAA;;IAGf;;;;;;;;;;;;;;;;;;IClCE,6BAAA;EACI,IAAA,EAAA,GACAQ;qBADsD,GAAA,EAAA,CAAA,iBAAA;;EAGtD,IAAA,EAAA;;IAAkB;;;;MAEtB,kBAAkB;;oBACZ,MAAA,IAAI;;uEAKJ,YAAA,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,wFACe,0CAIf,yBAKL;6HACqB,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,cAC1B,iBAAiB,mBAAkB;uEAQ/B,mHAAmC,MACrC,CAAC,8DAEe,CAAC;;sCAQO,CAAC;;;IAkB3B,SAAS,SAAA,UAAA;0BACa;;;;;;;;;;;;;;;;;;;cCuBpB,GAAA,EAAA,CAAA,UAAA;;;;;kBAIST,kBACN;0BAMI;;;;;6BA2BQ;;IASjB;yBAQqB,CAAC;;IAItB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BCzGK;0BAIT,GAAG;;gCAAA;MAEC;MAAY;;kBAWZ,YAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MClCF;mBAEW;mBACF,EAAE;iBACJ;;;;;wBAOW;;;;;;;;;;;;;;;;ACnCf,uUAWC;;0HADC,CAAA,EAAA,GAAA,MAAM,mFACT,EAAE;CAAA,iBACA,EAAA;;;kBAGA,EAAA;;qBACD,CAAC;;+BAqBOK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MC3BP,aAAkC,qBAAZ;MACtB,aAAkC,qBAAZ;MACtB,cAAmDL,YAAM;MACzD,cAAmDA,YAAM;EAEzD,IAAA,EAAA;;eAAC,GAAA,EAAA,CAAA,CAAA;EACD,IAAA,EAAA;;eAAC,GAAA,EAAA,CAAA,CAAA;EACD,IAAA,EAAA,uBAC8B;;IAElB;EACZ,IAAA,EAAA,uBAC8B;;IAElB;;;;EAGhB,IAAA,EAAA;;;0BAGO;sCAFa,GAAA,EAAA,CAAA,CAAA,CAAA;;EAGlB,IAAA,EAAA,uBAIU;IAFd;;MAIE;;QACA;IACF;IAEA,mCAAiC,KAAA,IAAA,eAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,cAAA;;gFACJ;;iBAGhB,WAAW;;;uBACP;mCACW;;IAE5B,mBAAA,6BAAA,cAAe,EAAE;;MAIf;;iBAAwB;;;;6CAKa,CAAC;6BAEjB;;;MAKrB,sBAAsBD;sBACR,cAAc;QAC5B,CAAC;;;6BAMoB,MAAM;;iBAGrB;;;;IAKR,qBAAoB;8BAEQ;;;;;gCAMF;;;;WAKtB;;;UAID;qBAEY,CAAC;MAEd;QAEA,cAAc;IAChB,IAAI;;;;;IAOJ;0BAEwB;;;kBAGpB,aAAa,CAAC;;IAIlB;;;IAIA;;wBAIkB;;;IAElB,IAAI,CAAA,CAAA,EAAA,GAAA;;;QAIF;MAEA;;8CACkB;QAClB,CAAA,CAAA,EAAA,GAAA;;;QAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8CCTyC;;;gDACf;;;UAAtB,GAAA,EAAA,CAAA;;;;;EAGF,IAAA,EAAA,oBAMe,iBAAiB;IAJpC;;;;EAMM,IAAA,EAAA;iBAAc,GAAA,EAAA,CAAA,CAAA,CAAA;;;;;8BAElB;;;;;MASI,2BAA2B;yBAE7B;;;;MAIF,YAAY,eAAS;MAErB,4BAAwB,CAAC;kBACf,YAAA;QAEV,cAAc;;;;;;;;;8CACP;4BACH;;;iCAI6C;;;;;;;;;mCAUlC,yBAA0B;+BACpC,CAAC;oCACI;;;;;;gBAOV;;;eAGC;;gBAID,eAAiB;;;;;;;;;KAGlB,GAAG;;kBAIA,YAAA;;;;;;kBAOI,YAAA;;6BAEa;iDAuBI,cAAc;;MAAjC;;;oDAkBW,aADC;iBAYJ;;;;kDAWU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2DC/BV,EAAA;;;;;;;;;;;;;;;;;;;;;;;qBAaH,GAAA,EAAA,CAAA,iBAAA;kBACD,GAAA,EAAA,CAAA,cAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uEC9Ne,EAAA;;;;;uBAFd;mCAAA,GAAA,EAAA;;;eAIA,iDAAA;;qBAGC,wBAAA;MAGV,gFAAmC;EAGnC,IAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UC6CE,GAAA,EAAA,KAAA,KAAA,CAAA;;;;IAOE;;;0BAqCS,EAAC;;IAFC,qBAED;;;;sBAaM,yBAAA;gDAUI,EAAA,CAAA,MAAA;4CAmBoB;;IAiB1C;IASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBC5HW;sCAAA,GAAA,EAAA;;;;;oBASV;oCAAA,GAAA,EAAA;;yCAUqB;0BAatB;;;iCAgBG;uDACmB;;GAExB;;QAEE,mBAAY;UACR;;;+BAEN;SACE;;;iBAWK;IACP;;MAGA,OAAA;WACI;;kBAGJ;;;;;;2BAMM;;mCAG6B,CAAC;;;MAUlC;;;;;;;cAOF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBCsGiE,GAAA,EAAA,CAAA,qBAAA;;;;;;;;;;;;qDAStC;;;;4BACT,GAAA,EAAA,KAAA,KAAA,CAAA;;iCACG,GAAA,EAAA,KAAA,KAAA,CAAA;;;;;kBAIf,GAAA,EAAA,CAAA,cAAA;qCACiB;qDAAA,GAAA,EAAA;;;;;;;;;;;;;;UAOvB,GAAA,GAAA,KAAA,KAAA,CAAA;;mCACkB;;;EAId,IAAA,GAAA;;;6BAEJ;;;;;YAG2B,GAAA,GAAA,CAAA,QAAA;IAC7B;IAEA;;;IAKA;IACA;EACE,IAAA,GAAA;;IAAkB;;;;;;;;;;;IAUpB;gBACsB,GAAA,GAAA,CAAA;EAEpB,IAAA,GAAA;;;EACA,IAAA,GAAA;;;EAEA,IAAA,GAAA;;;EAGI,IAAA,GAAA,6BAawB,CAAC;IAZ/B;IACA;IACA,mBACE,GAAA,GAAA,CAAA,mBAAA;;;;wCAI8B,GAAA,GAAA,CAAA,oCAAA;YAC5B,GAAA,GAAA,CAAA,QAAA;IAEE;MAGA;;;;;;;;;;;kBAKJ,IAAI,CAAC;sBACH,UAAU;;qBAEX;;;;;;;;;;;;;;;;;6BA0CU,8CACc;;;;;;;iBAWhB;MACT,QAEI;cAOI;;;;;;;;;;;EA+BR,IAAA,GAAA;;;;;;MACA,4DAMA;MAEA;;QAEA,uBAAuB;;;;MAIvB;yDAU0B;;;;aAErB;;;;8BAMP,+BAEA;;;;;QAUE;;MAGA,qCACgB,mBACjB,8CAEa,QAAQ,EAAE;MAIpB;MACA;;QACA,cAAc,EAAE;MAChB;2BAEqB;qCAEvB,WAAW;0BAEC,eAAS;;MAErB;;MAQF,oBAAsB,2FAMtB;mBAsBe,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAQ,4DAAoB,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA;oBAC3B,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,qEAA6B,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA;4EAIvB,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA;kBACR,WAIL,wHAaO,oEAGH;0BAmBQ;;;oCAaQ,CACnB;;;;;;;iCACsB;;;;;wBACnB;+BAEF;;;;;;;;;;;;;;;;;;;;;;;;iBAcH,oBAAA,OAAA,CAAA,CAAA,YAAA,CAAA,CAAA;;;;mDAOW;;;;;;;;;;;;;gBAiDF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BCnfM,oCAAA;;;0BAE6C;uCAAA,GAAA,EAAA;;;kCAEtC,GAAA,EAAA,CAAA,8BAAA;;;sCAEH;mDAAA,GAAA,EAAA;;;;;;;;;;;EAcrB,IAAA,EAAA,GAKNU;;;;;EACE,IAAA,EAAA;;iBAA0B,GAAA,EAAA,CAAA,CAAA;eACnBC;;cACH,GAAAC,mBAAA,CAAA,EAAA,EAAO;;YAMT;;;;;;YAWI,MAAM;;wCAGP,+BAME;;sPAU4B;;;;;MAoDnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EC6Ca;WAEJ,SAAS;WACb,EAAE;;;IAOT;YACM,SAAS;;sBACC;;WAGT;;MAGH,KAAO;;aAOA;sBACS;aAEX;;;YAGL,SAAW;;;aAMV;;;WAIE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBCrRI;;;;;;YA4D+B;yBAEvB,eAAe,CAC9B;UAKF,OAAAH,cAAA,CAAAA,cAAA,CAAA,EAAA;;YAIE;gBACM;WAAqB,CAAA;eAGxB;;;;;;iCAGQ;wBACkB;;;;;;;;;;;;0BAQ3B;8BACE,MAAM,EAAA,CAAA,MAAA;;;;;;;;SAKX;UACD;2BACiB;;;;;;;;;;;;;sBAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aCtHX;YACH;;;;EASL;;WA2DQ,mBAAA,QAAkB;;;;4BAQH,CAAC;yBAEN,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAI;;;;;;;;;;;;;wBAUzB;;;;;;oBAKJ,GAAA,EAAA,CAAA,UAAA;;;;;;;;;;;;;;UAUN;;UAEA;UACA;eACK;UACL,eAAe;;;;;;;;;sBAQC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnIpB;AAcE;MAYI;wCAKsC;gCAKV;;;;IA2ChC;;;;;IAOA;IACA,uBAAuB,YAAA;;;;;;;;;AAYzB,SACE,eACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"sdk2.cjs.development.js","sources":["../src/version.ts","../src/lib/utils/platform.ts","../src/lib/utils/dataUrlToBase64.ts","../src/contexts/SubmissionContext.ts","../src/components/common/Page.tsx","../src/components/common/overlay.tsx","../src/components/common/LoaderButton.tsx","../src/components/submission/GeolocationAccessDeniedOverlay.tsx","../src/components/submission/Errors.ts","../src/components/submission/SubmissionErrorOverlay.tsx","../src/components/submission/SessionIdMissingOverlay.tsx","../src/components/submission/SessionValidationFailedOverlay.tsx","../src/components/submission/AuthUrlNotAllowedOverlay.tsx","../src/components/submission/SessionValidationErrorOverlay.tsx","../src/components/common/spinner.tsx","../src/contexts/AuthStateContext.tsx","../src/lib/utils/logger.ts","../src/components/submission/SubmissionProvider.tsx","../src/lib/barcode/Scan.ts","../src/lib/utils/getFrameDimensions.ts","../src/components/common/InvisibleCanvas.tsx","../src/lib/camera/Camera.ts","../src/components/camera/CameraProvider.tsx","../src/lib/models/VisionRuntime.ts","../src/lib/utils/isMobile.ts","../src/lib/utils/cropping.ts","../src/lib/models/CapabilityProbing.ts","../src/lib/models/helpers.ts","../src/lib/models/Focus.ts","../node_modules/@mediapipe/face_detection/face_detection.js","../src/lib/models/FaceDetection.ts","../src/lib/models/preloadModels.ts","../src/lib/models/DocumentDetection.ts","../src/lib/models/FrameLoop.ts","../src/components/id_capture/DocumentDetectionModelProvider.tsx","../src/components/id_capture/IdCaptureModelsProvider.tsx","../src/components/id_capture/CapturedDocuments.ts","../src/components/id_capture/IdCaptureRequirementOption.ts","../src/components/id_capture/IdCaptureStateProvider.tsx","../src/components/common/debug.tsx","../src/lib/locales/en/translation.js","../src/lib/locales/es/translation.js","../src/lib/locales/index.ts","../src/components/common/GuidanceMessage.tsx","../src/components/common/cdn.ts","../src/components/id_capture/IdCapture.tsx","../src/components/common/ExitCaptureButton.tsx","../src/components/common/ButtonsRow.tsx","../src/components/id_capture/IdCaptureLoadingGraphic.tsx","../src/components/id_capture/IdCaptureLoadingOverlayDefault.tsx","../src/components/id_capture/IdCaptureLoadingOverlayLegacy.tsx","../src/components/common/CapturedDocumentImg.tsx","../src/components/id_capture/IdCaptureSuccess.tsx","../src/components/camera/CameraVideoTag.tsx","../src/components/common/useShowSuccessScreen.ts","../src/lib/utils/canvas.ts","../src/components/id_capture/IdCaptureGuideOverlay.tsx","../src/components/id_capture/FlipIdPrompt.tsx","../src/components/id_capture/IdCaptureFitGuide.tsx","../src/components/id_capture/IdCaptureGuides.tsx","../src/components/common/SelfieProgressPreview.tsx","../src/components/document_capture/DocumentCaptureStateProvider.tsx","../src/components/document_capture/DocumentCaptureGuideOverlay.tsx","../src/components/document_capture/DocumentCaptureScreen.tsx","../src/lib/utils/resizeFile.tsx","../src/components/fallback_flows/IdCapture.tsx","../src/components/id_capture/IdCaptureWizard.tsx","../src/components/selfie_capture/SelfieGuidanceModelsProvider.tsx","../src/lib/utils/useTimeout.ts","../src/components/fallback_flows/SelfieCapture.tsx","../src/components/selfie_capture/SelfieCapture.tsx","../src/components/face_liveness/FaceLivenessCapture.tsx","../src/components/selfie_capture/SelfieCaptureLoadingOverlayLegacy.tsx","../src/components/selfie_capture/SelfieCaptureLoadingGraphic.tsx","../src/components/selfie_capture/SelfieCaptureLoadingOverlayDefault.tsx","../src/components/face_liveness/FaceLivenessWizard.tsx","../src/components/GuideOrientationProvider.tsx","../src/components/submission/SubmissionSuccess.tsx","../src/components/additional_document_capture/AdditionalDocumentCapture.tsx","../src/components/additional_document_capture/AdditionalDocumentCaptureWizard.tsx","../src/components/signature_capture/data.ts","../src/components/common/signature.tsx","../src/lib/camera/useVideoRecorder.ts","../src/components/video_signature_capture/VideoSignatureCapture.tsx","../src/components/video_signature_capture/VideoSignatureWizard.tsx","../src/components/video_id/IdVideoCaptureFlipIdPrompt.tsx","../src/components/video_id/IdVideoCaptureGuides.tsx","../src/components/read_text_prompt/ReadTextPrompt.tsx","../src/components/video_id/IdVideoCapture.tsx","../src/components/CompositeWizard.tsx","../src/themes/index.tsx","../src/components/customer_verification/CustomerVerificationCapture.tsx","../src/components/customer_identification/CustomerIdentificationCapture.tsx","../src/index.tsx"],"sourcesContent":["export const webSdkVersion = '2.0.3';\n","'use client'\n\nimport platform from 'platform'\n\nexport type Platform = typeof platform\n\nexport function getPlatform(): Platform | undefined {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (typeof window !== 'undefined' && typeof window.platform !== 'undefined')\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return window.platform\n\n return platform\n}\n","export async function dataUrlToBase64(url: string): Promise<string> {\n if (url.indexOf('blob:') >= 0) {\n return new Promise((resolve, reject) => {\n // Fetch the Blob content\n fetch(url)\n .then(response => {\n if (!response.ok) {\n throw new Error('Failed to fetch Blob content');\n }\n return response.blob();\n })\n .then(blob => {\n const reader = new FileReader();\n reader.onload = () => {\n const base64String = reader.result ? (reader.result as string).split(',')[1] : ''\n resolve(base64String);\n };\n reader.onerror = () => {\n reader.abort();\n reject(new Error('Error converting blob to base64'));\n };\n reader.readAsDataURL(blob);\n })\n .catch(error => {\n reject(error);\n });\n });\n }\n return url.replace(/^data:image\\/(png|jpeg);base64,/, '')\n}\n\nexport function dataUrlToBase64Sync(url: string): string {\n return url.replace(/^data:.*;base64,/, '')\n}\n\nexport function contentDispositionFromDataUrl(url: string): string {\n return url.match(/^(data:.*;base64),/)?.[1] ?? ''\n}\n\nexport function b64toBlob(b64Data: string, contentType = '', sliceSize = 512) {\n const byteCharacters = atob(b64Data)\n const byteArrays = []\n\n for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {\n const slice = byteCharacters.slice(offset, offset + sliceSize)\n\n const byteNumbers = new Array(slice.length)\n for (let i = 0; i < slice.length; i++) {\n byteNumbers[i] = slice.charCodeAt(i)\n }\n\n const byteArray = new Uint8Array(byteNumbers)\n byteArrays.push(byteArray)\n }\n\n return new Blob(byteArrays, { type: contentType })\n}\n\nexport function blobToB64(blob: Blob): Promise<string> {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.readAsDataURL(blob)\n })\n}\n","import { UploadedDocument } from '../components/additional_document_capture/AdditionalDocumentCapture'\nimport { webSdkVersion } from '../version'\nimport { getPlatform } from '../lib/utils/platform'\nimport { dataUrlToBase64Sync } from '../lib/utils/dataUrlToBase64'\nimport { DetectedObjectBox } from '../lib/models/DocumentDetection'\n\nexport enum SubmissionAction {\n NONE = 'NONE',\n ENROLL = 'ENROLL',\n IDENTIFY = 'IDENTIFY',\n VALIDATE = 'VALIDATE',\n VERIFY = 'VERIFY',\n}\n\nexport enum SubmissionStatus {\n READY = 'READY',\n SUBMITTING = 'SUBMITTING',\n SUBMITTED = 'SUBMITTED',\n FAILED = 'FAILED',\n}\n\nexport type SubmissionEnvironment = 'prod' | 'demo'\n\nexport const submissionHosts = {\n prod: 'https://api.idmission.com',\n demo: 'https://apidemo.idmission.com',\n}\n\nexport type SubmissionRequest = {\n securityData: {\n userName: string\n password: string\n merchantId: number\n }\n customerData: {\n idData: {\n idImageFront?: string\n idImageBack?: string\n videoIdImageFront?: string\n videoIdImageBack?: string\n\n idType: 'NSP'\n idCountry: 'NSP'\n idState: ''\n }\n personalData?: PersonalData\n cardData?: CardData\n biometricData?: {\n selfie?: string\n videoData?: string\n voiceData?: string\n voiceStartTime?: number\n expectedAudioText?: string\n }\n signatureData?: {\n signatureImage?: string\n signatureVideo?: string\n }\n additionalDocuments?: UploadedDocument[]\n }\n // TODO: remove once API is fixed\n biometricData?: {\n selfie?: string\n }\n additionalData: {\n uniqueRequestId: string\n clientRequestID?: string\n clientTraceId?: string\n manualReviewRequired: 'Y' | 'N'\n bypassAgeValidation: 'Y' | 'N'\n deDuplicationRequired: 'Y' | 'N'\n bypassNameMatching: 'Y' | 'N'\n postDataAPIRequired: 'Y' | 'N'\n postDataOnReviewRequired: 'Y' | 'N'\n sendInputImagesInPost: 'Y' | 'N'\n sendProcessedImagesInPost: 'Y' | 'N'\n needImmediateResponse: 'Y' | 'N'\n deduplicationSynchronous: 'Y' | 'N'\n verifyDataWithHost: 'Y' | 'N'\n idBackImageRequired: 'Y' | 'N'\n stripSpecialCharacters: 'Y' | 'N'\n idImageResolutionCheck: 'Y' | 'N'\n metadata?: string\n }\n employee?: { companyId?: string }\n}\n\nexport type CaptureAttemptMetadata = {\n autoCapture: 'Y' | 'N' // always Y until we add support for manual capture\n captureTime: number // time from start of the camera start to camera stop in ms\n operationTime?: number // time from start of the selfie detection or ID detection to capture in ms\n bestDetectionScore?: number\n bestFocusScore?: number\n boundingBox?: DetectedObjectBox\n}\n\nexport type PersonalData = {\n uniqueNumber?: string\n name?: string\n phone?: string\n phoneCountryCode?: string\n email?: string\n dob?: string // date of birth, formatted DD/MM/YYYY, e.g. 31/12/2019\n gender?: 'M' | 'F'\n addressLine1?: string\n addressLine2?: string\n city?: string\n district?: string // two-letter code indicating state if USA, e.g. CA\n postalCode?: string\n country?: string // three-letter code indicating country, e.g. USA\n}\n\nexport type CardData = {\n cardToken?: string\n cardLast4?: string\n cardExpDate?: string\n nameOnCard?: string\n}\n\nexport type SubmissionMetadata = {\n selfie: CaptureAttemptMetadata[]\n back: CaptureAttemptMetadata[]\n front: CaptureAttemptMetadata[]\n sdkVersion: string\n isRealIDCheckRequired: 'true' | 'false'\n os?: string\n osVersion?: string\n browserVersion?: string\n Resolution?: string\n GeoLocation?: string\n}\n\nexport type SubmissionResponseStatus = {\n statusCode: string\n statusMessage?: string\n errorData?: string\n}\n\nexport type SubmissionResponse = {\n status: SubmissionResponseStatus\n resultData: Record<string, unknown>\n}\n\nexport type LivenessCheckRequest = {\n securityData: {\n userName: string\n password: string\n merchantId: number\n }\n customerData: {\n additionalData?: {\n uniqueRequestId?: string\n }\n biometricData: {\n selfie: string\n }\n idData?: {\n idImageFront?: string\n }\n }\n additionalData: {\n uniqueRequestId: string\n clientRequestID?: string\n stripSpecialCharacters: 'Y' | 'N'\n estimateAge: 'Y' | 'N'\n predictGender: 'Y' | 'N'\n metadata?: string\n }\n}\nexport type LiveCheckResponse = {\n status: { statusCode: string; statusMessage: string; errorData: string }\n resultData: {\n verificationResult: string\n eyeCovering: 'true' | 'false'\n faceMask: 'true' | 'false'\n headCovering: 'true' | 'false'\n cellPhone: 'true' | 'false'\n }\n}\n\nexport function parseJwt(token: string): Record<string, unknown> {\n const base64Url = token.split('.')[1]\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')\n const jsonPayload = decodeURIComponent(\n window\n .atob(base64)\n .split('')\n .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join(''),\n )\n\n return JSON.parse(jsonPayload)\n}\n\nexport function determineSubmissionHost(\n environment: SubmissionEnvironment,\n token?: string,\n): string {\n if (token) {\n switch (parseJwt(token)['iss']) {\n case 'https://auth.idmission.com/auth/realms/identity':\n return submissionHosts.prod\n case 'https://demoauth.idmission.com/auth/realms/identity':\n return submissionHosts.demo\n }\n }\n\n const host = submissionHosts[environment]\n if (!host)\n throw new Error(`unrecognized SubmissionEnvironment ${environment}`)\n return host\n}\n\nexport function determineSubmissionEndpoint(\n action: SubmissionAction,\n hasId: boolean,\n hasSelfie: boolean,\n): string {\n switch (action) {\n case SubmissionAction.ENROLL:\n return hasId ? `/v4/customer/enroll` : `/v4/customer/enroll-biometrics`\n\n case SubmissionAction.IDENTIFY:\n return `/v4/customer/identify`\n\n case SubmissionAction.VALIDATE:\n return hasSelfie\n ? `/v4/customer/validate-id-match-face`\n : `/v4/customer/validate-id`\n\n case SubmissionAction.VERIFY:\n return `/v4/customer/verify`\n\n default:\n throw new Error(`unrecognized SubmissionAction ${action}`)\n }\n}\n\nexport function liveCheckEndpoint(hasDocumentToMatchFace = false): string {\n return hasDocumentToMatchFace\n ? `/v4/customer/match-id-face`\n : `/v4/customer/live-check`\n}\n\nexport function apiHeaders(\n sessionId?: string,\n sendBase64DocumentsInSwaggerProxy = false,\n): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'X-Send-Base64-Documents': sendBase64DocumentsInSwaggerProxy ? '1' : '0',\n Origin: '*',\n }\n if (sessionId) {\n headers['X-Session-Id'] = sessionId\n }\n return headers\n}\n\nexport function attachMetadataToRequest(\n request: SubmissionRequest | LivenessCheckRequest,\n {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n }: {\n selfieCaptureAttempts: CaptureAttemptMetadata[]\n idFrontCaptureAttempts: CaptureAttemptMetadata[]\n idBackCaptureAttempts: CaptureAttemptMetadata[]\n geolocationResult: GeolocationPosition | null\n },\n) {\n const metadata: SubmissionMetadata = {\n selfie: selfieCaptureAttempts,\n front: idFrontCaptureAttempts,\n back: idBackCaptureAttempts,\n isRealIDCheckRequired: 'false',\n sdkVersion: `WebSDK_${webSdkVersion}`,\n Resolution:\n typeof window !== 'undefined'\n ? `${window.innerWidth} x ${window.innerHeight}`\n : 'unknown',\n }\n const platform = getPlatform()\n if (platform) {\n metadata.os = platform.os?.family\n metadata.osVersion = platform.os?.version\n metadata.browserVersion = `${platform.name} ${platform.version}`\n }\n if (geolocationResult) {\n metadata.GeoLocation = JSON.stringify(geolocationResult)\n }\n request.additionalData.metadata = JSON.stringify(metadata)\n}\n\nexport function videoDataUrlToB64(url: string): Promise<string> {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => {\n resolve(dataUrlToBase64Sync(reader.result as string))\n }\n fetch(url)\n .then((resp) => resp.blob())\n .then((blob) => reader.readAsDataURL(blob))\n })\n}\n","import React, {\n CSSProperties,\n forwardRef,\n ReactElement,\n ReactNode,\n RefCallback,\n useEffect,\n useState,\n} from 'react'\nimport styled from 'styled-components'\n\nexport const PageContainerDiv = styled.div<{\n $heightOffset?: number\n}>`\n ${(props) =>\n props.theme.isFullscreen === false\n ? ``\n : `\n position: fixed;\n top: 0;\n left: 0;\n width: var(--app-width);\n height: calc(\n var(--app-height) - ${props.$heightOffset ?? 0}px\n );\n overflow-x: hidden;\n overflow-y: auto;\n `}\n\n ${(props) =>\n props.theme.fontFamily ? `font-family: ${props.theme.fontFamily};` : ``}\n\n &.flex {\n display: flex;\n }\n\n &.padded {\n box-sizing: border-box;\n padding: 16px 24px;\n }\n`\n\nexport const PageContainer = forwardRef(\n (\n {\n children,\n className,\n heightOffset = 0,\n style,\n onClick,\n }: {\n ref?: RefCallback<HTMLDivElement>\n children: ReactNode\n className?: string\n heightOffset?: number\n style?: CSSProperties\n onClick?: () => void\n },\n ref: React.ForwardedRef<HTMLDivElement>,\n ): ReactElement => {\n const [dimensionsCalculated, setDimensionsCalculated] = useState(false)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n setDimensionsCalculated(false)\n const calcAppDimensions = () => {\n const doc = document.documentElement\n doc.style.setProperty('--app-width', `${window.innerWidth}px`)\n doc.style.setProperty('--app-height', `${window.innerHeight}px`)\n }\n window.addEventListener('resize', calcAppDimensions)\n calcAppDimensions()\n setDimensionsCalculated(true)\n\n return () => {\n window.removeEventListener('resize', calcAppDimensions)\n }\n }, [])\n\n return (\n <PageContainerDiv\n ref={ref}\n style={style}\n onClick={onClick}\n className={className}\n $heightOffset={heightOffset}\n >\n {dimensionsCalculated && children}\n </PageContainerDiv>\n )\n },\n)\n\nPageContainer.displayName = 'PageContainer'\n","import styled from 'styled-components'\nimport { PageContainer } from './Page'\n\nexport const OverlayContainer = styled(PageContainer)`\n background: ${(props) =>\n props.theme.background ? `${props.theme.background}` : `white`};\n ${(props) =>\n props.theme.textColor ? `color: ${props.theme.textColor};` : ``}\n z-index: 10000;\n`\n\nexport const OverlayInner = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n max-height: var(--app-height);\n height: 100%;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n`\n\nexport const OverlayImageContainer = styled.div`\n position: relative;\n display: flex;\n flex-grow: 1;\n padding-bottom: 25px;\n max-width: var(--app-width);\n max-height: var(--app-height);\n overflow: hidden;\n\n & > img,\n & > svg {\n margin: 0 auto;\n width: max-content;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: initial;\n object-fit: contain;\n display: block;\n }\n`\n\nexport const OverlayImageRow = styled.div`\n display: flex;\n margin: auto;\n\n & > div {\n max-height: calc(100vh - 320px);\n\n & > img {\n width: 100%;\n max-height: 100%;\n height: auto;\n object-fit: contain;\n }\n }\n`\n","import React, {\n CSSProperties,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { LaddaButton } from 'ladda'\nimport styled from 'styled-components'\n\nexport type LoaderButtonVariant =\n | 'primary'\n | 'secondary'\n | 'positive'\n | 'negative'\n | 'warning'\n\nexport type LoaderButtonColors = {\n backgroundColor?: string\n textColor?: string\n loadingBackgroundColor?: string\n loadingTextColor?: string\n}\n\nexport type LoaderButtonProps = {\n children?: ReactNode\n className?: string\n disabled?: boolean\n finished?: boolean\n colors?: LoaderButtonColors\n onClick?: () => void\n style?: CSSProperties\n variant?: LoaderButtonVariant\n}\n\nexport const LoaderButton = ({\n children,\n className,\n colors = {},\n disabled,\n finished,\n onClick,\n style,\n variant = 'primary',\n}: LoaderButtonProps) => {\n const buttonRef = useRef<HTMLButtonElement | null>(null)\n const laddaRef = useRef<LaddaButton | null>(null)\n const [laddaLoaded, setLaddaLoaded] = useState(false)\n\n useEffect(() => {\n if (laddaLoaded || finished) return\n\n let interval: NodeJS.Timeout\n\n import('ladda').then((Ladda) => {\n if (!buttonRef.current) return\n laddaRef.current = Ladda.create(buttonRef.current)\n laddaRef.current.start()\n setLaddaLoaded(true)\n\n let currentProgress = 0\n interval = setInterval(() => {\n if (currentProgress < 0.9) currentProgress += 0.1\n laddaRef.current?.setProgress(currentProgress)\n }, 250)\n })\n\n return () => {\n laddaRef.current?.remove()\n clearInterval(interval)\n }\n }, [finished, laddaLoaded])\n\n useEffect(() => {\n if (laddaLoaded && finished) laddaRef.current?.stop()\n }, [finished, laddaLoaded])\n\n return (\n <StyledButton\n className={`ladda-button ${className} ${disabled ? 'disabled' : ''}`}\n data-style=\"expand-right\"\n disabled={disabled}\n ref={buttonRef}\n onClick={onClick}\n $backgroundColor={colors.backgroundColor}\n $textColor={colors.textColor}\n $disabledBackgroundColor={colors.loadingBackgroundColor}\n $disabledTextColor={colors.loadingTextColor}\n $variant={variant}\n style={style}\n >\n <span className=\"ladda-label\">{children}</span>\n </StyledButton>\n )\n}\n\nconst StyledButton = styled.button<{\n $backgroundColor?: string\n $textColor?: string\n $disabledBackgroundColor?: string\n $disabledTextColor?: string\n $variant?: LoaderButtonVariant\n}>`\n ${(props) =>\n props.theme.buttons?.style === 'bootstrap' &&\n `\n border-radius: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n text-transform: none;\n -webkit-appearance: button;\n \n &:not(:disabled),\n &[type='button']:not(:disabled),\n &[type='reset']:not(:disabled),\n &[type='submit']:not(:disabled) {\n cursor: pointer;\n }\n \n &:focus:not(:focus-visible) {\n outline: 0;\n }\n \n --bs-btn-padding-x: 0.75rem;\n --bs-btn-padding-y: 0.375rem;\n --bs-btn-font-family: ;\n --bs-btn-font-size: 1rem;\n --bs-btn-font-weight: 400;\n --bs-btn-line-height: 1.5;\n --bs-btn-color: var(--bs-body-color);\n --bs-btn-bg: transparent;\n --bs-btn-border-width: var(--bs-border-width);\n --bs-btn-border-color: transparent;\n --bs-btn-border-radius: var(--bs-border-radius);\n --bs-btn-hover-border-color: transparent;\n --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 1px 1px rgba(0, 0, 0, 0.075);\n --bs-btn-disabled-opacity: 0.65;\n --bs-btn-focus-box-shadow: 0 0 0 0.25rem\n rgba(var(--bs-btn-focus-shadow-rgb), 0.5);\n display: inline-block;\n padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);\n font-family: var(--bs-btn-font-family);\n font-size: var(--bs-btn-font-size);\n font-weight: var(--bs-btn-font-weight);\n line-height: var(--bs-btn-line-height);\n color: var(--bs-btn-color);\n text-align: center;\n text-decoration: none;\n vertical-align: middle;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);\n border-radius: var(--bs-btn-border-radius);\n background-color: var(--bs-btn-bg);\n //transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,\n // border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n \n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n \n &:hover {\n filter: brightness(1.15);\n }\n \n &:focus-visible {\n color: var(--bs-btn-hover-color);\n background-color: var(--bs-btn-hover-bg);\n border-color: var(--bs-btn-hover-border-color);\n outline: 0;\n box-shadow: var(--bs-btn-focus-box-shadow);\n }\n \n &:disabled,\n &.disabled,\n fieldset:disabled & {\n color: var(--bs-btn-disabled-color);\n pointer-events: none;\n background-color: var(--bs-btn-disabled-bg);\n border-color: var(--bs-btn-disabled-border-color);\n opacity: var(--bs-btn-disabled-opacity);\n }\n \n --bs-btn-color: ${\n props.$textColor ??\n props.theme.buttons?.[props.$variant ?? 'primary']?.textColor ??\n '#fff'\n };\n --bs-btn-bg: ${\n props.$backgroundColor ??\n props.theme.buttons?.[props.$variant ?? 'primary']?.backgroundColor ??\n '#0d6efd'\n };\n --bs-btn-border-color: var(--bs-btn-bg);\n --bs-btn-focus-shadow-rgb: 49, 132, 253;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #0a58ca;\n --bs-btn-active-border-color: #0a53be;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: ${\n props.$disabledTextColor ??\n props.theme.buttons?.loading?.textColor ??\n '#fff'\n };\n --bs-btn-disabled-bg: ${\n props.$disabledBackgroundColor ??\n props.theme.buttons?.loading?.backgroundColor ??\n 'gray'\n };\n --bs-btn-disabled-border-color: ${\n props.$disabledBackgroundColor ?? '#0d6efd'\n };\n \n --bs-btn-padding-y: 14px;\n --bs-btn-padding-x: 1rem;\n --bs-btn-font-size: 18px;\n --bs-btn-border-radius: 4px;\n `}\n\n /*!\n * Ladda\n * http://lab.hakim.se/ladda\n * MIT licensed\n *\n * Copyright (C) 2018 Hakim El Hattab, http://hakim.se\n */\n @keyframes ladda-spinner-line-fade {\n 0%,\n 100% {\n opacity: 0.22;\n }\n 1% {\n opacity: 1;\n }\n }\n\n position: relative;\n\n .ladda-spinner {\n position: absolute;\n z-index: 2;\n display: inline-block;\n width: 32px;\n top: 50%;\n margin-top: 0;\n opacity: 0;\n pointer-events: none;\n }\n .ladda-label {\n position: relative;\n z-index: 3;\n }\n .ladda-progress {\n position: absolute;\n width: 0;\n height: 100%;\n left: 0;\n top: 0;\n background: rgba(0, 0, 0, 0.2);\n display: none;\n transition: 0.1s linear all !important;\n }\n &[data-loading] .ladda-progress {\n display: block;\n }\n\n transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;\n\n .ladda-spinner,\n .ladda-label {\n transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) all !important;\n }\n &[data-style='zoom-in'],\n &[data-style='zoom-in'] .ladda-spinner,\n &[data-style='zoom-in'] .ladda-label,\n &[data-style='zoom-out'],\n &[data-style='zoom-out'] .ladda-spinner,\n &[data-style='zoom-out'] .ladda-label {\n transition: 0.3s ease all !important;\n }\n &[data-style='expand-right'] .ladda-spinner {\n right: -6px;\n }\n &[data-style='expand-right'][data-size='s'] .ladda-spinner,\n &[data-style='expand-right'][data-size='xs'] .ladda-spinner {\n right: -12px;\n }\n &[data-style='expand-right'][data-loading] {\n padding-right: 56px;\n }\n &[data-style='expand-right'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-right'][data-loading][data-size='s'],\n &[data-style='expand-right'][data-loading][data-size='xs'] {\n padding-right: 40px;\n }\n &[data-style='expand-left'] .ladda-spinner {\n left: 26px;\n }\n &[data-style='expand-left'][data-size='s'] .ladda-spinner,\n &[data-style='expand-left'][data-size='xs'] .ladda-spinner {\n left: 4px;\n }\n &[data-style='expand-left'][data-loading] {\n padding-left: 56px;\n }\n &[data-style='expand-left'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-left'][data-loading][data-size='s'],\n &[data-style='expand-left'][data-loading][data-size='xs'] {\n padding-left: 40px;\n }\n &[data-style='expand-up'] {\n overflow: hidden;\n }\n &[data-style='expand-up'] .ladda-spinner {\n top: -32px;\n left: 50%;\n margin-left: 0;\n }\n &[data-style='expand-up'][data-loading] {\n padding-top: 54px;\n }\n &[data-style='expand-up'][data-loading] .ladda-spinner {\n opacity: 1;\n top: 26px;\n margin-top: 0;\n }\n &[data-style='expand-up'][data-loading][data-size='s'],\n &[data-style='expand-up'][data-loading][data-size='xs'] {\n padding-top: 32px;\n }\n &[data-style='expand-up'][data-loading][data-size='s'] .ladda-spinner,\n &[data-style='expand-up'][data-loading][data-size='xs'] .ladda-spinner {\n top: 4px;\n }\n &[data-style='expand-down'] {\n overflow: hidden;\n }\n &[data-style='expand-down'] .ladda-spinner {\n top: 62px;\n left: 50%;\n margin-left: 0;\n }\n &[data-style='expand-down'][data-size='s'] .ladda-spinner,\n &[data-style='expand-down'][data-size='xs'] .ladda-spinner {\n top: 40px;\n }\n &[data-style='expand-down'][data-loading] {\n padding-bottom: 54px;\n }\n &[data-style='expand-down'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='expand-down'][data-loading][data-size='s'],\n &[data-style='expand-down'][data-loading][data-size='xs'] {\n padding-bottom: 32px;\n }\n &[data-style='slide-left'] {\n overflow: hidden;\n }\n &[data-style='slide-left'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-left'] .ladda-spinner {\n left: 100%;\n margin-left: 0;\n }\n &[data-style='slide-left'][data-loading] .ladda-label {\n opacity: 0;\n left: -100%;\n }\n &[data-style='slide-left'][data-loading] .ladda-spinner {\n opacity: 1;\n left: 50%;\n }\n &[data-style='slide-right'] {\n overflow: hidden;\n }\n &[data-style='slide-right'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-right'] .ladda-spinner {\n right: 100%;\n margin-left: 0;\n left: 16px;\n }\n [dir='rtl'] &[data-style='slide-right'] .ladda-spinner {\n right: auto;\n }\n &[data-style='slide-right'][data-loading] .ladda-label {\n opacity: 0;\n left: 100%;\n }\n &[data-style='slide-right'][data-loading] .ladda-spinner {\n opacity: 1;\n left: 50%;\n }\n &[data-style='slide-up'] {\n overflow: hidden;\n }\n &[data-style='slide-up'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-up'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n margin-top: 1em;\n }\n &[data-style='slide-up'][data-loading] .ladda-label {\n opacity: 0;\n top: -1em;\n }\n &[data-style='slide-up'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-top: 0;\n }\n &[data-style='slide-down'] {\n overflow: hidden;\n }\n &[data-style='slide-down'] .ladda-label {\n position: relative;\n }\n &[data-style='slide-down'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n margin-top: -2em;\n }\n &[data-style='slide-down'][data-loading] .ladda-label {\n opacity: 0;\n top: 1em;\n }\n &[data-style='slide-down'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-top: 0;\n }\n &[data-style='zoom-out'] {\n overflow: hidden;\n }\n &[data-style='zoom-out'] .ladda-spinner {\n left: 50%;\n margin-left: 32px;\n transform: scale(2.5);\n }\n &[data-style='zoom-out'] .ladda-label {\n position: relative;\n display: inline-block;\n }\n &[data-style='zoom-out'][data-loading] .ladda-label {\n opacity: 0;\n transform: scale(0.5);\n }\n &[data-style='zoom-out'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-left: 0;\n transform: none;\n }\n &[data-style='zoom-in'] {\n overflow: hidden;\n }\n &[data-style='zoom-in'] .ladda-spinner {\n left: 50%;\n margin-left: -16px;\n transform: scale(0.2);\n }\n &[data-style='zoom-in'] .ladda-label {\n position: relative;\n display: inline-block;\n }\n &[data-style='zoom-in'][data-loading] .ladda-label {\n opacity: 0;\n transform: scale(2.2);\n }\n &[data-style='zoom-in'][data-loading] .ladda-spinner {\n opacity: 1;\n margin-left: 0;\n transform: none;\n }\n &[data-style='contract'] {\n overflow: hidden;\n width: 100px;\n }\n &[data-style='contract'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n }\n &[data-style='contract'][data-loading] {\n border-radius: 50%;\n width: 52px;\n }\n &[data-style='contract'][data-loading] .ladda-label {\n opacity: 0;\n }\n &[data-style='contract'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n &[data-style='contract-overlay'] {\n overflow: hidden;\n width: 100px;\n box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0, 0);\n }\n &[data-style='contract-overlay'] .ladda-spinner {\n left: 50%;\n margin-left: 0;\n }\n &[data-style='contract-overlay'][data-loading] {\n border-radius: 50%;\n width: 52px;\n box-shadow: 0px 0px 0px 2000px rgba(0, 0, 0, 0.8);\n }\n &[data-style='contract-overlay'][data-loading] .ladda-label {\n opacity: 0;\n }\n &[data-style='contract-overlay'][data-loading] .ladda-spinner {\n opacity: 1;\n }\n [dir='rtl'] .ladda-spinner > div {\n left: 25% !important;\n }\n`\n","import React, { ReactElement, useContext } from 'react'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { useTranslation } from 'react-i18next'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { SubmissionContext } from './SubmissionProvider'\n\nexport type GeolocationAccessDeniedOverlayProps = {\n accessBlockedImageUrl?: string\n}\n\nexport const GeolocationAccessDeniedOverlay = ({\n accessBlockedImageUrl,\n}: GeolocationAccessDeniedOverlayProps): ReactElement => {\n const { t } = useTranslation()\n const { retryLocationAccess } = useContext(SubmissionContext)\n\n return (\n <OverlayContainer>\n <div style={{ display: 'flex', height: '100%' }}>\n <OverlayInner style={{ maxWidth: 500, height: 'auto', margin: 'auto' }}>\n <OverlayImageContainer style={{ flexGrow: 0 }}>\n <img src={accessBlockedImageUrl} alt={''} />\n </OverlayImageContainer>\n\n <h3>{t('Your location access is disabled')}</h3>\n <p style={{ lineHeight: 1.5, marginBottom: 50 }}>\n {t(\n 'This application requires access to your location to continue. ' +\n 'Please accept the permission once prompted by the browser. ' +\n 'If the browser does not prompt for location permissions, you must go to settings ' +\n 'and provide location access to the current browser.',\n )}\n </p>\n\n <LoaderButton\n variant=\"primary\"\n onClick={retryLocationAccess}\n style={{ width: 200, marginLeft: 'auto', marginRight: 'auto' }}\n finished\n >\n {t('Retry')}\n </LoaderButton>\n </OverlayInner>\n </div>\n </OverlayContainer>\n )\n}\n","import { SubmissionResponseStatus } from '../../contexts/SubmissionContext'\n\nexport class SubmissionError extends Error {\n constructor(public status: SubmissionResponseStatus) {\n super(status.statusMessage)\n }\n}\n\nexport class NetworkError extends Error {}\n\nexport class SessionValidationFailedError extends Error {\n constructor(\n public err: Error,\n public host: string,\n ) {\n super(err.message)\n }\n}\n","import React, { ReactElement } from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { NetworkError, SubmissionError } from './Errors'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslation } from 'react-i18next'\n\nexport type SubmissionErrorOverlayProps = {\n error: SubmissionError | NetworkError\n onRetry?: () => void\n}\n\nexport const SubmissionErrorOverlay = ({\n error,\n onRetry,\n}: SubmissionErrorOverlayProps): ReactElement => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n {error instanceof NetworkError ? (\n <NetworkErrorContent error={error} onRetry={onRetry} />\n ) : (\n <SubmissionErrorContent error={error} />\n )}\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst SubmissionErrorContent = ({ error }: { error: SubmissionError }) => {\n const { t } = useTranslation()\n\n const headingText = t(`We're sorry, an unexpected error has occurred.`)\n\n return (\n <>\n <h3 style={{ marginBottom: 8 }}>{headingText}</h3>\n {error.status.statusCode && (\n <p style={{ marginBottom: 0 }}>\n <code>Status: {error.status.statusCode}</code>\n </p>\n )}\n <p style={{ marginBottom: 0 }}>\n Message: <code>{error.message}</code>\n </p>\n {error.status.errorData && (\n <p style={{ marginBottom: 0 }}>\n Data: <code>{error.status.errorData}</code>\n </p>\n )}\n </>\n )\n}\n\nconst NetworkErrorContent = ({\n onRetry,\n}: {\n error: NetworkError\n onRetry?: () => void\n}) => {\n const { t } = useTranslation()\n const headingText = t('Network unreachable')\n const messageText = t(\n `We're having trouble reaching our services, please check your connection and try again.`,\n )\n const retryText = t('Retry')\n\n return (\n <>\n <h3 style={{ marginBottom: 8 }}>{headingText}</h3>\n <p style={{ marginBottom: 0 }}>{messageText}</p>\n\n {onRetry && (\n <div style={{ marginTop: 32 }}>\n <LoaderButton variant=\"warning\" finished onClick={onRetry}>\n {retryText}\n </LoaderButton>\n </div>\n )}\n </>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const SessionIdMissingOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>sessionId</code> is missing.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const SessionValidationFailedOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>sessionId</code> is not valid.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\n\nexport const AuthUrlNotAllowedOverlay = () => {\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n Required property <code>authUrl</code> comes from an unrecognized\n issuer.\n </p>\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n Ensure you are generating a fresh session for each request to the\n IDmission WebSDK.\n </p>\n <p style={{ lineHeight: '1.5rem' }}>\n Please refer to the{' '}\n <a\n href=\"https://www.npmjs.com/package/idmission-web-sdk#getting-started\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Getting Started\n </a>{' '}\n section of the documentation for information on how to use your\n credentials to generate a valid session for your IDmission account.\n Every usage of the IDmission WebSDK must be authorized with a valid\n session from IDmission's servers.\n </p>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import React from 'react'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { SessionValidationFailedError } from './Errors'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslation } from 'react-i18next'\n\nexport const SessionValidationErrorOverlay = ({\n error,\n onRetry,\n}: {\n error: SessionValidationFailedError | null\n onRetry?: () => void\n}) => {\n const { t } = useTranslation()\n const retryText = t('Retry')\n\n return (\n <OverlayContainer>\n <OverlayInner style={{ justifyContent: 'center' }}>\n <h3 style={{ marginBottom: 8 }}>IDmission WebSDK failed to load</h3>\n <p style={{ marginBottom: 0 }}>\n {error?.host ? (\n <>\n Failed to reach <code>{error.host}</code>.\n </>\n ) : (\n <>\n Failed to validate <code>sessionId</code>.\n </>\n )}\n </p>\n {error?.message && (\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n <code>{error.message}</code>\n </p>\n )}\n <p style={{ marginBottom: 0, lineHeight: '1.5rem' }}>\n Please ensure that IDmission's servers can be reached. If you\n believe you have reached this page in error, please contact us at{' '}\n <a href=\"mailto:support@idmission.com\">support@idmission.com</a>.\n </p>\n\n {onRetry && (\n <div style={{ marginTop: 32 }}>\n <LoaderButton variant=\"warning\" finished onClick={onRetry}>\n {retryText}\n </LoaderButton>\n </div>\n )}\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import styled from 'styled-components'\n\nexport const Spinner = styled.div<{\n $size?: number\n $thickness?: number\n $color?: string\n}>`\n display: inline-block;\n width: ${({ $size }) => $size ?? 80}px;\n height: ${({ $size }) => $size ?? 80}px;\n margin: auto;\n\n &:after {\n content: ' ';\n display: block;\n width: ${({ $size }) => ($size ?? 80) - 16}px;\n height: ${({ $size }) => ($size ?? 80) - 16}px;\n margin: 8px;\n border-radius: 50%;\n border: ${({ $thickness }) => $thickness ?? 6}px solid\n ${({ $color }) => $color ?? '#888'};\n border-color: ${({ $color }) => $color ?? '#888'} transparent\n ${({ $color }) => $color ?? '#888'} transparent;\n animation: lds-dual-ring 1.2s linear infinite;\n box-sizing: content-box;\n }\n\n @keyframes lds-dual-ring {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n`\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useContext,\n useEffect,\n useReducer,\n} from 'react'\nimport { SessionValidationFailedError } from '../components/submission/Errors'\nimport { SessionIdMissingOverlay } from '../components/submission/SessionIdMissingOverlay'\nimport { SessionValidationFailedOverlay } from '../components/submission/SessionValidationFailedOverlay'\nimport { AuthUrlNotAllowedOverlay } from '../components/submission/AuthUrlNotAllowedOverlay'\nimport { SessionValidationErrorOverlay } from '../components/submission/SessionValidationErrorOverlay'\nimport { PageContainer } from '../components/common/Page'\nimport { Spinner } from '../components/common/spinner'\n\nexport const defaultAuthUrl = 'https://portal-api.idmission.com'\nexport const allowedAuthUrls = [\n 'https://portal-api.idmission.com',\n 'https://portal-api-uat.idmission.com',\n 'https://portal-api-demo.idmission.com',\n 'https://portal-api-dev.idmission.com',\n 'http://localhost:10000',\n]\n\nexport type SessionCheckState =\n | 'READY'\n | 'RUNNING'\n | 'PASSED'\n | 'FAILED'\n | 'MISSING'\n | 'AUTH_URL_NOT_ALLOWED'\n | 'ERROR'\n\nexport type AuthState = {\n authUrl: string\n sessionCheckState: SessionCheckState\n sessionId?: string\n authError?: SessionValidationFailedError\n}\n\nconst initialState = {\n authUrl: defaultAuthUrl,\n sessionCheckState: 'READY',\n} satisfies AuthState\n\nexport const AuthStateContext = createContext<AuthState>(initialState)\n\nexport type AuthAction =\n | {\n type: 'setSessionId'\n payload: string\n }\n | { type: 'setCheckState'; payload: SessionCheckState }\n | {\n type: 'setError'\n payload: SessionValidationFailedError\n }\n | { type: 'retry' }\n\nexport type AuthDispatch = Dispatch<AuthAction>\n\nexport const AuthDispatchContext = createContext<AuthDispatch>(() => {})\n\nconst reducer = (state: AuthState, action: AuthAction): AuthState => {\n switch (action.type) {\n case 'setSessionId':\n return { ...state, sessionId: action.payload }\n\n case 'setCheckState':\n return { ...state, sessionCheckState: action.payload }\n\n case 'setError':\n return { ...state, sessionCheckState: 'ERROR', authError: action.payload }\n\n case 'retry':\n return {\n ...state,\n sessionCheckState: 'READY',\n authError: undefined,\n sessionId: undefined,\n }\n\n default:\n return state\n }\n}\n\nexport function useAuthReducer(\n authUrl = defaultAuthUrl,\n sessionId?: string | (() => Promise<string>),\n): [AuthState, AuthDispatch] {\n const [state, dispatch] = useReducer(reducer, { ...initialState, authUrl })\n const { sessionId: resolvedSessionId, sessionCheckState } = state\n\n useEffect(() => {\n if (!allowedAuthUrls.includes(authUrl))\n return dispatch({\n type: 'setCheckState',\n payload: 'AUTH_URL_NOT_ALLOWED',\n })\n }, [authUrl])\n\n useEffect(() => {\n if (sessionCheckState !== 'READY') return\n\n if (!resolvedSessionId) {\n if (!sessionId)\n return dispatch({ type: 'setCheckState', payload: 'MISSING' })\n\n if (typeof sessionId === 'string')\n return dispatch({ type: 'setSessionId', payload: sessionId })\n\n if (sessionId instanceof Function) {\n sessionId()\n .then((sessionId) => {\n dispatch({ type: 'setSessionId', payload: sessionId })\n })\n .catch((e) => {\n console.error('failed to resolve session id', e)\n dispatch({\n type: 'setError',\n payload: new SessionValidationFailedError(e, authUrl),\n })\n })\n }\n } else {\n dispatch({ type: 'setCheckState', payload: 'RUNNING' })\n ;(async () => {\n try {\n const resp = await fetch(\n `${authUrl}/portal.sessions.v1.SessionsService/ValidateSession`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ id: resolvedSessionId }),\n },\n )\n const { valid } = await resp.json()\n dispatch({\n type: 'setCheckState',\n payload: valid ? 'PASSED' : 'FAILED',\n })\n } catch (e) {\n dispatch({\n type: 'setError',\n payload: new SessionValidationFailedError(e as Error, authUrl),\n })\n }\n })()\n }\n }, [authUrl, sessionCheckState, resolvedSessionId, sessionId])\n\n return [state, dispatch]\n}\n\nexport function useAuthContext(): [AuthState, AuthDispatch] {\n const state = useContext(AuthStateContext)\n const dispatch = useContext(AuthDispatchContext)\n if (!state || !dispatch)\n throw new Error('useAuthContext cannot be used without AuthStateProvider')\n\n return [state, dispatch]\n}\n\nexport function AuthProvider({\n authUrl = defaultAuthUrl,\n sessionId,\n children,\n}: {\n authUrl?: string\n sessionId: string | (() => Promise<string>)\n children: ReactNode\n}) {\n const [state, dispatch] = useAuthReducer(authUrl, sessionId)\n\n if (state.sessionCheckState === 'MISSING') {\n return <SessionIdMissingOverlay />\n }\n\n if (state.sessionCheckState === 'FAILED') {\n return <SessionValidationFailedOverlay />\n }\n\n if (state.sessionCheckState === 'AUTH_URL_NOT_ALLOWED') {\n return <AuthUrlNotAllowedOverlay />\n }\n\n if (state.sessionCheckState === 'ERROR') {\n return (\n <SessionValidationErrorOverlay\n error={state.authError!}\n onRetry={() => dispatch({ type: 'retry' })}\n />\n )\n }\n\n if (\n state.sessionCheckState === 'READY' ||\n state.sessionCheckState === 'RUNNING'\n )\n return (\n <PageContainer className=\"flex\">\n <Spinner />\n </PageContainer>\n )\n\n return (\n <AuthStateContext.Provider value={state}>\n <AuthDispatchContext.Provider value={dispatch}>\n {children}\n </AuthDispatchContext.Provider>\n </AuthStateContext.Provider>\n )\n}\n","import { useEffect } from 'react'\n\nexport enum LogLevel {\n Off,\n Error,\n Warn,\n Info,\n Debug,\n}\n\nlet logLevel: LogLevel = LogLevel.Warn\n\nexport function useLogLevel(newLogLevel: LogLevel) {\n useEffect(() => {\n const oldLogLevel = logLevel\n if (newLogLevel === oldLogLevel) return\n logLevel = newLogLevel\n return () => {\n logLevel = oldLogLevel\n }\n }, [newLogLevel])\n}\n\nexport function useDebugLogging(enabled: boolean) {\n useLogLevel(enabled ? LogLevel.Debug : logLevel)\n}\n\nexport function debug(...parts: unknown[]) {\n if (logLevel < LogLevel.Debug) return\n console.debug(...parts) // eslint-disable-line\n}\n\nexport function log(...parts: unknown[]) {\n if (logLevel < LogLevel.Info) return\n console.log(...parts) // eslint-disable-line\n}\n\nexport function warn(...parts: unknown[]) {\n if (logLevel < LogLevel.Warn) return\n console.warn(...parts) // eslint-disable-line\n}\n\nexport function error(...parts: unknown[]) {\n if (logLevel < LogLevel.Error) return\n console.error(...parts) // eslint-disable-line\n}\n\nexport function time(label?: string) {\n if (logLevel < LogLevel.Info) return\n console.time(label) // eslint-disable-line\n}\n\nexport function timeEnd(label?: string) {\n if (logLevel < LogLevel.Info) return\n console.timeEnd(label) // eslint-disable-line\n}\n\nexport default log\n","import React, {\n createContext,\n ReactElement,\n useCallback,\n useEffect,\n useState,\n} from 'react'\nimport {\n apiHeaders,\n attachMetadataToRequest,\n CaptureAttemptMetadata,\n CardData,\n determineSubmissionEndpoint,\n determineSubmissionHost,\n liveCheckEndpoint,\n LiveCheckResponse,\n LivenessCheckRequest,\n PersonalData,\n SubmissionAction,\n SubmissionEnvironment,\n SubmissionRequest,\n SubmissionResponse,\n SubmissionStatus,\n videoDataUrlToB64,\n} from '../../contexts/SubmissionContext'\nimport {\n blobToB64,\n dataUrlToBase64,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport { UploadedDocument } from '../additional_document_capture/AdditionalDocumentCapture'\nimport { SignatureData } from '../signature_capture/data'\nimport { GeolocationAccessDeniedOverlay } from './GeolocationAccessDeniedOverlay'\nimport { SubmissionErrorOverlay } from './SubmissionErrorOverlay'\nimport { NetworkError, SubmissionError } from './Errors'\nimport { CapturedDocuments } from '../id_capture/CapturedDocuments'\nimport { useAuthContext } from '../../contexts/AuthStateContext'\nimport { Upload, UploadOptions } from 'tus-js-client'\nimport log from '../../lib/utils/logger'\n\nexport const defaultSubmissionUrl = 'https://portal-api.idmission.com/swagger'\nexport const defaultDocumentServiceUrl =\n 'https://portal-api.idmission.com/files/'\n\nexport type DocumentMetadata = { filename?: string; filetype?: string }\nexport type DocumentUploadProgressEvent = {\n bytesUploaded: number\n bytesTotal: number\n percentage: string\n metadata?: DocumentMetadata\n}\nexport type OnBeforeDocumentUpload = (\n content: Blob,\n metadata?: DocumentMetadata,\n) => Promise<void | false>\nexport type OnDocumentUploadProgress = (\n event: DocumentUploadProgressEvent,\n) => void\nexport type OnDocumentUploaded = (\n documentId: string,\n metadata?: DocumentMetadata,\n) => Promise<void>\nexport type OnDocumentUploadFailed = (\n error: Error,\n metadata?: DocumentMetadata,\n) => void\n\nexport type SubmissionState = {\n submit: () => Promise<SubmissionResponse | null>\n submissionStatus: SubmissionStatus\n submissionRequest: SubmissionRequest | null\n submissionResponse: SubmissionResponse | null\n submissionError: SubmissionError | NetworkError | null\n submissionEnvironment: SubmissionEnvironment\n\n idFrontImage: string | null\n idBackImage: string | null\n passportImage: string | null\n selfieImage: string | null\n signatureData: SignatureData | null\n signatureVideoUrl: string | null\n idCaptureVideoUrl: string | null\n idCaptureVideoIdFrontImage: string | null\n idCaptureVideoIdBackImage: string | null\n idCaptureVideoAudioUrl: string | null\n idCaptureVideoAudioStartsAt: number | null\n additionalDocuments: UploadedDocument[] | null\n\n setIdFrontImage: (image: string) => void\n setIdBackImage: (image: string) => void\n setPassportImage: (image: string) => void\n setSelfieImage: (image: string) => void\n setSignatureData: (signatureData: SignatureData) => void\n setSignatureVideoUrl: (videoDataUrl: string) => void\n setIdCaptureVideoUrl: (videoDataUrl: string) => void\n setIdCaptureVideoIdFrontImage: (image: string) => void\n setIdCaptureVideoIdBackImage: (image: string) => void\n setIdCaptureVideoAudioUrl: (videoDataUrl: string) => void\n setIdCaptureVideoAudioStartsAt: (value: number) => void\n setExpectedAudioText: (value: string) => void\n setAdditionalDocuments: (uploadedDocuments: UploadedDocument[]) => void\n\n uploadDocument: (blob: Blob, metadata?: DocumentMetadata) => Promise<string>\n\n logIdFrontCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n logIdBackCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n logSelfieCaptureAttempt: (attempt: CaptureAttemptMetadata) => void\n\n livenessCheckRequest: LivenessCheckRequest | null\n checkLiveness: (imageDataUrl: string) => Promise<LiveCheckResponse>\n\n retryLocationAccess: () => void\n}\n\nexport const SubmissionContext = createContext<SubmissionState>({\n submit: async () => null,\n submissionStatus: SubmissionStatus.READY,\n submissionRequest: null,\n submissionResponse: null,\n submissionError: null,\n submissionEnvironment: 'prod',\n\n idFrontImage: null,\n idBackImage: null,\n passportImage: null,\n selfieImage: null,\n signatureData: null,\n signatureVideoUrl: null,\n idCaptureVideoUrl: null,\n idCaptureVideoIdFrontImage: null,\n idCaptureVideoIdBackImage: null,\n idCaptureVideoAudioUrl: null,\n idCaptureVideoAudioStartsAt: null,\n additionalDocuments: null,\n\n setIdFrontImage: () => null,\n setIdBackImage: () => null,\n setPassportImage: () => null,\n setSelfieImage: () => null,\n setSignatureData: () => null,\n setSignatureVideoUrl: () => null,\n setIdCaptureVideoUrl: () => null,\n setIdCaptureVideoIdFrontImage: () => null,\n setIdCaptureVideoIdBackImage: () => null,\n setIdCaptureVideoAudioUrl: () => null,\n setIdCaptureVideoAudioStartsAt: () => null,\n setExpectedAudioText: () => null,\n setAdditionalDocuments: () => null,\n\n uploadDocument: Promise.resolve,\n\n logIdFrontCaptureAttempt: () => null,\n logIdBackCaptureAttempt: () => null,\n logSelfieCaptureAttempt: () => null,\n\n livenessCheckRequest: null,\n checkLiveness: async () => {\n throw new Error('checkLiveness is not implemented')\n },\n\n retryLocationAccess: () => null,\n})\n\nexport type SubmissionProviderProps = {\n action: SubmissionAction\n children: ReactElement\n submissionUrl?: string\n environment?: SubmissionEnvironment\n companyId?: string\n enrollmentId?: string\n personalData?: PersonalData\n cardData?: CardData\n bypassAgeValidation?: boolean\n bypassNameMatching?: boolean\n needImmediateResponse?: boolean\n manualReviewRequired?: boolean\n idBackImageRequired?: boolean\n idImageResolutionCheck?: boolean\n verifyIdWithExternalDatabases?: boolean\n deduplicationEnabled?: boolean\n deduplicationSynchronous?: boolean\n idCardForFaceMatch?: string\n geolocationEnabled?: boolean\n geolocationRequired?: boolean\n webhooksEnabled?: boolean\n webhooksClientTraceId?: string\n webhooksStripSpecialCharacters?: boolean\n webhooksSendInputImages?: boolean\n webhooksSendProcessedImages?: boolean\n webhooksFireOnReview?: boolean\n precapturedDocuments?: CapturedDocuments\n documentServiceUrl?: string\n sendBase64DocumentsInSwaggerProxy?: boolean\n onSubmit?: (payload: SubmissionRequest) => void\n onBeforeSubmit?: (req: SubmissionRequest) => Promise<SubmissionRequest>\n onBeforeLivenessCheck?: (\n req: LivenessCheckRequest,\n ) => Promise<LivenessCheckRequest>\n onBeforeDocumentUpload?: OnBeforeDocumentUpload\n onDocumentUploadProgress?: OnDocumentUploadProgress\n onDocumentUploaded?: OnDocumentUploaded\n onDocumentUploadFailed?: OnDocumentUploadFailed\n onResponseReceived?: (res: SubmissionResponse, req: SubmissionRequest) => void\n onRequestFailure?: (err: Error) => void\n readTextPrompt?: string // by the time we get to the submission context, the type should have resolved to string\n clientRequestID?: string\n}\n\nexport const SubmissionProvider = ({\n action,\n children,\n submissionUrl = defaultSubmissionUrl,\n environment = 'prod',\n companyId,\n enrollmentId,\n personalData,\n cardData,\n bypassAgeValidation = false,\n bypassNameMatching = true,\n needImmediateResponse = false,\n manualReviewRequired = false,\n idBackImageRequired = true,\n idImageResolutionCheck = true,\n verifyIdWithExternalDatabases = false,\n deduplicationEnabled = false,\n deduplicationSynchronous = false,\n idCardForFaceMatch,\n geolocationEnabled = true,\n geolocationRequired = false,\n webhooksEnabled = false,\n webhooksClientTraceId,\n webhooksStripSpecialCharacters = true,\n webhooksSendInputImages = false,\n webhooksSendProcessedImages = false,\n webhooksFireOnReview = false,\n precapturedDocuments,\n documentServiceUrl = defaultDocumentServiceUrl,\n sendBase64DocumentsInSwaggerProxy = false,\n onSubmit,\n onBeforeSubmit,\n onBeforeLivenessCheck,\n onBeforeDocumentUpload,\n onDocumentUploadProgress,\n onDocumentUploaded,\n onDocumentUploadFailed,\n onResponseReceived,\n onRequestFailure,\n clientRequestID,\n}: SubmissionProviderProps): ReactElement => {\n const [{ sessionId }] = useAuthContext()\n const [submissionStatus, setSubmissionStatus] = useState<SubmissionStatus>(\n SubmissionStatus.READY,\n )\n const [submissionRequest, setSubmissionRequest] =\n useState<SubmissionRequest | null>(null)\n const [submissionResponse, setSubmissionResponse] =\n useState<SubmissionResponse | null>(null)\n const [submissionError, setSubmissionError] = useState<\n SubmissionError | NetworkError | null\n >(null)\n const [retrySubmission, setRetrySubmission] = useState<(() => void) | null>(\n null,\n )\n const [livenessCheckRequest, setLivenessCheckRequest] =\n useState<LivenessCheckRequest | null>(null)\n\n const [idFrontImage, setIdFrontImage] = useState<string | null>(null)\n const [idBackImage, setIdBackImage] = useState<string | null>(null)\n const [passportImage, setPassportImage] = useState<string | null>(null)\n const [selfieImage, setSelfieImage] = useState<string | null>(null)\n const [signatureData, setSignatureData] = useState<SignatureData | null>(null)\n const [signatureVideoUrl, setSignatureVideoUrl] = useState<string | null>(\n null,\n )\n const [idCaptureVideoUrl, setIdCaptureVideoUrl] = useState<string | null>(\n null,\n )\n const [idCaptureVideoIdFrontImage, setIdCaptureVideoIdFrontImage] = useState<\n string | null\n >(null)\n const [idCaptureVideoIdBackImage, setIdCaptureVideoIdBackImage] = useState<\n string | null\n >(null)\n const [idCaptureVideoAudioUrl, setIdCaptureVideoAudioUrl] = useState<\n string | null\n >(null)\n const [idCaptureVideoAudioStartsAt, setIdCaptureVideoAudioStartsAt] =\n useState<number | null>(null)\n const [expectedAudioText, setExpectedAudioText] = useState<string | null>(\n null,\n )\n const [additionalDocuments, setAdditionalDocuments] = useState<\n UploadedDocument[] | null\n >(null)\n\n const [geolocationResult, setGeolocationResult] =\n useState<GeolocationPosition | null>(null)\n const [geolocationAttempts, setGeolocationAttempts] = useState(0)\n const [geolocationBlocked, setGeolocationBlocked] = useState(false)\n\n const [idFrontCaptureAttempts, setIdFrontCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n const [idBackCaptureAttempts, setIdBackCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n const [selfieCaptureAttempts, setSelfieCaptureAttempts] = useState<\n CaptureAttemptMetadata[]\n >([])\n\n const logIdFrontCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setIdFrontCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n const logIdBackCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setIdBackCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n const logSelfieCaptureAttempt = useCallback(\n (attempt: CaptureAttemptMetadata) => {\n setSelfieCaptureAttempts((attempts) => [...attempts, attempt])\n },\n [],\n )\n\n useEffect(() => {\n if (precapturedDocuments?.selfie) {\n setSelfieImage(dataUrlToBase64Sync(precapturedDocuments.selfie.imageData))\n }\n }, [precapturedDocuments?.selfie])\n\n const uploadDocument = useCallback(\n (src: Blob | string, metadata?: DocumentMetadata) =>\n new Promise<string>(async (resolve, reject) => {\n const blob = typeof src === 'string' ? convertBase64ToBlob(src) : src\n if (\n onBeforeDocumentUpload &&\n (await onBeforeDocumentUpload?.(blob, metadata)) === false\n )\n return resolve(blobToB64(blob))\n\n const upload = createUpload(blob, {\n endpoint: documentServiceUrl,\n retryDelays: [0, 1000, 1000, 1000, 3000, 5000, 10000, 20000],\n headers: { 'X-Session-Id': sessionId! },\n metadata: metadata || { filetype: blob.type },\n onProgress(bytesUploaded, bytesTotal) {\n onDocumentUploadProgress?.({\n bytesUploaded,\n bytesTotal,\n percentage: ((bytesUploaded / bytesTotal) * 100).toFixed(2) + '%',\n metadata,\n })\n },\n onSuccess() {\n const documentId =\n 'urn:documentsv1:' +\n upload.url!.split('/files/').pop()?.split('+').shift()\n\n onDocumentUploaded?.(documentId, metadata)\n resolve(documentId)\n },\n onError(error) {\n log('Failed because: ' + error)\n onDocumentUploadFailed?.(error, metadata)\n reject(error)\n },\n })\n\n // Check if there are any previous uploads to continue.\n upload.findPreviousUploads().then(function (previousUploads) {\n // Found previous uploads so we select the first one.\n if (previousUploads.length) {\n upload.resumeFromPreviousUpload(previousUploads[0])\n }\n\n // Start the upload\n upload.start()\n })\n }),\n [\n onBeforeDocumentUpload,\n documentServiceUrl,\n sessionId,\n onDocumentUploadProgress,\n onDocumentUploaded,\n onDocumentUploadFailed,\n ],\n )\n\n const buildSubmissionPayload = useCallback(async () => {\n async function uploadIfPossible(\n src: string,\n filename: string,\n filetype = 'image/jpeg',\n ) {\n if (!documentServiceUrl) return src\n if (!src.startsWith('data:')) src = `data:${filetype};base64,${src}`\n return await uploadDocument(src, { filename, filetype })\n }\n\n const documents: { [key: string]: string | null } = {\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n signatureVideo:\n signatureVideoUrl && (await videoDataUrlToB64(signatureVideoUrl)),\n idCaptureVideo:\n idCaptureVideoUrl && (await videoDataUrlToB64(idCaptureVideoUrl)),\n idCaptureVideoAudio:\n idCaptureVideoAudioUrl &&\n (await videoDataUrlToB64(idCaptureVideoAudioUrl)),\n idCaptureVideoIdFrontImage,\n idCaptureVideoIdBackImage,\n }\n if (signatureData) {\n documents.signatureImage = signatureData?.fileContent\n }\n if (documentServiceUrl) {\n await Promise.all(\n Object.keys(documents).map(async (k) => {\n if (documents[k]) {\n documents[k] = await uploadIfPossible(documents[k]!, k)\n }\n }),\n )\n }\n\n let submissionRequest: SubmissionRequest = {\n securityData: { userName: '', password: '', merchantId: 0 },\n customerData: {\n idData: { idType: 'NSP', idCountry: 'NSP', idState: '' },\n },\n additionalData: {\n uniqueRequestId: new Date().getTime().toString(),\n manualReviewRequired: manualReviewRequired ? 'Y' : 'N',\n bypassAgeValidation: bypassAgeValidation ? 'Y' : 'N',\n bypassNameMatching: bypassNameMatching ? 'Y' : 'N',\n postDataAPIRequired: webhooksEnabled ? 'Y' : 'N',\n postDataOnReviewRequired: webhooksFireOnReview ? 'Y' : 'N',\n sendInputImagesInPost: webhooksSendInputImages ? 'Y' : 'N',\n sendProcessedImagesInPost: webhooksSendProcessedImages ? 'Y' : 'N',\n needImmediateResponse: needImmediateResponse ? 'Y' : 'N',\n deDuplicationRequired: deduplicationEnabled ? 'Y' : 'N',\n deduplicationSynchronous: deduplicationSynchronous ? 'Y' : 'N',\n verifyDataWithHost: verifyIdWithExternalDatabases ? 'Y' : 'N',\n idBackImageRequired: idBackImageRequired ? 'Y' : 'N',\n stripSpecialCharacters: webhooksStripSpecialCharacters ? 'Y' : 'N',\n idImageResolutionCheck: idImageResolutionCheck ? 'Y' : 'N',\n },\n }\n\n if (clientRequestID) {\n submissionRequest.additionalData.clientRequestID = clientRequestID\n }\n if (documents.idFrontImage) {\n submissionRequest.customerData.idData.idImageFront =\n documents.idFrontImage\n }\n if (documents.idBackImage) {\n submissionRequest.customerData.idData.idImageBack = documents.idBackImage\n }\n if (documents.passportImage) {\n submissionRequest.customerData.idData.idImageFront =\n documents.passportImage\n }\n if (documents.selfieImage) {\n // if (action === SubmissionAction.IDENTIFY) {\n // // TODO: remove once API is fixed\n // submissionRequest.biometricData = { selfie: documents.selfieImage }\n // }\n submissionRequest.customerData.biometricData = {\n selfie: documents.selfieImage,\n }\n }\n if (companyId) {\n submissionRequest.employee = { companyId }\n }\n if (personalData) {\n submissionRequest.customerData.personalData = personalData\n }\n if (cardData) {\n submissionRequest.customerData.cardData = cardData\n }\n if (enrollmentId) {\n submissionRequest.customerData.personalData ||= {}\n submissionRequest.customerData.personalData.uniqueNumber = enrollmentId\n }\n if (webhooksClientTraceId) {\n submissionRequest.additionalData.clientTraceId = webhooksClientTraceId\n }\n if (signatureData) {\n submissionRequest.customerData.signatureData = {\n signatureImage: JSON.stringify(signatureData),\n }\n if (documents.signatureVideo) {\n submissionRequest.customerData.signatureData.signatureVideo =\n documents.signatureVideo\n }\n }\n if (additionalDocuments) {\n submissionRequest.customerData.additionalDocuments =\n additionalDocuments.map((d) => ({\n ...d,\n additionalDocument: JSON.stringify({\n ...(d.additionalDocument as Record<string, string>),\n uniqueId: submissionRequest.additionalData.uniqueRequestId,\n }),\n }))\n }\n if (documents.idCaptureVideo) {\n submissionRequest.customerData.biometricData ||= {}\n submissionRequest.customerData.biometricData.videoData =\n documents.idCaptureVideo\n }\n if (documents.idCaptureVideoAudio) {\n submissionRequest.customerData.biometricData ||= {}\n submissionRequest.customerData.biometricData.voiceData =\n documents.idCaptureVideoAudio\n submissionRequest.customerData.biometricData.voiceStartTime =\n idCaptureVideoAudioStartsAt ?? undefined\n submissionRequest.customerData.biometricData.expectedAudioText =\n expectedAudioText ?? undefined\n }\n if (documents.idCaptureVideoIdFrontImage) {\n submissionRequest.customerData.idData.videoIdImageFront =\n documents.idCaptureVideoIdFrontImage\n }\n if (documents.idCaptureVideoIdBackImage) {\n submissionRequest.customerData.idData.videoIdImageBack =\n documents.idCaptureVideoIdBackImage\n }\n\n attachMetadataToRequest(submissionRequest, {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n })\n\n if (onBeforeSubmit) {\n const onBeforeSubmitResult = await onBeforeSubmit(submissionRequest)\n if (onBeforeSubmitResult) submissionRequest = onBeforeSubmitResult\n }\n\n return submissionRequest\n }, [\n action,\n additionalDocuments,\n bypassAgeValidation,\n bypassNameMatching,\n cardData,\n companyId,\n deduplicationEnabled,\n deduplicationSynchronous,\n documentServiceUrl,\n enrollmentId,\n expectedAudioText,\n geolocationResult,\n idBackCaptureAttempts,\n idBackImage,\n idBackImageRequired,\n idCaptureVideoAudioStartsAt,\n idCaptureVideoAudioUrl,\n idCaptureVideoIdBackImage,\n idCaptureVideoIdFrontImage,\n idCaptureVideoUrl,\n idFrontCaptureAttempts,\n idFrontImage,\n idImageResolutionCheck,\n manualReviewRequired,\n needImmediateResponse,\n onBeforeSubmit,\n passportImage,\n personalData,\n selfieCaptureAttempts,\n selfieImage,\n signatureData,\n signatureVideoUrl,\n uploadDocument,\n verifyIdWithExternalDatabases,\n webhooksClientTraceId,\n webhooksEnabled,\n webhooksFireOnReview,\n webhooksSendInputImages,\n webhooksSendProcessedImages,\n webhooksStripSpecialCharacters,\n ])\n\n const defaultOnSubmit = useCallback(async () => {\n if (action === SubmissionAction.NONE) {\n const submissionResponse = {\n status: { statusCode: '000' },\n resultData: {},\n }\n setSubmissionStatus(SubmissionStatus.SUBMITTED)\n setSubmissionResponse(submissionResponse)\n return submissionResponse\n }\n\n setSubmissionStatus(SubmissionStatus.SUBMITTING)\n\n try {\n const payload = await buildSubmissionPayload()\n const host = submissionUrl || determineSubmissionHost(environment)\n const endpoint = determineSubmissionEndpoint(\n action,\n !!(idFrontImage || idBackImage || passportImage),\n !!selfieImage,\n )\n const response = await fetch(host + endpoint, {\n method: 'POST',\n headers: apiHeaders(sessionId, sendBase64DocumentsInSwaggerProxy),\n body: JSON.stringify(payload),\n }).catch((e) => {\n throw new NetworkError(e.message)\n })\n\n if (!response || !response.ok) {\n const statusMessage = await response?.text()\n\n if (!statusMessage || statusMessage === 'Load failed')\n throw new NetworkError(statusMessage)\n\n throw new SubmissionError({\n statusCode: response?.statusText ?? '???',\n statusMessage,\n })\n }\n\n const submissionResponse = await response.json()\n if (submissionResponse.status.statusCode !== '000') {\n throw new SubmissionError(submissionResponse.status)\n }\n\n setSubmissionRequest(payload)\n setSubmissionResponse(submissionResponse)\n setSubmissionStatus(SubmissionStatus.SUBMITTED)\n onResponseReceived?.(submissionResponse, payload)\n return submissionResponse\n } catch (e) {\n const err = e as Error\n setSubmissionStatus(SubmissionStatus.FAILED)\n setSubmissionError(\n e instanceof SubmissionError || e instanceof NetworkError\n ? e\n : err.message === 'Load failed'\n ? new NetworkError()\n : new SubmissionError({\n statusCode: '',\n statusMessage: err.message,\n }),\n )\n setRetrySubmission(() =>\n ['VERIFY', 'IDENTIFY'].includes(action) ? () => null : defaultOnSubmit,\n )\n onRequestFailure?.(err)\n throw err\n }\n }, [\n action,\n buildSubmissionPayload,\n submissionUrl,\n environment,\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n sessionId,\n sendBase64DocumentsInSwaggerProxy,\n onResponseReceived,\n onRequestFailure,\n ])\n\n const submit = useCallback(async () => {\n if (onSubmit) return onSubmit(await buildSubmissionPayload())\n return await defaultOnSubmit()\n }, [buildSubmissionPayload, defaultOnSubmit, onSubmit])\n\n const checkLiveness = useCallback(\n async (imageDataUrl: string) => {\n try {\n let request: LivenessCheckRequest = {\n securityData: { userName: '', password: '', merchantId: 0 },\n customerData: {\n biometricData: { selfie: await dataUrlToBase64(imageDataUrl) },\n },\n additionalData: {\n uniqueRequestId: new Date().getTime().toString(),\n stripSpecialCharacters: webhooksStripSpecialCharacters ? 'Y' : 'N',\n estimateAge: 'N',\n predictGender: 'N',\n },\n }\n\n if (clientRequestID) {\n request.additionalData.clientRequestID = clientRequestID\n }\n\n if (idCardForFaceMatch) {\n request.customerData.idData = { idImageFront: idCardForFaceMatch }\n // TODO: remove when fixed\n request.customerData.additionalData = {\n uniqueRequestId: request.additionalData.uniqueRequestId,\n }\n }\n\n attachMetadataToRequest(request, {\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n })\n\n setLivenessCheckRequest(request)\n\n if (onBeforeLivenessCheck) {\n const onBeforeLivenessCheckResult =\n await onBeforeLivenessCheck(request)\n if (onBeforeLivenessCheckResult) request = onBeforeLivenessCheckResult\n }\n\n const host = submissionUrl || determineSubmissionHost(environment)\n const endpoint = liveCheckEndpoint(!!idCardForFaceMatch)\n const response = await fetch(host + endpoint, {\n method: 'POST',\n headers: apiHeaders(sessionId, sendBase64DocumentsInSwaggerProxy),\n body: JSON.stringify(request),\n }).catch((e) => {\n throw new NetworkError(e.message)\n })\n\n if (!response.ok) {\n const statusMessage = await response.text()\n\n if (!statusMessage || statusMessage === 'Load failed')\n throw new NetworkError(statusMessage)\n\n throw new SubmissionError({\n statusCode: response.statusText,\n statusMessage,\n })\n }\n\n const submissionResponse = await response.json()\n if (submissionResponse.status.statusCode !== '000') {\n throw new SubmissionError(submissionResponse.status)\n }\n\n setSubmissionResponse(submissionResponse)\n return submissionResponse\n } catch (e) {\n const err = e as Error\n setSubmissionStatus(SubmissionStatus.FAILED)\n setSubmissionError(\n e instanceof SubmissionError || e instanceof NetworkError\n ? e\n : err.message === 'Load failed'\n ? new NetworkError()\n : new SubmissionError({\n statusCode: '',\n statusMessage: err.message,\n }),\n )\n // the face liveness routine will call again, so don't repeat the call here.\n setRetrySubmission(() => () => null)\n onRequestFailure?.(err)\n throw err\n }\n },\n [\n webhooksStripSpecialCharacters,\n idCardForFaceMatch,\n selfieCaptureAttempts,\n idFrontCaptureAttempts,\n idBackCaptureAttempts,\n geolocationResult,\n onBeforeLivenessCheck,\n submissionUrl,\n environment,\n sessionId,\n onRequestFailure,\n ],\n )\n\n const retryLocationAccess = useCallback(() => {\n setGeolocationAttempts((n) => n + 1)\n }, [])\n\n useEffect(() => {\n if (!geolocationEnabled) return\n\n log('making geolocation attempt', geolocationAttempts)\n navigator.geolocation.getCurrentPosition(\n (position) => {\n setGeolocationResult(position)\n setGeolocationBlocked(false)\n },\n (positionError) => {\n if (positionError.code === 1) {\n setGeolocationBlocked(true)\n } else {\n throw new Error(positionError.message)\n }\n },\n )\n }, [geolocationAttempts, geolocationEnabled, geolocationRequired])\n\n const onRetry = useCallback(() => {\n if (!retrySubmission) return\n setSubmissionError(null)\n setSubmissionStatus(SubmissionStatus.READY)\n retrySubmission()\n }, [retrySubmission])\n\n const value: SubmissionState = {\n submit,\n submissionStatus,\n submissionRequest,\n submissionResponse,\n submissionError,\n submissionEnvironment: environment,\n\n idFrontImage,\n idBackImage,\n passportImage,\n selfieImage,\n signatureData,\n signatureVideoUrl,\n idCaptureVideoUrl,\n idCaptureVideoIdFrontImage,\n idCaptureVideoIdBackImage,\n idCaptureVideoAudioUrl,\n idCaptureVideoAudioStartsAt,\n additionalDocuments,\n\n setIdFrontImage,\n setIdBackImage,\n setPassportImage,\n setSelfieImage,\n setSignatureData,\n setSignatureVideoUrl,\n setIdCaptureVideoUrl,\n setIdCaptureVideoIdFrontImage,\n setIdCaptureVideoIdBackImage,\n setIdCaptureVideoAudioUrl,\n setIdCaptureVideoAudioStartsAt,\n setExpectedAudioText,\n setAdditionalDocuments,\n\n uploadDocument,\n\n logIdFrontCaptureAttempt,\n logIdBackCaptureAttempt,\n logSelfieCaptureAttempt,\n\n livenessCheckRequest,\n checkLiveness,\n retryLocationAccess,\n }\n\n return (\n <SubmissionContext.Provider value={value}>\n {geolocationRequired && geolocationBlocked ? (\n <GeolocationAccessDeniedOverlay />\n ) : (\n children\n )}\n\n {submissionError && (\n <SubmissionErrorOverlay error={submissionError} onRetry={onRetry} />\n )}\n </SubmissionContext.Provider>\n )\n}\n\nfunction createUpload(blob: Blob, options: UploadOptions): Upload {\n const UploadType =\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof window.tus !== 'undefined' ? window.tus.Upload : Upload\n\n return new UploadType(blob, options)\n}\n\nfunction convertBase64ToBlob(base64Image: string) {\n // Split into two parts\n const parts = base64Image.split(';base64,')\n\n // Hold the content type\n const imageType = parts[0].split(':')[1]\n\n // Decode Base64 string\n const decodedData = window.atob(parts[1])\n\n // Create UNIT8ARRAY of size same as row data length\n const uInt8Array = new Uint8Array(decodedData.length)\n\n // Insert all character code into uInt8Array\n for (let i = 0; i < decodedData.length; ++i) {\n uInt8Array[i] = decodedData.charCodeAt(i)\n }\n\n // Return BLOB image after conversion\n return new Blob([uInt8Array], { type: imageType })\n}\n","import { getNativeBarcodeReaderResult, PDF417DetectionResult } from './Native'\nimport { getZxingBarcodeReaderResult } from './ZXing'\nimport log from '../utils/logger'\nimport { DetectedObjectBox } from '../models/DocumentDetection'\n\nexport function supportsNativeBarcodeScanning(): boolean {\n return 'BarcodeDetector' in window\n}\n\nexport function scanBarcode(\n blob: Blob,\n box?: DetectedObjectBox,\n): Promise<PDF417DetectionResult | null> {\n return new Promise((resolve) => {\n const image = new Image()\n image.onload = async () => {\n if (supportsNativeBarcodeScanning()) {\n const result = await getNativeBarcodeReaderResult(image)\n log('native result', result, `${image.width}x${image.height}`)\n if (result.length > 0) {\n resolve({ ...result[0], Source: 'native' })\n } else {\n resolve(null)\n }\n } else {\n const shouldRotate = (box?.width ?? 0) < (box?.height ?? 0)\n const result = await getZxingBarcodeReaderResult(image, shouldRotate)\n log('zxing result', result)\n if (result.length > 0) {\n resolve({ ...result[0], Source: 'zxing' })\n } else {\n resolve(null)\n }\n }\n }\n image.src = URL.createObjectURL(blob)\n })\n}\n","export type Frame =\n | ImageBitmap\n | HTMLVideoElement\n | HTMLImageElement\n | HTMLCanvasElement\n\nexport function getFrameDimensions(frame: Frame): [number, number] {\n let frameWidth = frame.width,\n frameHeight = frame.height\n\n if (frame instanceof HTMLImageElement) {\n frameWidth = frame.naturalWidth\n frameHeight = frame.naturalHeight\n }\n\n if (frame instanceof HTMLVideoElement) {\n frameWidth = frame.videoWidth\n frameHeight = frame.videoHeight\n }\n\n return [frameWidth, frameHeight]\n}\n","import styled from 'styled-components'\nimport { Frame, getFrameDimensions } from '../../lib/utils/getFrameDimensions'\n\nexport const InvisibleCanvas = styled.canvas`\n display: none;\n`\n\nexport function drawToCanvas(\n canvas: HTMLCanvasElement | null,\n frame: Frame,\n width?: number,\n height?: number,\n): void {\n if (!canvas) return\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n if (!width || !height) {\n const [frameWidth, frameHeight] = getFrameDimensions(frame)\n width ||= frameWidth\n height ||= frameHeight\n }\n canvas.width = width\n canvas.height = height\n ctx.drawImage(frame, 0, 0, width, height)\n}\n\nexport function clearCanvas(canvas: HTMLCanvasElement | null) {\n canvas?.getContext('2d')?.clearRect(0, 0, canvas?.width, canvas?.height)\n}\n","import {\n MutableRefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { getPlatform } from '../utils/platform'\nimport { drawToCanvas } from '../../components/common/InvisibleCanvas'\nimport log, { error } from '../utils/logger'\n\nexport type Camera = {\n stream: MediaStream\n isRearFacing: boolean\n release: () => void\n label: string\n width: number\n height: number\n}\n\nexport type CameraResolution = 'LOW' | 'MID' | 'MAX'\n\nlet choosingCamera = false\n\nexport async function selectAndOpenCamera(\n resolution: CameraResolution = 'MID',\n): Promise<Camera> {\n if (choosingCamera) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (!choosingCamera) {\n clearInterval(interval)\n resolve(null)\n }\n }, 10)\n })\n }\n\n choosingCamera = true\n\n const video: MediaTrackConstraints = {\n facingMode: { ideal: 'environment' },\n focusMode: 'continuous',\n }\n if (resolution === 'LOW') {\n video.width = { ideal: 640 }\n } else if (resolution === 'MID') {\n video.width = { ideal: 1920 }\n }\n\n const stream = await navigator.mediaDevices.getUserMedia({ video })\n let mediaTrackSettings = stream.getVideoTracks()[0].getSettings()\n const camera: Camera = {\n // you only get the labels for each camera if you call getUserMedia first.\n stream,\n isRearFacing: false,\n release: () => {\n camera.stream.getTracks().forEach((track) => track.stop())\n },\n width: mediaTrackSettings.width ?? 0,\n height: mediaTrackSettings.height ?? 0,\n label: '',\n }\n\n let chosenLabel = ''\n let bestResDevice: [string, number, number] = ['', 0, 0]\n const videoDevices = (await navigator.mediaDevices.enumerateDevices()).filter(\n (deviceInfo) => deviceInfo.kind === 'videoinput',\n )\n\n await Promise.all(\n videoDevices.map(async (deviceInfo) => {\n log('checking out', deviceInfo.label, resolution)\n const { width: maxWidth, height: maxHeight } =\n await getVideoDeviceMaxDimensions(deviceInfo)\n log('device', deviceInfo.label, 'max dimensions', {\n maxWidth,\n maxHeight,\n })\n if (maxWidth > bestResDevice[1]) {\n bestResDevice = [deviceInfo.deviceId, maxWidth, maxHeight]\n }\n if (deviceInfo.label) {\n const label = deviceInfo.label.toLocaleLowerCase().split(' ').join('')\n if (\n labelMatches(label, rearLabels) &&\n !labelMatches(label, backUltraWideLabels)\n ) {\n camera.label = label\n camera.isRearFacing = true\n video.deviceId = deviceInfo.deviceId\n chosenLabel = label\n if (resolution === 'MAX') {\n log('going for max!', `${maxWidth}x${maxHeight}`)\n video.width = { exact: maxWidth }\n video.height = { exact: maxHeight }\n }\n }\n }\n }),\n )\n\n if (resolution === 'MAX' && chosenLabel === '') {\n chosenLabel = bestResDevice[0]\n video.deviceId = bestResDevice[0]\n video.width = { ideal: bestResDevice[1] }\n video.height = { ideal: bestResDevice[2] }\n }\n log('chose device', chosenLabel, resolution)\n\n camera.label = chosenLabel\n\n if (video.deviceId) {\n camera.release()\n camera.stream = await navigator.mediaDevices.getUserMedia({ video })\n mediaTrackSettings = camera.stream.getVideoTracks()[0].getSettings()\n camera.width = mediaTrackSettings.width ?? 0\n camera.height = mediaTrackSettings.height ?? 0\n }\n\n log('SETTINGS', camera.stream.getVideoTracks()[0].getSettings())\n\n choosingCamera = false\n return camera\n}\n\n// interface HasCapabilities {\n// getCapabilities?: () => {\n// width: { max: number }\n// height: { max: number }\n// }\n// }\nexport async function getVideoDeviceMaxDimensions(\n deviceInfo: MediaDeviceInfo,\n): Promise<{\n width: number\n height: number\n}> {\n const best = await bestAvailableResolution(deviceInfo)\n if (!best) return { width: 1, height: 1 }\n return { width: best.width, height: best.height }\n // try {\n // const {\n // width: { max: width },\n // height: { max: height },\n // } = (deviceInfo as HasCapabilities).getCapabilities?.() ?? {\n // width: { max: 1920 },\n // height: { max: 1080 },\n // }\n //\n // return { width, height }\n // } catch (e) {\n // error(e)\n // return { width: 1, height: 1 }\n // }\n}\n\ntype Resolution = {\n label: string\n width: number\n height: number\n ratio: string\n}\nexport const quickScan: Resolution[] = [\n // {\n // label: '4K(UHD)',\n // width: 3840,\n // height: 2160,\n // ratio: '16:9',\n // },\n {\n label: '1080p(FHD)',\n width: 1920,\n height: 1080,\n ratio: '16:9',\n },\n {\n label: 'UXGA',\n width: 1600,\n height: 1200,\n ratio: '4:3',\n },\n {\n label: '720p(HD)',\n width: 1280,\n height: 720,\n ratio: '16:9',\n },\n {\n label: 'SVGA',\n width: 800,\n height: 600,\n ratio: '4:3',\n },\n {\n label: 'VGA',\n width: 640,\n height: 480,\n ratio: '4:3',\n },\n {\n label: '360p(nHD)',\n width: 640,\n height: 360,\n ratio: '16:9',\n },\n {\n label: 'CIF',\n width: 352,\n height: 288,\n ratio: '4:3',\n },\n {\n label: 'QVGA',\n width: 320,\n height: 240,\n ratio: '4:3',\n },\n {\n label: 'QCIF',\n width: 176,\n height: 144,\n ratio: '4:3',\n },\n {\n label: 'QQVGA',\n width: 160,\n height: 120,\n ratio: '4:3',\n },\n]\n\nasync function bestAvailableResolution(\n deviceInfo: MediaDeviceInfo,\n): Promise<Resolution | null> {\n for (let i = 0; i !== quickScan.length; ++i) {\n if (await isResolutionAvailable(quickScan[i], deviceInfo)) {\n return quickScan[i]\n }\n }\n\n return null\n}\n\nfunction isResolutionAvailable(\n candidate: Resolution,\n deviceInfo: MediaDeviceInfo,\n): Promise<boolean> {\n return new Promise((resolve) => {\n // const devices = []\n // const deviceInfos = await navigator.mediaDevices.enumerateDevices()\n //\n // for (let i = 0; i !== deviceInfos.length; ++i) {\n // const deviceInfo = deviceInfos[i]\n // if (deviceInfo.kind === 'videoinput') {\n // devices.push(deviceInfo)\n // }\n // }\n\n const video = document.createElement('video')\n const windowWithStream = window as unknown as { stream: MediaStream }\n const existingStream = windowWithStream.stream\n if (existingStream) {\n existingStream.getTracks().forEach((track) => {\n track.stop()\n })\n }\n\n const constraints = {\n audio: false,\n video: {\n deviceId: deviceInfo.deviceId,\n // ? { exact: deviceInfo.deviceId }\n // : undefined,\n width: { exact: candidate.width }, //new syntax\n height: { exact: candidate.height }, //new syntax\n },\n }\n\n setTimeout(\n () => {\n navigator.mediaDevices\n .getUserMedia(constraints)\n .then(gotStream)\n .catch((error) => {\n log('getUserMedia error!', error, candidate)\n resolve(false)\n })\n },\n windowWithStream.stream ? 200 : 0,\n ) //official examples had this at 200\n\n function gotStream(mediaStream: MediaStream) {\n //change the video dimensions\n log(\n 'Display size for ' +\n candidate.label +\n ': ' +\n candidate.width +\n 'x' +\n candidate.height,\n )\n video.width = candidate.width\n video.height = candidate.height\n\n windowWithStream.stream = mediaStream // make globally available\n video.srcObject = mediaStream\n\n resolve(true)\n }\n })\n}\n\nexport type FacingMode = 'user' | 'environment' | 'left' | 'right'\n\nexport async function listAvailableCameras(\n facingMode?: FacingMode,\n requestMicAccess: boolean = false,\n): Promise<MediaDeviceInfo[]> {\n // The first thing we need to do is call getUserMedia() so that the subsequent call to enumerateDevices() works.\n let cameraEnumerationStream: MediaStream | null =\n await navigator.mediaDevices.getUserMedia({\n video: { facingMode: { exact: facingMode } },\n audio: requestMicAccess,\n })\n\n // This lists all available cameras attached to the user's device.\n const videoDevices = (await navigator.mediaDevices.enumerateDevices()).filter(\n ({ kind }) => kind === 'videoinput',\n )\n\n // Release the access to the user's camera that we obtained for enumeration purposes.\n cameraEnumerationStream.getVideoTracks().forEach((track) => {\n track.enabled = false\n track.stop()\n })\n\n cameraEnumerationStream = null\n\n return videoDevices\n}\n\nconst frontLabels = [\n 'front',\n 'avant',\n 'anteriore',\n 'cameraaanvoorzijde',\n 'kamerapåframsidan',\n 'forsidekamera',\n 'kamerapåforsiden',\n 'aparatprzedni',\n 'etukamera',\n 'kameradepan',\n 'ÖnKamera',\n 'cameramặttrước',\n 'camerăfață',\n 'prednákamera',\n 'prednjakamera',\n 'előlapikamera',\n 'přednífotoaparát',\n 'μπροστινήκάμερα',\n 'переднякамера',\n 'передняякамера',\n 'преднакамера',\n 'алдыңғыкамера',\n 'מצלמה קדמית',\n 'الكاميرا الأمامية',\n 'फ़्रंटकैमरा',\n '前置相机',\n '前置鏡頭',\n '前面カメラ',\n '전면카메라',\n 'กล้องด้านหน้า',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\nconst rearLabels = [\n 'back',\n 'rear',\n 'posterior',\n 'trasera',\n 'traseira',\n 'arrière',\n 'rückkamera',\n 'fotocamera(posteriore)',\n 'cameraaanachterzijde',\n 'kamerapåbaksidan',\n 'kamerapåbaksiden',\n 'bagsidekamera',\n 'aparattylny',\n 'takakamera',\n 'arkakamera',\n 'kamerabelakang',\n 'cameramặtsau',\n 'camerăspate',\n 'stražnjakamera',\n 'zadnákamera',\n 'hátoldalikamera',\n 'zadnífotoaparát',\n 'πίσωκάμερα',\n 'заднякамера',\n 'Задняякамера',\n 'заднакамера',\n 'артқыкамера',\n 'מצלמה אחורית',\n 'الكاميرا الخلفية',\n 'बैककैमरा',\n '后置相机',\n '後置鏡頭',\n '背面カメラ',\n '후면카메라',\n 'กล้องด้านหลัง',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\nconst backUltraWideLabels = [\n 'backdualwidecamera',\n 'backultrawidecamera',\n 'ultraampliaposterior',\n 'ultra-angulartraseira',\n 'ultragrandeangulartraseira',\n 'ultragrandangle',\n 'ultragranangular',\n 'ultra-weitwinkelkamera',\n 'ultra-grandangolo',\n 'ultrabredecameraaanachterzijde',\n 'ultravidvinkelkamerapåbaksidan',\n 'ultravidvinkelkameraetpåbagsiden',\n 'ultravidvinkelkamerabak',\n 'ultragenişkameraarkayüzü',\n 'ultralaajakulmainentakakamera',\n 'tylnyaparatultraszerokokątny',\n 'cameracựcrộngmặtsau',\n 'camerăcuobiectivultra‑superangularspate',\n 'ultraszéleslátószögűkamera',\n 'kameraultralebarbelakang',\n 'stražnjaultraširokakamera',\n 'zadníultraširokoúhlýfotoaparát',\n 'ultraširokouhlá',\n 'πίσωυπερευρείακάμερα',\n 'заднянадширококутнакамера',\n 'Задняясверхширокоугольнаякамера',\n 'Задна свръх широкоъгълна камера',\n 'артқыультракеңбұрыштыкамера',\n 'מצלמה אולטרה רחבה אחורית',\n 'كاميرا خلفية عريضة جدًا',\n 'बैकअल्ट्रावाइडकैमरा',\n '后置超广角相机',\n '後置超廣角鏡頭相機',\n '背面超広角カメラ',\n '후면울트라와이드카메라',\n 'กล้องด้านหลังอัลตร้าไวด์',\n].map((s) => s.toLocaleLowerCase().split(' ').join(''))\n\nconst labelMatches = (\n labelOrDevice: string | MediaDeviceInfo,\n labelSetOrLabel: string | string[],\n) => {\n const label =\n labelOrDevice instanceof MediaDeviceInfo\n ? getDeviceLabel(labelOrDevice)\n : labelOrDevice\n\n const labelSet =\n typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel\n\n return labelSet.some((l) => label.includes(l))\n}\n\nconst getDeviceLabel = (deviceInfo: MediaDeviceInfo) =>\n deviceInfo.label.toLocaleLowerCase().split(' ').join('')\n\nlet currentCamera: Camera | undefined\nlet currentAudioStream: MediaStream | undefined\n\nexport function obtainCameraAccess(\n stream: MediaStream,\n deviceLabel: string,\n video?: HTMLVideoElement | null,\n): Camera {\n releaseCameraAccess()\n\n log('obtaining camera access...')\n let { width, height } = stream.getVideoTracks()[0].getSettings()\n const label = deviceLabel.toLocaleLowerCase().split(' ').join('')\n const isRearFacing = labelMatches(label, [\n ...rearLabels,\n ...backUltraWideLabels,\n 'iphone',\n ])\n const release = () => {\n stream.getTracks().forEach((track) => {\n track.enabled = false\n track.stop()\n })\n if (video) {\n video.pause()\n video.srcObject = null\n video.src = ''\n }\n }\n\n width ||= 0\n height ||= 0\n\n currentCamera = {\n label: deviceLabel,\n stream,\n width,\n height,\n isRearFacing,\n release,\n }\n if (video) video.srcObject = stream\n\n return currentCamera\n}\n\nexport function releaseCameraAccess() {\n if (!currentCamera) return\n log('releasing camera access...')\n currentCamera.release()\n currentCamera = undefined\n}\n\nexport function releaseMicrophoneAccess() {\n if (!currentAudioStream) return\n log('releasing microphone access...')\n currentAudioStream.stop?.()\n currentAudioStream.getAudioTracks().forEach((t) => {\n t.stop?.()\n })\n currentAudioStream = undefined\n}\n\ntype UsePreferredCaptureDeviceParams = {\n requestAccessAutomatically?: boolean\n preferFrontFacingCamera?: boolean\n preferContinuityCamera?: boolean\n requireMicrophoneAccess?: boolean\n maxVideoWidth?: number\n maxFps?: number\n debugMode?: boolean\n}\n\nexport type CaptureDevice = {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n videoDevice: MediaDeviceInfo | null\n videoLoaded: boolean\n setVideoLoaded: (value: boolean) => void\n onVideoUnmounted: (videoElement: HTMLVideoElement) => void\n cameraRef: MutableRefObject<Camera | null>\n cameraReady: boolean\n cameraAccessDenied: boolean\n requestCameraAccess: () => void\n releaseCameraAccess: () => void\n iphoneContinuityCameraAvailable: boolean\n iphoneContinuityCameraAllowed: boolean\n setIphoneContinuityCameraAllowed: (value: boolean) => void\n takePhoto: () => Promise<Blob | null>\n audioStream: MediaStream | null\n microphoneReady: boolean\n microphoneAccessDenied: boolean\n requestMicrophoneAccess: () => void\n}\n\nexport function usePreferredCaptureDevice({\n requestAccessAutomatically = true,\n preferFrontFacingCamera = false,\n preferContinuityCamera = true,\n requireMicrophoneAccess = false,\n maxVideoWidth = 1920,\n maxFps,\n debugMode = false,\n}: UsePreferredCaptureDeviceParams = {}): CaptureDevice {\n const videoRef = useRef<HTMLVideoElement | null>(null)\n const videoRefStack = useRef<HTMLVideoElement[]>([])\n const cameraRef = useRef<Camera | null>(null)\n const [cameraReady, setCameraReady] = useState(false)\n const [microphoneReady, setMicrophoneReady] = useState(false)\n const [videoDevice, setVideoDevice] = useState<MediaDeviceInfo | null>(null)\n const [audioStream, setAudioStream] = useState<MediaStream | null>(null)\n const [videoLoaded, setVideoLoaded] = useState(false)\n const [iphoneContinuityCameraAvailable, setIphoneContinuityCameraAvailable] =\n useState(false)\n const [iphoneContinuityCameraAllowed, setIphoneContinuityCameraAllowed] =\n useState(preferContinuityCamera)\n const [iphoneContinuityCameraDenied, setIphoneContinuityCameraDenied] =\n useState(false)\n const [cameraAccessDenied, setCameraAccessDenied] = useState(false)\n const [microphoneAccessDenied, setMicrophoneAccessDenied] = useState(false)\n\n const videoRefElement = videoRef.current\n useEffect(\n function pushVideoRefToStackWhenChanged() {\n // proceed if the video element being mounted is not already at the top of the videoRefStack.\n const topOfStack = videoRefStack.current.slice(-1)[0]\n if (videoRefElement && videoRefElement !== topOfStack) {\n log('adding video to stack', videoRefElement)\n videoRefStack.current.push(videoRefElement)\n }\n },\n [videoRefElement],\n )\n\n const onVideoUnmounted = useCallback((videoElement: HTMLVideoElement) => {\n log('removing video from stack', videoElement)\n videoRefStack.current = videoRefStack.current.filter(\n (v) => v !== videoElement,\n )\n\n videoRef.current = videoRefStack.current.slice(-1)[0] // top of stack.\n log('new videoRef is', videoRef.current)\n }, [])\n\n useEffect(\n function resetCameraOnContinuityPreferenceChanged() {\n if (debugMode) {\n log(\n 'iphone continuity camera allowed changed',\n iphoneContinuityCameraAllowed,\n )\n }\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n },\n [debugMode, iphoneContinuityCameraAllowed],\n )\n\n // NOTE: the bound callback function here is called requestCameraAccess, because\n // it initiates the useEffect chain that results in camera access being requested\n // (requestCameraAccessAutomatically -> chooseFromAvailableCameras -> accessChosenCamera).\n //\n // We chose to title the inner function \"chooseFromAvailableCameras\" because\n // that's all it literally does -- the available cameras are enumerated, and then\n // the result is parsed to decide which one we like best, which is then passed to\n // setVideoDevice, which causes accessChosenCamera to trigger.\n //\n // I am not a huge fan of getUserMedia's design -- you need to call it twice in order\n // to select the \"best\" camera for your application's purposes.\n const requestCameraAccess = useCallback(\n async function chooseFromAvailableCameras() {\n setCameraReady(false)\n setCameraAccessDenied(false)\n\n try {\n let availableCameras = await listAvailableCameras()\n let selectedCamera: MediaDeviceInfo | undefined\n\n if (debugMode) {\n log('availableCameras', availableCameras)\n }\n\n const platform = getPlatform()\n if (debugMode) {\n log('platformDetails', platform)\n }\n if (\n !iphoneContinuityCameraDenied &&\n (!platform?.os || platform.os.family === 'OS X')\n ) {\n const iphoneContinuityCamera = availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'iphone'),\n )\n setIphoneContinuityCameraAvailable(!!iphoneContinuityCamera)\n if (iphoneContinuityCamera && iphoneContinuityCameraAllowed) {\n selectedCamera = iphoneContinuityCamera\n }\n } else if (\n platform?.os?.family === 'Android' ||\n availableCameras.every((c) => c.label.startsWith('camera2 '))\n ) {\n availableCameras = availableCameras.sort((a, b) =>\n a.label.toLowerCase().localeCompare(b.label.toLowerCase()),\n )\n if (debugMode) {\n log('cameras have been sorted', availableCameras)\n }\n }\n\n if (preferFrontFacingCamera) {\n selectedCamera = availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, frontLabels),\n )\n }\n\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'backtriplecamera'),\n )\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, 'backdualcamera'),\n )\n selectedCamera ||= availableCameras.find(\n (deviceInfo) =>\n labelMatches(deviceInfo, rearLabels) &&\n !labelMatches(deviceInfo, backUltraWideLabels),\n )\n\n selectedCamera ||= availableCameras.find((deviceInfo) =>\n labelMatches(deviceInfo, rearLabels),\n )\n\n // on iOS, the front facing camera always is at the first position in the list, so we skip it if all else fails.\n if (\n !preferFrontFacingCamera &&\n platform?.os?.family === 'iOS' &&\n availableCameras.length > 0\n ) {\n selectedCamera ||= availableCameras[1]\n }\n\n selectedCamera ||= availableCameras[0]\n\n if (debugMode) log('selectedCamera', selectedCamera)\n setVideoDevice(selectedCamera)\n } catch (e) {\n if ((e as { name: string }).name === 'NotAllowedError') {\n error('camera access has been blocked by the user', e)\n setCameraAccessDenied(true)\n } else {\n error('camera access encountered some other error', e)\n throw e\n }\n }\n },\n [\n debugMode,\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraDenied,\n preferFrontFacingCamera,\n ],\n )\n\n useEffect(\n function requestCameraAccessAutomatically() {\n if (requestAccessAutomatically && !cameraAccessDenied) {\n requestCameraAccess().catch(error)\n }\n },\n [cameraAccessDenied, requestAccessAutomatically, requestCameraAccess],\n )\n\n useEffect(\n function accessChosenCamera() {\n if (!videoDevice) return\n\n const cleanup = () => {\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n }\n\n if (!navigator.mediaDevices?.getUserMedia) return cleanup\n ;(async () => {\n const constraints: MediaStreamConstraints = {\n audio: false,\n video: {\n deviceId: { exact: videoDevice.deviceId },\n width: { ideal: maxVideoWidth },\n aspectRatio: 1.777777778,\n frameRate: {},\n } satisfies MediaTrackConstraints,\n }\n\n if (maxFps) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n constraints.video.frameRate = { max: maxFps }\n }\n\n let stream: MediaStream | null = null\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraints)\n } catch (e) {\n if ((e as { name: string }).name === 'NotAllowedError') {\n if (iphoneContinuityCameraAllowed) {\n setIphoneContinuityCameraAvailable(false)\n setIphoneContinuityCameraDenied(true)\n } else {\n setCameraAccessDenied(true)\n }\n return\n }\n }\n\n if (!stream) {\n try {\n stream = await navigator.mediaDevices.getUserMedia({\n audio: false,\n video: true,\n })\n\n log('opened stream with no width and height constraints')\n } catch (e) {\n log('cannot open stream at all')\n }\n }\n\n if (!stream) {\n throw new Error('failed to open camera')\n }\n\n const handleStreamEnded = () => {\n if (\n iphoneContinuityCameraAvailable &&\n iphoneContinuityCameraAllowed\n ) {\n log('someone unplugged the continuity camera')\n releaseCameraAccess()\n cameraRef.current = null\n setIphoneContinuityCameraAvailable(false)\n setIphoneContinuityCameraDenied(true)\n setVideoDevice(null)\n } else {\n log('someone unplugged the webcam')\n releaseCameraAccess()\n cameraRef.current = null\n setVideoLoaded(false)\n setCameraAccessDenied(true)\n }\n }\n\n videoRef.current?.addEventListener('ended', handleStreamEnded)\n stream.getVideoTracks().forEach((track) => {\n track.onended = handleStreamEnded\n })\n\n cameraRef.current = obtainCameraAccess(\n stream,\n videoDevice.label,\n videoRef.current,\n )\n })()\n\n return cleanup\n },\n [\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraAvailable,\n maxFps,\n maxVideoWidth,\n videoDevice,\n ],\n )\n\n useEffect(\n function triggerCameraReady() {\n // TODO: in the future let's evaluate whether we can simplify this to just\n // setCameraReady(!!videoDevice && videoLoaded) -- we are wondering whether\n // we somehow depend on this being set twice.\n\n setCameraReady(false)\n\n if (videoDevice && videoLoaded) {\n setCameraReady(videoDevice && videoLoaded)\n }\n },\n [videoLoaded, videoDevice],\n )\n\n const requestMicrophoneAccess = useCallback(\n async function _requestMicrophoneAccess() {\n setMicrophoneReady(false)\n setMicrophoneAccessDenied(false)\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n video: false,\n })\n currentAudioStream = stream\n setAudioStream(stream)\n setMicrophoneReady(true)\n\n stream.getAudioTracks().forEach((track) => {\n track.onended = () => {\n setMicrophoneAccessDenied(true)\n }\n })\n } catch (e) {\n setMicrophoneAccessDenied(true)\n }\n },\n [],\n )\n\n useEffect(\n function requestMicrophoneAccessIfNeeded() {\n if (!requireMicrophoneAccess || microphoneAccessDenied) return\n\n requestMicrophoneAccess().catch(error)\n\n return () => {\n releaseMicrophoneAccess()\n setAudioStream(null)\n setMicrophoneReady(false)\n }\n },\n [microphoneAccessDenied, requestMicrophoneAccess, requireMicrophoneAccess],\n )\n\n const takePhoto = useCallback(\n async function _takePhoto(): Promise<Blob | null> {\n if (!cameraRef.current) return null\n if (typeof ImageCapture !== 'undefined') {\n return await new ImageCapture(\n cameraRef.current.stream.getTracks()[0],\n ).takePhoto()\n }\n\n if (!videoRef.current) return null\n const canvas = document.createElement('canvas')\n drawToCanvas(canvas, videoRef.current)\n return new Promise((resolve) => canvas.toBlob(resolve))\n },\n [],\n )\n\n return useMemo<CaptureDevice>(\n () => ({\n videoRef,\n videoDevice,\n videoLoaded,\n setVideoLoaded,\n onVideoUnmounted,\n cameraRef,\n cameraReady,\n cameraAccessDenied,\n requestCameraAccess,\n releaseCameraAccess,\n iphoneContinuityCameraAvailable,\n iphoneContinuityCameraAllowed,\n setIphoneContinuityCameraAllowed,\n takePhoto,\n audioStream,\n microphoneReady,\n microphoneAccessDenied,\n requestMicrophoneAccess,\n }),\n [\n audioStream,\n cameraAccessDenied,\n cameraReady,\n iphoneContinuityCameraAllowed,\n iphoneContinuityCameraAvailable,\n microphoneAccessDenied,\n microphoneReady,\n onVideoUnmounted,\n requestCameraAccess,\n requestMicrophoneAccess,\n takePhoto,\n videoDevice,\n videoLoaded,\n ],\n )\n}\n\nexport const useDualResCaptureDevice = () => {\n const {\n videoRef: maxVideoRef,\n videoDevice,\n videoLoaded: maxVideoLoaded,\n setVideoLoaded: setMaxVideoLoaded,\n cameraRef: maxCameraRef,\n cameraReady: maxCameraReady,\n takePhoto: takeFullResPhoto,\n } = usePreferredCaptureDevice()\n\n const minVideoRef = useRef<HTMLVideoElement | null>(null)\n const [minCamera, setMinCamera] = useState<Camera | null>(null)\n const [minVideoLoaded, setMinVideoLoaded] = useState(false)\n\n useEffect(() => {\n if (!videoDevice || !maxCameraRef.current) return\n\n let cam: Camera\n const cleanup = () => {\n cam?.release()\n setMinCamera(null)\n setMinVideoLoaded(false)\n }\n\n if (!minVideoRef.current) return cleanup\n if (!navigator.mediaDevices?.getUserMedia) return cleanup\n ;(async () => {\n if (!maxCameraRef.current) return\n\n let idealWidth = 448\n let idealHeight = 448\n\n if (maxCameraRef.current.width < maxCameraRef.current.height) {\n idealHeight =\n 448 * (maxCameraRef.current.height / maxCameraRef.current.width)\n } else {\n idealWidth =\n 448 * (maxCameraRef.current.width / maxCameraRef.current.height)\n }\n\n log('min dimensions', idealWidth, idealHeight)\n\n const constraints = {\n audio: false,\n video: {\n deviceId: { exact: videoDevice.deviceId },\n width: { ideal: idealWidth },\n height: { ideal: idealHeight },\n },\n }\n\n const stream = await navigator.mediaDevices.getUserMedia(constraints)\n cam = obtainCameraAccess(stream, videoDevice.label, minVideoRef.current)\n setMinCamera(cam)\n })()\n\n return cleanup\n }, [maxCameraRef, videoDevice])\n\n return {\n minVideoRef,\n maxVideoRef,\n minCamera,\n maxCamera: maxCameraRef.current,\n maxCameraReady,\n minVideoLoaded,\n maxVideoLoaded,\n setMinVideoLoaded,\n setMaxVideoLoaded,\n takeFullResPhoto,\n }\n}\n","import React, { createContext, ReactElement, useEffect } from 'react'\nimport {\n CaptureDevice,\n usePreferredCaptureDevice,\n} from '../../lib/camera/Camera'\n\nexport const CameraStateContext = createContext<CaptureDevice>({\n videoRef: { current: null },\n videoDevice: null,\n videoLoaded: false,\n cameraRef: { current: null },\n cameraReady: false,\n cameraAccessDenied: false,\n requestCameraAccess: () => null,\n releaseCameraAccess: () => null,\n iphoneContinuityCameraAvailable: false,\n iphoneContinuityCameraAllowed: true,\n setIphoneContinuityCameraAllowed: () => null,\n takePhoto: () => Promise.resolve(null),\n setVideoLoaded: () => null,\n onVideoUnmounted: () => null,\n audioStream: null,\n microphoneReady: false,\n microphoneAccessDenied: false,\n requestMicrophoneAccess: () => null,\n})\n\nexport type CameraProviderProps = {\n children: ReactElement\n requestAccessAutomatically?: boolean\n preferFrontFacingCamera?: boolean\n preferContinuityCamera?: boolean\n requireMicrophoneAccess?: boolean\n maxVideoWidth?: number\n maxFps?: number\n onCameraAccessDenied?: () => void\n onMicrophoneAccessDenied?: () => void\n debugMode?: boolean\n}\n\nexport const CameraProvider = ({\n children,\n requestAccessAutomatically = true,\n preferFrontFacingCamera = false,\n preferContinuityCamera = true,\n requireMicrophoneAccess = false,\n maxVideoWidth = 1920,\n maxFps,\n onCameraAccessDenied,\n onMicrophoneAccessDenied,\n debugMode = false,\n}: CameraProviderProps): ReactElement => {\n const captureDevice = usePreferredCaptureDevice({\n requestAccessAutomatically,\n preferFrontFacingCamera,\n preferContinuityCamera,\n requireMicrophoneAccess,\n maxVideoWidth,\n maxFps,\n debugMode,\n })\n\n useEffect(() => {\n if (captureDevice.cameraAccessDenied) onCameraAccessDenied?.()\n }, [captureDevice.cameraAccessDenied, onCameraAccessDenied])\n\n useEffect(() => {\n if (captureDevice.microphoneAccessDenied) onMicrophoneAccessDenied?.()\n }, [captureDevice.microphoneAccessDenied, onMicrophoneAccessDenied])\n\n const releaseCameraAccess = captureDevice.releaseCameraAccess\n\n useEffect(() => {\n return () => {\n releaseCameraAccess()\n }\n }, [releaseCameraAccess])\n\n return (\n <CameraStateContext.Provider value={captureDevice}>\n {children}\n </CameraStateContext.Provider>\n )\n}\n","import {\n preloadDependency,\n progressByUseCase,\n sumUpProgressForDependencies,\n} from './preloadModels'\n\nexport const visionTasksBasePath = `https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.7/wasm`\n\nlet visionRuntimePreloading = false\n\nexport async function preloadVisionRuntime(): Promise<void> {\n if (visionRuntimePreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!visionRuntimePreloading) resolve()\n }, 100)\n })\n\n visionRuntimePreloading = true\n\n const url = `${visionTasksBasePath}/vision_wasm_internal.wasm`\n\n function handleDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (detail.url !== url) return\n progressByUseCase.visionRuntime = sumUpProgressForDependencies([url])\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.visionRuntime', {\n detail: progressByUseCase.visionRuntime,\n }),\n )\n }\n\n document.addEventListener('idmission.preloadProgress', handleDownloadProgress)\n\n try {\n await preloadDependency(url)\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleDownloadProgress,\n )\n visionRuntimePreloading = false\n }\n}\n","function _isNavigatorDefined() {\n return typeof navigator !== 'undefined' && navigator != null\n}\n\nexport function isMobile(nav?: Navigator) {\n if (nav || _isNavigatorDefined()) {\n if (!nav) {\n nav = navigator\n }\n if (nav.product === 'ReactNative') {\n return true\n }\n const a =\n nav.userAgent ||\n nav.vendor ||\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (typeof window !== 'undefined' ? window.opera : '')\n if (!a) {\n const navAny = nav\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return navAny.userAgentData && navAny.userAgentData.mobile\n }\n return (\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n a,\n ) ||\n // tslint:disable-next-line:max-line-length\n /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(\n a.substr(0, 4),\n )\n )\n }\n return false\n}\n","import { Frame } from './getFrameDimensions'\nimport { clearCanvas } from '../../components/common/InvisibleCanvas'\nimport { isMobile } from './isMobile'\nimport { DetectedObjectBox } from '../models/DocumentDetection'\nimport { Face } from '../models/FaceDetection'\n\nexport function cropToShoulders(\n rawCanvas: HTMLCanvasElement | null,\n cropCanvas: HTMLCanvasElement | null,\n frame: ImageData,\n face: Face,\n): string {\n if (!rawCanvas || !cropCanvas) return ''\n\n const rawCtx = rawCanvas.getContext('2d')\n const cropCtx = cropCanvas.getContext('2d')\n if (!rawCtx || !cropCtx) throw new Error('could not get 2d context')\n\n rawCanvas.width = frame.width\n rawCanvas.height = frame.height\n rawCtx.putImageData(frame, 0, 0)\n\n const { xMin, width } = face.box\n const frameHeight = frame.height\n const xPadding = frameHeight * 0.6 - width\n const xPos = Math.max(0, xMin - xPadding / 2)\n if (isMobile()) {\n cropCanvas.width = frame.width\n cropCanvas.height = frame.height\n cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height)\n } else {\n cropCanvas.width = width + xPadding\n cropCanvas.height = frame.height\n cropCtx.drawImage(\n rawCanvas,\n xPos,\n 0,\n cropCanvas.width,\n cropCanvas.height,\n 0,\n 0,\n cropCanvas.width,\n cropCanvas.height,\n )\n }\n\n const dataURL = cropCanvas.toDataURL('image/jpeg', 0.92)\n\n clearCanvas(rawCanvas)\n clearCanvas(cropCanvas)\n\n return dataURL\n}\n\nexport function cropToDetectedObjectBox(\n frame: Frame,\n box: DetectedObjectBox,\n canvas?: HTMLCanvasElement,\n): HTMLCanvasElement {\n canvas ||= document.createElement('canvas')\n const ctx = canvas.getContext('2d')\n if (!ctx) throw new Error('could not get 2d context')\n\n const { xMin, yMin, width, height } = box\n canvas.width = width\n canvas.height = height\n ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height)\n return canvas\n}\n","import { FilesetResolver, ImageSegmenter } from '@mediapipe/tasks-vision'\nimport { error, log, warn } from '../utils/logger'\nimport { preloadVisionRuntime, visionTasksBasePath } from './VisionRuntime'\nimport { preloadDependency } from './preloadModels'\n\ntype ProbeState = 'notProbed' | 'probing' | 'probed'\n\nexport type NetworkTier = 'untested' | 'unusable' | 'slow' | 'medium' | 'fast'\n\ntype ModelCapabilities = {\n probeState: ProbeState\n delegate: 'GPU' | 'CPU' | 'NONE' // if we haven't probed capabilities, optimistically try GPU.\n networkTier: NetworkTier\n networkSpeed: number // represented in bytes per second, but flawed due to small sample size.\n networkTestTime: number // represented in seconds.\n}\n\nexport const defaultImageSegmenterModelPath =\n 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite'\nconst imageSegmenterModelSizeInBytes = 256440.32\n\n// The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test\n// isn't fooled by cache times, but subsequent downloads of the vision runtime still do load from the cache.\nlet tinyModelCacheKey = new Date().getTime()\n\nconst initialModelCapabilities = {\n probeState: 'notProbed',\n delegate: 'GPU',\n networkTier: 'untested',\n networkSpeed: 0,\n networkTestTime: 0,\n} satisfies ModelCapabilities\n\nexport let modelCapabilities: ModelCapabilities = {\n ...initialModelCapabilities,\n}\n\nexport async function probeModelCapabilities(): Promise<void> {\n if (modelCapabilities.probeState === 'probed') return\n if (modelCapabilities.probeState === 'probing')\n return new Promise((resolve) => {\n setInterval(() => {\n if (modelCapabilities.probeState === 'probed') resolve()\n }, 100)\n })\n\n modelCapabilities.probeState = 'probing'\n await preloadVisionRuntime()\n try {\n log('Model Probing: testing GPU capabilities...')\n await loadTinyModel('GPU')\n log('Model Probing: GPU is capable.')\n } catch (error) {\n warn('Model Probing: GPU delegate could not be loaded', error)\n modelCapabilities.delegate = 'CPU'\n try {\n log('Model Probing: testing CPU capabilities...')\n await loadTinyModel('CPU')\n log('Model Probing: CPU is capable.')\n } catch (error) {\n warn('Model Probing: CPU delegate could not be loaded', error)\n modelCapabilities.delegate = 'NONE'\n }\n } finally {\n modelCapabilities.probeState = 'probed'\n }\n}\n\nasync function loadTinyModel(delegate: 'GPU' | 'CPU' = 'GPU', maxTime = 10000) {\n const modelAssetPath = `${defaultImageSegmenterModelPath}?_=${tinyModelCacheKey}`\n\n const startedAt = new Date()\n try {\n await Promise.race([\n preloadDependency(modelAssetPath),\n giveUpAfter(maxTime),\n ])\n } catch (e) {\n error('speed test failed', e)\n modelCapabilities.networkTier = 'unusable'\n return\n }\n\n const time = (new Date().getTime() - startedAt.getTime()) / 1000.0\n\n modelCapabilities.networkTestTime ||= time\n modelCapabilities.networkSpeed ||= imageSegmenterModelSizeInBytes / time\n modelCapabilities.networkTier =\n time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow'\n\n const speedMbps = modelCapabilities.networkSpeed / 1024 / 1024\n log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps')\n log('Model Probing: network test took', time)\n log('Model Probing: network tier', modelCapabilities.networkTier)\n\n const model = await ImageSegmenter.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n { baseOptions: { modelAssetPath, delegate } },\n )\n\n const emptyFrame = document.createElement('canvas')\n model.segment(emptyFrame)\n emptyFrame.remove()\n}\n\nfunction giveUpAfter(maxTime: number) {\n return new Promise((_resolve, reject) => {\n setTimeout(() => {\n reject(new Error('gave up after reaching maximum time allowed'))\n }, maxTime)\n })\n}\n\nexport function resetModelCapabilityProbe() {\n tinyModelCacheKey = new Date().getTime()\n modelCapabilities = { ...initialModelCapabilities }\n}\n","import { BoundingBox } from '@mediapipe/tasks-vision'\nimport { MutableRefObject } from 'react'\n\nexport function convertBoundingBox(box?: BoundingBox) {\n return {\n xMin: box?.originX ?? 0,\n xMax: (box?.originX ?? 0) + (box?.width ?? 0),\n yMin: box?.originY ?? 0,\n yMax: (box?.originY ?? 0) + (box?.height ?? 0),\n width: box?.width ?? 0,\n height: box?.height ?? 0,\n }\n}\n\nexport function waitForVideoReady(\n videoRef: MutableRefObject<HTMLVideoElement | null>,\n checkEveryMs = 100,\n) {\n return new Promise<void>((resolve) => {\n if (videoRef.current?.readyState === 4) return resolve()\n\n const interval = setInterval(() => {\n if (videoRef.current?.readyState === 4) {\n clearInterval(interval)\n resolve()\n }\n }, checkEveryMs)\n })\n}\n","import { FilesetResolver, ImageClassifier } from '@mediapipe/tasks-vision'\nimport {\n preloadFocusModelDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { Frame } from '../utils/getFrameDimensions'\nimport { DetectedObjectBox } from './DocumentDetection'\nimport { cropToDetectedObjectBox } from '../utils/cropping'\nimport { useContext, useEffect, useRef, useState } from 'react'\nimport { modelCapabilities } from './CapabilityProbing'\nimport { CameraStateContext } from '../../components/camera/CameraProvider'\nimport { waitForVideoReady } from './helpers'\n\nexport const defaultFocusModelPath = `https://websdk-cdn-dev.idmission.com/assets/models/focusmp20240523/model_float16.tflite`\nexport const defaultFocusModelLoadTimeoutMs = 45000\n\nexport type FocusPrediction = {\n score: number\n predictionTime: number\n}\n\nexport type FocusThresholds = {\n idCard?: {\n desktop?: number\n mobile?: number\n }\n passport?: {\n desktop?: number\n mobile?: number\n }\n}\n\nexport const defaultFocusThresholds: FocusThresholds = {\n idCard: {\n desktop: 0,\n mobile: 0.3,\n },\n passport: {\n desktop: 0,\n mobile: 0.3,\n },\n}\n\nconst models: { [id: string]: ImageClassifier } = {}\n\nexport async function loadFocusModel(\n modelAssetPath: string,\n): Promise<ImageClassifier> {\n const id = `${modelAssetPath}`\n if (models[id]) return models[id]\n\n await preloadFocusModelDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for focus detector.')\n }\n\n models[id] = await ImageClassifier.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: { modelAssetPath, delegate: modelCapabilities.delegate },\n runningMode: 'VIDEO',\n },\n )\n\n return models[id]\n}\n\nexport function useLoadFocusModel({\n modelPath = defaultFocusModelPath,\n modelLoadTimeoutMs = defaultFocusModelLoadTimeoutMs,\n onModelError,\n}: {\n modelPath?: string\n modelLoadTimeoutMs?: number\n onModelError?: (error: Error) => void\n}) {\n const model = useRef<ImageClassifier | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n const { videoRef } = useContext(CameraStateContext)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.focus',\n handleDownloadProgress,\n )\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n loadFocusModel(modelPath)\n .then(async (loadedModel) => {\n model.current = loadedModel\n setModelDownloadProgress(100)\n clearTimeout(modelLoadTimeout)\n await waitForVideoReady(videoRef)\n loadedModel.classifyForVideo(videoRef.current!, performance.now())\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.focus',\n handleDownloadProgress,\n )\n }\n },\n [modelPath, modelLoadTimeoutMs, videoRef],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { model, ready, modelDownloadProgress, modelError }\n}\n\nexport function makeFocusModelPrediction(\n model: ImageClassifier,\n imageData: Frame,\n cropCanvas: HTMLCanvasElement,\n rotateCanvas: HTMLCanvasElement,\n box?: DetectedObjectBox,\n): FocusPrediction {\n const startedAt = new Date()\n const image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box)\n const result = model.classifyForVideo(image, performance.now())\n const score =\n result?.classifications?.[0]?.categories?.find(\n (c) => c.categoryName === 'focused',\n )?.score ?? 0\n const predictionTime = new Date().getTime() - startedAt.getTime()\n return { score, predictionTime }\n}\n\nfunction cropIfNecessary(\n imageData: Frame,\n cropCanvas: HTMLCanvasElement,\n rotateCanvas: HTMLCanvasElement,\n box?: DetectedObjectBox,\n): Frame {\n if (!box) return imageData\n\n const cropped = cropToDetectedObjectBox(imageData, box, cropCanvas)\n const [bw, bh] = [box.width, box.height]\n if (bh <= bw) return cropped\n\n const ctx = rotateCanvas.getContext('2d')\n if (!ctx) return cropped\n\n rotateCanvas.width = bh\n rotateCanvas.height = bw\n ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height)\n ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2)\n ctx.rotate(1.5708) // 90 deg in radians\n ctx.drawImage(cropped, -bw / 2, -bh / 2)\n return rotateCanvas\n}\n","(function(){/*\n\n Copyright The Closure Library Authors.\n SPDX-License-Identifier: Apache-2.0\n*/\n'use strict';var x;function aa(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}var ba=\"function\"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(a==Array.prototype||a==Object.prototype)return a;a[b]=c.value;return a};\nfunction ca(a){a=[\"object\"==typeof globalThis&&globalThis,a,\"object\"==typeof window&&window,\"object\"==typeof self&&self,\"object\"==typeof global&&global];for(var b=0;b<a.length;++b){var c=a[b];if(c&&c.Math==Math)return c}throw Error(\"Cannot find global object\");}var y=ca(this);function B(a,b){if(b)a:{var c=y;a=a.split(\".\");for(var d=0;d<a.length-1;d++){var e=a[d];if(!(e in c))break a;c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&ba(c,a,{configurable:!0,writable:!0,value:b})}}\nB(\"Symbol\",function(a){function b(g){if(this instanceof b)throw new TypeError(\"Symbol is not a constructor\");return new c(d+(g||\"\")+\"_\"+e++,g)}function c(g,f){this.g=g;ba(this,\"description\",{configurable:!0,writable:!0,value:f})}if(a)return a;c.prototype.toString=function(){return this.g};var d=\"jscomp_symbol_\"+(1E9*Math.random()>>>0)+\"_\",e=0;return b});\nB(\"Symbol.iterator\",function(a){if(a)return a;a=Symbol(\"Symbol.iterator\");for(var b=\"Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array\".split(\" \"),c=0;c<b.length;c++){var d=y[b[c]];\"function\"===typeof d&&\"function\"!=typeof d.prototype[a]&&ba(d.prototype,a,{configurable:!0,writable:!0,value:function(){return da(aa(this))}})}return a});function da(a){a={next:a};a[Symbol.iterator]=function(){return this};return a}\nfunction C(a){var b=\"undefined\"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:aa(a)}}function D(a){if(!(a instanceof Array)){a=C(a);for(var b,c=[];!(b=a.next()).done;)c.push(b.value);a=c}return a}var ea=\"function\"==typeof Object.create?Object.create:function(a){function b(){}b.prototype=a;return new b},fa;\nif(\"function\"==typeof Object.setPrototypeOf)fa=Object.setPrototypeOf;else{var ha;a:{var ia={a:!0},ja={};try{ja.__proto__=ia;ha=ja.a;break a}catch(a){}ha=!1}fa=ha?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+\" is not extensible\");return a}:null}var ka=fa;\nfunction E(a,b){a.prototype=ea(b.prototype);a.prototype.constructor=a;if(ka)ka(a,b);else for(var c in b)if(\"prototype\"!=c)if(Object.defineProperties){var d=Object.getOwnPropertyDescriptor(b,c);d&&Object.defineProperty(a,c,d)}else a[c]=b[c];a.na=b.prototype}function la(){this.l=!1;this.i=null;this.h=void 0;this.g=1;this.u=this.o=0;this.j=null}function ma(a){if(a.l)throw new TypeError(\"Generator is already running\");a.l=!0}la.prototype.s=function(a){this.h=a};\nfunction na(a,b){a.j={da:b,ea:!0};a.g=a.o||a.u}la.prototype.return=function(a){this.j={return:a};this.g=this.u};function G(a,b,c){a.g=c;return{value:b}}function oa(a){this.g=new la;this.h=a}function pa(a,b){ma(a.g);var c=a.g.i;if(c)return qa(a,\"return\"in c?c[\"return\"]:function(d){return{value:d,done:!0}},b,a.g.return);a.g.return(b);return H(a)}\nfunction qa(a,b,c,d){try{var e=b.call(a.g.i,c);if(!(e instanceof Object))throw new TypeError(\"Iterator result \"+e+\" is not an object\");if(!e.done)return a.g.l=!1,e;var g=e.value}catch(f){return a.g.i=null,na(a.g,f),H(a)}a.g.i=null;d.call(a.g,g);return H(a)}function H(a){for(;a.g.g;)try{var b=a.h(a.g);if(b)return a.g.l=!1,{value:b.value,done:!1}}catch(c){a.g.h=void 0,na(a.g,c)}a.g.l=!1;if(a.g.j){b=a.g.j;a.g.j=null;if(b.ea)throw b.da;return{value:b.return,done:!0}}return{value:void 0,done:!0}}\nfunction ra(a){this.next=function(b){ma(a.g);a.g.i?b=qa(a,a.g.i.next,b,a.g.s):(a.g.s(b),b=H(a));return b};this.throw=function(b){ma(a.g);a.g.i?b=qa(a,a.g.i[\"throw\"],b,a.g.s):(na(a.g,b),b=H(a));return b};this.return=function(b){return pa(a,b)};this[Symbol.iterator]=function(){return this}}function sa(a){function b(d){return a.next(d)}function c(d){return a.throw(d)}return new Promise(function(d,e){function g(f){f.done?d(f.value):Promise.resolve(f.value).then(b,c).then(g,e)}g(a.next())})}\nfunction J(a){return sa(new ra(new oa(a)))}\nB(\"Promise\",function(a){function b(f){this.h=0;this.i=void 0;this.g=[];this.s=!1;var h=this.j();try{f(h.resolve,h.reject)}catch(k){h.reject(k)}}function c(){this.g=null}function d(f){return f instanceof b?f:new b(function(h){h(f)})}if(a)return a;c.prototype.h=function(f){if(null==this.g){this.g=[];var h=this;this.i(function(){h.l()})}this.g.push(f)};var e=y.setTimeout;c.prototype.i=function(f){e(f,0)};c.prototype.l=function(){for(;this.g&&this.g.length;){var f=this.g;this.g=[];for(var h=0;h<f.length;++h){var k=\nf[h];f[h]=null;try{k()}catch(l){this.j(l)}}}this.g=null};c.prototype.j=function(f){this.i(function(){throw f;})};b.prototype.j=function(){function f(l){return function(m){k||(k=!0,l.call(h,m))}}var h=this,k=!1;return{resolve:f(this.D),reject:f(this.l)}};b.prototype.D=function(f){if(f===this)this.l(new TypeError(\"A Promise cannot resolve to itself\"));else if(f instanceof b)this.H(f);else{a:switch(typeof f){case \"object\":var h=null!=f;break a;case \"function\":h=!0;break a;default:h=!1}h?this.A(f):this.o(f)}};\nb.prototype.A=function(f){var h=void 0;try{h=f.then}catch(k){this.l(k);return}\"function\"==typeof h?this.I(h,f):this.o(f)};b.prototype.l=function(f){this.u(2,f)};b.prototype.o=function(f){this.u(1,f)};b.prototype.u=function(f,h){if(0!=this.h)throw Error(\"Cannot settle(\"+f+\", \"+h+\"): Promise already settled in state\"+this.h);this.h=f;this.i=h;2===this.h&&this.G();this.B()};b.prototype.G=function(){var f=this;e(function(){if(f.C()){var h=y.console;\"undefined\"!==typeof h&&h.error(f.i)}},1)};b.prototype.C=\nfunction(){if(this.s)return!1;var f=y.CustomEvent,h=y.Event,k=y.dispatchEvent;if(\"undefined\"===typeof k)return!0;\"function\"===typeof f?f=new f(\"unhandledrejection\",{cancelable:!0}):\"function\"===typeof h?f=new h(\"unhandledrejection\",{cancelable:!0}):(f=y.document.createEvent(\"CustomEvent\"),f.initCustomEvent(\"unhandledrejection\",!1,!0,f));f.promise=this;f.reason=this.i;return k(f)};b.prototype.B=function(){if(null!=this.g){for(var f=0;f<this.g.length;++f)g.h(this.g[f]);this.g=null}};var g=new c;b.prototype.H=\nfunction(f){var h=this.j();f.M(h.resolve,h.reject)};b.prototype.I=function(f,h){var k=this.j();try{f.call(h,k.resolve,k.reject)}catch(l){k.reject(l)}};b.prototype.then=function(f,h){function k(p,n){return\"function\"==typeof p?function(r){try{l(p(r))}catch(t){m(t)}}:n}var l,m,q=new b(function(p,n){l=p;m=n});this.M(k(f,l),k(h,m));return q};b.prototype.catch=function(f){return this.then(void 0,f)};b.prototype.M=function(f,h){function k(){switch(l.h){case 1:f(l.i);break;case 2:h(l.i);break;default:throw Error(\"Unexpected state: \"+\nl.h);}}var l=this;null==this.g?g.h(k):this.g.push(k);this.s=!0};b.resolve=d;b.reject=function(f){return new b(function(h,k){k(f)})};b.race=function(f){return new b(function(h,k){for(var l=C(f),m=l.next();!m.done;m=l.next())d(m.value).M(h,k)})};b.all=function(f){var h=C(f),k=h.next();return k.done?d([]):new b(function(l,m){function q(r){return function(t){p[r]=t;n--;0==n&&l(p)}}var p=[],n=0;do p.push(void 0),n++,d(k.value).M(q(p.length-1),m),k=h.next();while(!k.done)})};return b});\nfunction ta(a,b){a instanceof String&&(a+=\"\");var c=0,d=!1,e={next:function(){if(!d&&c<a.length){var g=c++;return{value:b(g,a[g]),done:!1}}d=!0;return{done:!0,value:void 0}}};e[Symbol.iterator]=function(){return e};return e}var ua=\"function\"==typeof Object.assign?Object.assign:function(a,b){for(var c=1;c<arguments.length;c++){var d=arguments[c];if(d)for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(a[e]=d[e])}return a};B(\"Object.assign\",function(a){return a||ua});\nB(\"Object.is\",function(a){return a?a:function(b,c){return b===c?0!==b||1/b===1/c:b!==b&&c!==c}});B(\"Array.prototype.includes\",function(a){return a?a:function(b,c){var d=this;d instanceof String&&(d=String(d));var e=d.length;c=c||0;for(0>c&&(c=Math.max(c+e,0));c<e;c++){var g=d[c];if(g===b||Object.is(g,b))return!0}return!1}});\nB(\"String.prototype.includes\",function(a){return a?a:function(b,c){if(null==this)throw new TypeError(\"The 'this' value for String.prototype.includes must not be null or undefined\");if(b instanceof RegExp)throw new TypeError(\"First argument to String.prototype.includes must not be a regular expression\");return-1!==this.indexOf(b,c||0)}});B(\"Array.prototype.keys\",function(a){return a?a:function(){return ta(this,function(b){return b})}});var va=this||self;\nfunction K(a,b){a=a.split(\".\");var c=va;a[0]in c||\"undefined\"==typeof c.execScript||c.execScript(\"var \"+a[0]);for(var d;a.length&&(d=a.shift());)a.length||void 0===b?c[d]&&c[d]!==Object.prototype[d]?c=c[d]:c=c[d]={}:c[d]=b};function L(){throw Error(\"Invalid UTF8\");}function wa(a,b){b=String.fromCharCode.apply(null,b);return null==a?b:a+b}var xa,ya=\"undefined\"!==typeof TextDecoder,za,Aa=\"undefined\"!==typeof TextEncoder;var Ba={},M=null;function Ca(a){var b;void 0===b&&(b=0);Da();b=Ba[b];for(var c=Array(Math.floor(a.length/3)),d=b[64]||\"\",e=0,g=0;e<a.length-2;e+=3){var f=a[e],h=a[e+1],k=a[e+2],l=b[f>>2];f=b[(f&3)<<4|h>>4];h=b[(h&15)<<2|k>>6];k=b[k&63];c[g++]=l+f+h+k}l=0;k=d;switch(a.length-e){case 2:l=a[e+1],k=b[(l&15)<<2]||d;case 1:a=a[e],c[g]=b[a>>2]+b[(a&3)<<4|l>>4]+k+d}return c.join(\"\")}\nfunction Ea(a){var b=a.length,c=3*b/4;c%3?c=Math.floor(c):-1!=\"=.\".indexOf(a[b-1])&&(c=-1!=\"=.\".indexOf(a[b-2])?c-2:c-1);var d=new Uint8Array(c),e=0;Fa(a,function(g){d[e++]=g});return e!==c?d.subarray(0,e):d}\nfunction Fa(a,b){function c(k){for(;d<a.length;){var l=a.charAt(d++),m=M[l];if(null!=m)return m;if(!/^[\\s\\xa0]*$/.test(l))throw Error(\"Unknown base64 encoding at char: \"+l);}return k}Da();for(var d=0;;){var e=c(-1),g=c(0),f=c(64),h=c(64);if(64===h&&-1===e)break;b(e<<2|g>>4);64!=f&&(b(g<<4&240|f>>2),64!=h&&b(f<<6&192|h))}}\nfunction Da(){if(!M){M={};for(var a=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\".split(\"\"),b=[\"+/=\",\"+/\",\"-_=\",\"-_.\",\"-_\"],c=0;5>c;c++){var d=a.concat(b[c].split(\"\"));Ba[c]=d;for(var e=0;e<d.length;e++){var g=d[e];void 0===M[g]&&(M[g]=e)}}}};var Ga=\"function\"===typeof Uint8Array;function Ha(a){return Ga&&null!=a&&a instanceof Uint8Array}var Ia;function Ja(a){this.L=a;if(null!==a&&0===a.length)throw Error(\"ByteString should be constructed with non-empty values\");};var Ka=\"function\"===typeof Uint8Array.prototype.slice,N=0,O=0;\nfunction La(a,b){if(a.constructor===Uint8Array)return a;if(a.constructor===ArrayBuffer)return new Uint8Array(a);if(a.constructor===Array)return new Uint8Array(a);if(a.constructor===String)return Ea(a);if(a.constructor===Ja){if(!b&&(b=a.L)&&b.constructor===Uint8Array)return b;b=a.L;b=null==b||Ha(b)?b:\"string\"===typeof b?Ea(b):null;return(a=a.L=b)?new Uint8Array(a):Ia||(Ia=new Uint8Array(0))}if(a instanceof Uint8Array)return new Uint8Array(a.buffer,a.byteOffset,a.byteLength);throw Error(\"Type not convertible to a Uint8Array, expected a Uint8Array, an ArrayBuffer, a base64 encoded string, or Array of numbers\");\n};function Ma(a,b){return Error(\"Invalid wire type: \"+a+\" (at position \"+b+\")\")}function Na(){return Error(\"Failed to read varint, encoding is invalid.\")};function Oa(a,b){b=void 0===b?{}:b;b=void 0===b.v?!1:b.v;this.h=null;this.g=this.i=this.j=0;this.v=b;a&&Pa(this,a)}function Pa(a,b){a.h=La(b,a.v);a.j=0;a.i=a.h.length;a.g=a.j}Oa.prototype.reset=function(){this.g=this.j};function P(a){if(a.g>a.i)throw Error(\"Tried to read past the end of the data \"+a.g+\" > \"+a.i);}\nfunction Q(a){var b=a.h,c=b[a.g],d=c&127;if(128>c)return a.g+=1,P(a),d;c=b[a.g+1];d|=(c&127)<<7;if(128>c)return a.g+=2,P(a),d;c=b[a.g+2];d|=(c&127)<<14;if(128>c)return a.g+=3,P(a),d;c=b[a.g+3];d|=(c&127)<<21;if(128>c)return a.g+=4,P(a),d;c=b[a.g+4];a.g+=5;d|=(c&15)<<28;if(128>c)return P(a),d;if(128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++]&&128<=b[a.g++])throw Na();P(a);return d}var Qa=[];function Ra(){this.g=[]}Ra.prototype.length=function(){return this.g.length};Ra.prototype.end=function(){var a=this.g;this.g=[];return a};function S(a,b){for(;127<b;)a.g.push(b&127|128),b>>>=7;a.g.push(b)};function Sa(a){var b={},c=void 0===b.W?!1:b.W;this.l={v:void 0===b.v?!1:b.v};this.W=c;b=this.l;Qa.length?(c=Qa.pop(),b&&(c.v=b.v),a&&Pa(c,a),a=c):a=new Oa(a,b);this.g=a;this.j=this.g.g;this.h=this.i=-1}Sa.prototype.reset=function(){this.g.reset();this.j=this.g.g;this.h=this.i=-1};function Ta(a){var b=a.g;if(b.g==b.i)return!1;a.j=a.g.g;var c=Q(a.g)>>>0;b=c>>>3;c&=7;if(!(0<=c&&5>=c))throw Ma(c,a.j);if(1>b)throw Error(\"Invalid field number: \"+b+\" (at position \"+a.j+\")\");a.i=b;a.h=c;return!0}\nfunction Ua(a){switch(a.h){case 0:if(0!=a.h)Ua(a);else a:{a=a.g;for(var b=a.g,c=b+10;b<c;)if(0===(a.h[b++]&128)){a.g=b;P(a);break a}throw Na();}break;case 1:a=a.g;a.g+=8;P(a);break;case 2:2!=a.h?Ua(a):(b=Q(a.g)>>>0,a=a.g,a.g+=b,P(a));break;case 5:a=a.g;a.g+=4;P(a);break;case 3:b=a.i;do{if(!Ta(a))throw Error(\"Unmatched start-group tag: stream EOF\");if(4==a.h){if(a.i!=b)throw Error(\"Unmatched end-group tag\");break}Ua(a)}while(1);break;default:throw Ma(a.h,a.j);}}var Va=[];function Wa(){this.i=[];this.h=0;this.g=new Ra}function T(a,b){0!==b.length&&(a.i.push(b),a.h+=b.length)}function Xa(a,b){if(b=b.ba){T(a,a.g.end());for(var c=0;c<b.length;c++)T(a,b[c])}};var U=\"function\"===typeof Symbol&&\"symbol\"===typeof Symbol()?Symbol(void 0):void 0;function Ya(a,b){Object.isFrozen(a)||(U?a[U]|=b:void 0!==a.N?a.N|=b:Object.defineProperties(a,{N:{value:b,configurable:!0,writable:!0,enumerable:!1}}))}function Za(a){var b;U?b=a[U]:b=a.N;return null==b?0:b}function $a(a){Ya(a,1);return a}function ab(a){return Array.isArray(a)?!!(Za(a)&2):!1}function bb(a){if(!Array.isArray(a))throw Error(\"cannot mark non-array as immutable\");Ya(a,2)};function cb(a){return null!==a&&\"object\"===typeof a&&!Array.isArray(a)&&a.constructor===Object}var db=Object.freeze($a([]));function eb(a){if(ab(a.m))throw Error(\"Cannot mutate an immutable Message\");}var fb=\"undefined\"!=typeof Symbol&&\"undefined\"!=typeof Symbol.hasInstance;function gb(a){return{value:a,configurable:!1,writable:!1,enumerable:!1}};function V(a,b,c){return-1===b?null:b>=a.i?a.g?a.g[b]:void 0:(void 0===c?0:c)&&a.g&&(c=a.g[b],null!=c)?c:a.m[b+a.h]}function W(a,b,c,d){d=void 0===d?!1:d;eb(a);b<a.i&&!d?a.m[b+a.h]=c:(a.g||(a.g=a.m[a.i+a.h]={}))[b]=c}function hb(a,b,c,d){c=void 0===c?!0:c;d=void 0===d?!1:d;var e=V(a,b,d);null==e&&(e=db);if(ab(a.m))c&&(bb(e),Object.freeze(e));else if(e===db||ab(e))e=$a(e.slice()),W(a,b,e,d);return e}function X(a,b,c){a=V(a,b);a=null==a?a:+a;return null==a?void 0===c?0:c:a}\nfunction ib(a,b,c,d){a.j||(a.j={});var e=ab(a.m),g=a.j[c];if(!g){d=hb(a,c,!0,void 0===d?!1:d);g=[];e=e||ab(d);for(var f=0;f<d.length;f++)g[f]=new b(d[f]),e&&bb(g[f].m);e&&(bb(g),Object.freeze(g));a.j[c]=g}return g}function jb(a,b,c,d,e){var g=void 0===g?!1:g;eb(a);g=ib(a,c,b,g);c=d?d:new c;a=hb(a,b);void 0!=e?(g.splice(e,0,c),a.splice(e,0,c.m)):(g.push(c),a.push(c.m));return c}function kb(a,b){a=V(a,b);return null==a?0:a}function lb(a,b){a=V(a,b);return null==a?\"\":a};function mb(a){switch(typeof a){case \"number\":return isFinite(a)?a:String(a);case \"object\":if(a&&!Array.isArray(a)){if(Ha(a))return Ca(a);if(a instanceof Ja){var b=a.L;b=null==b||\"string\"===typeof b?b:Ga&&b instanceof Uint8Array?Ca(b):null;return(a.L=b)||\"\"}}}return a};function nb(a){var b=ob;b=void 0===b?pb:b;return qb(a,b)}function rb(a,b){if(null!=a){if(Array.isArray(a))a=qb(a,b);else if(cb(a)){var c={},d;for(d in a)c[d]=rb(a[d],b);a=c}else a=b(a);return a}}function qb(a,b){for(var c=a.slice(),d=0;d<c.length;d++)c[d]=rb(c[d],b);Array.isArray(a)&&Za(a)&1&&$a(c);return c}function ob(a){if(a&&\"object\"==typeof a&&a.toJSON)return a.toJSON();a=mb(a);return Array.isArray(a)?nb(a):a}function pb(a){return Ha(a)?new Uint8Array(a):a};function sb(a,b,c){a||(a=tb);tb=null;var d=this.constructor.h;a||(a=d?[d]:[]);this.h=(d?0:-1)-(this.constructor.g||0);this.j=void 0;this.m=a;a:{d=this.m.length;a=d-1;if(d&&(d=this.m[a],cb(d))){this.i=a-this.h;this.g=d;break a}void 0!==b&&-1<b?(this.i=Math.max(b,a+1-this.h),this.g=void 0):this.i=Number.MAX_VALUE}if(c)for(b=0;b<c.length;b++)if(a=c[b],a<this.i)a+=this.h,(d=this.m[a])?Array.isArray(d)&&$a(d):this.m[a]=db;else{d=this.g||(this.g=this.m[this.i+this.h]={});var e=d[a];e?Array.isArray(e)&&\n$a(e):d[a]=db}}sb.prototype.toJSON=function(){return nb(this.m)};sb.prototype.toString=function(){return this.m.toString()};var tb;function ub(){sb.apply(this,arguments)}E(ub,sb);if(fb){var vb={};Object.defineProperties(ub,(vb[Symbol.hasInstance]=gb(function(){throw Error(\"Cannot perform instanceof checks for MutableMessage\");}),vb))};function wb(a,b,c){if(c){var d={},e;for(e in c){var g=c[e],f=g.ha;f||(d.F=g.la||g.fa.P,g.aa?(d.U=xb(g.aa),f=function(h){return function(k,l,m){return h.F(k,l,m,h.U)}}(d)):g.ca?(d.T=yb(g.X.g,g.ca),f=function(h){return function(k,l,m){return h.F(k,l,m,h.T)}}(d)):f=d.F,g.ha=f);f(b,a,g.X);d={F:d.F,U:d.U,T:d.T}}}Xa(b,a)}var zb=Symbol();function Ab(a,b,c){return a[zb]||(a[zb]=function(d,e){return b(d,e,c)})}\nfunction Bb(a){var b=a[zb];if(!b){var c=Cb(a);b=function(d,e){return Db(d,e,c)};a[zb]=b}return b}function Eb(a){var b=a.aa;if(b)return Bb(b);if(b=a.ka)return Ab(a.X.g,b,a.ca)}function Fb(a){var b=Eb(a),c=a.X,d=a.fa.O;return b?function(e,g){return d(e,g,c,b)}:function(e,g){return d(e,g,c)}}\nfunction Gb(a,b,c,d,e,g){a=a();var f=0;a.length&&\"number\"!==typeof a[0]&&(c(b,a[0]),f++);for(;f<a.length;){c=a[f++];for(var h=f+1;h<a.length&&\"number\"!==typeof a[h];)h++;var k=a[f++];h-=f;switch(h){case 0:d(b,c,k);break;case 1:d(b,c,k,a[f++]);break;case 2:e(b,c,k,a[f++],a[f++]);break;case 3:h=a[f++];var l=a[f++],m=a[f++];Array.isArray(m)?e(b,c,k,h,l,m):g(b,c,k,h,l,m);break;case 4:g(b,c,k,a[f++],a[f++],a[f++],a[f++]);break;default:throw Error(\"unexpected number of binary field arguments: \"+h);}}return b}\nvar Hb=Symbol();function xb(a){var b=a[Hb];if(!b){var c=Ib(a);b=function(d,e){return Jb(d,e,c)};a[Hb]=b}return b}function yb(a,b){var c=a[Hb];c||(c=function(d,e){return wb(d,e,b)},a[Hb]=c);return c}var Kb=Symbol();function Lb(a,b){a.push(b)}function Mb(a,b,c){a.push(b,c.P)}function Nb(a,b,c,d,e){var g=xb(e),f=c.P;a.push(b,function(h,k,l){return f(h,k,l,d,g)})}function Ob(a,b,c,d,e,g){var f=yb(d,g),h=c.P;a.push(b,function(k,l,m){return h(k,l,m,d,f)})}\nfunction Ib(a){var b=a[Kb];return b?b:Gb(a,a[Kb]=[],Lb,Mb,Nb,Ob)}var Pb=Symbol();function Qb(a,b){a[0]=b}function Rb(a,b,c,d){var e=c.O;a[b]=d?function(g,f,h){return e(g,f,h,d)}:e}function Sb(a,b,c,d,e,g){var f=c.O,h=Bb(e);a[b]=function(k,l,m){return f(k,l,m,d,h,g)}}function Tb(a,b,c,d,e,g,f){var h=c.O,k=Ab(d,e,g);a[b]=function(l,m,q){return h(l,m,q,d,k,f)}}function Cb(a){var b=a[Pb];return b?b:Gb(a,a[Pb]={},Qb,Rb,Sb,Tb)}\nfunction Db(a,b,c){for(;Ta(b)&&4!=b.h;){var d=b.i,e=c[d];if(!e){var g=c[0];g&&(g=g[d])&&(e=c[d]=Fb(g))}if(!e||!e(b,a,d))if(e=b,d=a,g=e.j,Ua(e),!e.W){var f=e.g.h;e=e.g.g;e=g===e?Ia||(Ia=new Uint8Array(0)):Ka?f.slice(g,e):new Uint8Array(f.subarray(g,e));(g=d.ba)?g.push(e):d.ba=[e]}}return a}\nfunction Ub(a,b,c){if(Va.length){var d=Va.pop();a&&(Pa(d.g,a),d.i=-1,d.h=-1);a=d}else a=new Sa(a);try{return Db(new b,a,Cb(c))}finally{b=a.g,b.h=null,b.j=0,b.i=0,b.g=0,b.v=!1,a.i=-1,a.h=-1,100>Va.length&&Va.push(a)}}function Jb(a,b,c){for(var d=c.length,e=1==d%2,g=e?1:0;g<d;g+=2)(0,c[g+1])(b,a,c[g]);wb(a,b,e?c[0]:void 0)}function Vb(a,b){var c=new Wa;Jb(a,c,Ib(b));T(c,c.g.end());a=new Uint8Array(c.h);b=c.i;for(var d=b.length,e=0,g=0;g<d;g++){var f=b[g];a.set(f,e);e+=f.length}c.i=[a];return a}\nfunction Wb(a,b){return{O:a,P:b}}\nvar Y=Wb(function(a,b,c){if(5!==a.h)return!1;a=a.g;var d=a.h[a.g];var e=a.h[a.g+1];var g=a.h[a.g+2],f=a.h[a.g+3];a.g+=4;P(a);e=(d<<0|e<<8|g<<16|f<<24)>>>0;a=2*(e>>31)+1;d=e>>>23&255;e&=8388607;W(b,c,255==d?e?NaN:Infinity*a:0==d?a*Math.pow(2,-149)*e:a*Math.pow(2,d-150)*(e+Math.pow(2,23)));return!0},function(a,b,c){b=V(b,c);if(null!=b){S(a.g,8*c+5);a=a.g;var d=b;d=(c=0>d?1:0)?-d:d;0===d?0<1/d?N=O=0:(O=0,N=2147483648):isNaN(d)?(O=0,N=2147483647):3.4028234663852886E38<d?(O=0,N=(c<<31|2139095040)>>>0):\n1.1754943508222875E-38>d?(d=Math.round(d/Math.pow(2,-149)),O=0,N=(c<<31|d)>>>0):(b=Math.floor(Math.log(d)/Math.LN2),d*=Math.pow(2,-b),d=Math.round(8388608*d),16777216<=d&&++b,O=0,N=(c<<31|b+127<<23|d&8388607)>>>0);c=N;a.g.push(c>>>0&255);a.g.push(c>>>8&255);a.g.push(c>>>16&255);a.g.push(c>>>24&255)}}),Xb=Wb(function(a,b,c){if(0!==a.h)return!1;for(var d=a.g,e=128,g=0,f=a=0;4>f&&128<=e;f++)e=d.h[d.g++],P(d),g|=(e&127)<<7*f;128<=e&&(e=d.h[d.g++],P(d),g|=(e&127)<<28,a|=(e&127)>>4);if(128<=e)for(f=0;5>\nf&&128<=e;f++)e=d.h[d.g++],P(d),a|=(e&127)<<7*f+3;if(128>e){d=g>>>0;e=a>>>0;if(a=e&2147483648)d=~d+1>>>0,e=~e>>>0,0==d&&(e=e+1>>>0);d=4294967296*e+(d>>>0)}else throw Na();W(b,c,a?-d:d);return!0},function(a,b,c){b=V(b,c);if(null!=b&&null!=b){S(a.g,8*c);a=a.g;var d=b;c=0>d;d=Math.abs(d);b=d>>>0;d=Math.floor((d-b)/4294967296);d>>>=0;c&&(d=~d>>>0,b=(~b>>>0)+1,4294967295<b&&(b=0,d++,4294967295<d&&(d=0)));N=b;O=d;c=N;for(b=O;0<b||127<c;)a.g.push(c&127|128),c=(c>>>7|b<<25)>>>0,b>>>=7;a.g.push(c)}}),Yb=Wb(function(a,\nb,c){if(0!==a.h)return!1;W(b,c,Q(a.g));return!0},function(a,b,c){b=V(b,c);if(null!=b&&null!=b)if(S(a.g,8*c),a=a.g,c=b,0<=c)S(a,c);else{for(b=0;9>b;b++)a.g.push(c&127|128),c>>=7;a.g.push(1)}}),Zb=Wb(function(a,b,c){if(2!==a.h)return!1;var d=Q(a.g)>>>0;a=a.g;var e=a.g;a.g+=d;P(a);a=a.h;var g;if(ya)(g=xa)||(g=xa=new TextDecoder(\"utf-8\",{fatal:!0})),g=g.decode(a.subarray(e,e+d));else{d=e+d;for(var f=[],h=null,k,l,m;e<d;)k=a[e++],128>k?f.push(k):224>k?e>=d?L():(l=a[e++],194>k||128!==(l&192)?(e--,L()):\nf.push((k&31)<<6|l&63)):240>k?e>=d-1?L():(l=a[e++],128!==(l&192)||224===k&&160>l||237===k&&160<=l||128!==((g=a[e++])&192)?(e--,L()):f.push((k&15)<<12|(l&63)<<6|g&63)):244>=k?e>=d-2?L():(l=a[e++],128!==(l&192)||0!==(k<<28)+(l-144)>>30||128!==((g=a[e++])&192)||128!==((m=a[e++])&192)?(e--,L()):(k=(k&7)<<18|(l&63)<<12|(g&63)<<6|m&63,k-=65536,f.push((k>>10&1023)+55296,(k&1023)+56320))):L(),8192<=f.length&&(h=wa(h,f),f.length=0);g=wa(h,f)}W(b,c,g);return!0},function(a,b,c){b=V(b,c);if(null!=b){var d=!1;\nd=void 0===d?!1:d;if(Aa){if(d&&/(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])/.test(b))throw Error(\"Found an unpaired surrogate\");b=(za||(za=new TextEncoder)).encode(b)}else{for(var e=0,g=new Uint8Array(3*b.length),f=0;f<b.length;f++){var h=b.charCodeAt(f);if(128>h)g[e++]=h;else{if(2048>h)g[e++]=h>>6|192;else{if(55296<=h&&57343>=h){if(56319>=h&&f<b.length){var k=b.charCodeAt(++f);if(56320<=k&&57343>=k){h=1024*(h-55296)+k-56320+65536;g[e++]=h>>18|240;g[e++]=h>>12&63|128;\ng[e++]=h>>6&63|128;g[e++]=h&63|128;continue}else f--}if(d)throw Error(\"Found an unpaired surrogate\");h=65533}g[e++]=h>>12|224;g[e++]=h>>6&63|128}g[e++]=h&63|128}}b=g.subarray(0,e)}S(a.g,8*c+2);S(a.g,b.length);T(a,a.g.end());T(a,b)}}),$b=Wb(function(a,b,c,d,e){if(2!==a.h)return!1;b=jb(b,c,d);c=a.g.i;d=Q(a.g)>>>0;var g=a.g.g+d,f=g-c;0>=f&&(a.g.i=g,e(b,a),f=g-a.g.g);if(f)throw Error(\"Message parsing ended unexpectedly. Expected to read \"+(d+\" bytes, instead read \"+(d-f)+\" bytes, either the data ended unexpectedly or the message misreported its own length\"));\na.g.g=g;a.g.i=c;return!0},function(a,b,c,d,e){b=ib(b,d,c);if(null!=b)for(d=0;d<b.length;d++){var g=a;S(g.g,8*c+2);var f=g.g.end();T(g,f);f.push(g.h);g=f;e(b[d],a);f=a;var h=g.pop();for(h=f.h+f.g.length()-h;127<h;)g.push(h&127|128),h>>>=7,f.h++;g.push(h);f.h++}});function Z(){ub.apply(this,arguments)}E(Z,ub);if(fb){var ac={};Object.defineProperties(Z,(ac[Symbol.hasInstance]=gb(Object[Symbol.hasInstance]),ac))};function bc(a){Z.call(this,a)}E(bc,Z);function cc(){return[1,Yb,2,Y,3,Zb,4,Zb]};function dc(a){Z.call(this,a,-1,ec)}E(dc,Z);dc.prototype.addClassification=function(a,b){jb(this,1,bc,a,b);return this};function fc(){return[1,$b,bc,cc]}var ec=[1];function gc(a){Z.call(this,a)}E(gc,Z);function hc(){return[1,Y,2,Y,3,Y,4,Y,5,Y]};function ic(a){Z.call(this,a,-1,jc)}E(ic,Z);function kc(){return[1,$b,gc,hc]}var jc=[1];function lc(a){Z.call(this,a)}E(lc,Z);function mc(){return[1,Y,2,Y,3,Y,4,Y,5,Y,6,Xb]};var nc=[[61,146],[146,91],[91,181],[181,84],[84,17],[17,314],[314,405],[405,321],[321,375],[375,291],[61,185],[185,40],[40,39],[39,37],[37,0],[0,267],[267,269],[269,270],[270,409],[409,291],[78,95],[95,88],[88,178],[178,87],[87,14],[14,317],[317,402],[402,318],[318,324],[324,308],[78,191],[191,80],[80,81],[81,82],[82,13],[13,312],[312,311],[311,310],[310,415],[415,308]],oc=[[263,249],[249,390],[390,373],[373,374],[374,380],[380,381],[381,382],[382,362],[263,466],[466,388],[388,387],[387,386],[386,\n385],[385,384],[384,398],[398,362]],pc=[[276,283],[283,282],[282,295],[295,285],[300,293],[293,334],[334,296],[296,336]],qc=[[33,7],[7,163],[163,144],[144,145],[145,153],[153,154],[154,155],[155,133],[33,246],[246,161],[161,160],[160,159],[159,158],[158,157],[157,173],[173,133]],rc=[[46,53],[53,52],[52,65],[65,55],[70,63],[63,105],[105,66],[66,107]],sc=[[10,338],[338,297],[297,332],[332,284],[284,251],[251,389],[389,356],[356,454],[454,323],[323,361],[361,288],[288,397],[397,365],[365,379],[379,378],\n[378,400],[400,377],[377,152],[152,148],[148,176],[176,149],[149,150],[150,136],[136,172],[172,58],[58,132],[132,93],[93,234],[234,127],[127,162],[162,21],[21,54],[54,103],[103,67],[67,109],[109,10]],tc=[].concat(D(nc),D(oc),D(pc),D(qc),D(rc),D(sc));function uc(a,b,c){c=a.createShader(0===c?a.VERTEX_SHADER:a.FRAGMENT_SHADER);a.shaderSource(c,b);a.compileShader(c);if(!a.getShaderParameter(c,a.COMPILE_STATUS))throw Error(\"Could not compile WebGL shader.\\n\\n\"+a.getShaderInfoLog(c));return c};function vc(a){return ib(a,bc,1).map(function(b){return{index:kb(b,1),ga:X(b,2),label:null!=V(b,3)?lb(b,3):void 0,displayName:null!=V(b,4)?lb(b,4):void 0}})};function wc(a){return{x:X(a,1),y:X(a,2),z:X(a,3),visibility:null!=V(a,4)?X(a,4):void 0}};function xc(a,b){this.h=a;this.g=b;this.l=0}\nfunction yc(a,b,c){zc(a,b);if(\"function\"===typeof a.g.canvas.transferToImageBitmap)return Promise.resolve(a.g.canvas.transferToImageBitmap());if(c)return Promise.resolve(a.g.canvas);if(\"function\"===typeof createImageBitmap)return createImageBitmap(a.g.canvas);void 0===a.i&&(a.i=document.createElement(\"canvas\"));return new Promise(function(d){a.i.height=a.g.canvas.height;a.i.width=a.g.canvas.width;a.i.getContext(\"2d\",{}).drawImage(a.g.canvas,0,0,a.g.canvas.width,a.g.canvas.height);d(a.i)})}\nfunction zc(a,b){var c=a.g;if(void 0===a.o){var d=uc(c,\"\\n attribute vec2 aVertex;\\n attribute vec2 aTex;\\n varying vec2 vTex;\\n void main(void) {\\n gl_Position = vec4(aVertex, 0.0, 1.0);\\n vTex = aTex;\\n }\",0),e=uc(c,\"\\n precision mediump float;\\n varying vec2 vTex;\\n uniform sampler2D sampler0;\\n void main(){\\n gl_FragColor = texture2D(sampler0, vTex);\\n }\",1),g=c.createProgram();c.attachShader(g,d);c.attachShader(g,e);c.linkProgram(g);if(!c.getProgramParameter(g,c.LINK_STATUS))throw Error(\"Could not compile WebGL program.\\n\\n\"+\nc.getProgramInfoLog(g));d=a.o=g;c.useProgram(d);e=c.getUniformLocation(d,\"sampler0\");a.j={K:c.getAttribLocation(d,\"aVertex\"),J:c.getAttribLocation(d,\"aTex\"),ma:e};a.u=c.createBuffer();c.bindBuffer(c.ARRAY_BUFFER,a.u);c.enableVertexAttribArray(a.j.K);c.vertexAttribPointer(a.j.K,2,c.FLOAT,!1,0,0);c.bufferData(c.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),c.STATIC_DRAW);c.bindBuffer(c.ARRAY_BUFFER,null);a.s=c.createBuffer();c.bindBuffer(c.ARRAY_BUFFER,a.s);c.enableVertexAttribArray(a.j.J);c.vertexAttribPointer(a.j.J,\n2,c.FLOAT,!1,0,0);c.bufferData(c.ARRAY_BUFFER,new Float32Array([0,1,0,0,1,0,1,1]),c.STATIC_DRAW);c.bindBuffer(c.ARRAY_BUFFER,null);c.uniform1i(e,0)}d=a.j;c.useProgram(a.o);c.canvas.width=b.width;c.canvas.height=b.height;c.viewport(0,0,b.width,b.height);c.activeTexture(c.TEXTURE0);a.h.bindTexture2d(b.glName);c.enableVertexAttribArray(d.K);c.bindBuffer(c.ARRAY_BUFFER,a.u);c.vertexAttribPointer(d.K,2,c.FLOAT,!1,0,0);c.enableVertexAttribArray(d.J);c.bindBuffer(c.ARRAY_BUFFER,a.s);c.vertexAttribPointer(d.J,\n2,c.FLOAT,!1,0,0);c.bindFramebuffer(c.DRAW_FRAMEBUFFER?c.DRAW_FRAMEBUFFER:c.FRAMEBUFFER,null);c.clearColor(0,0,0,0);c.clear(c.COLOR_BUFFER_BIT);c.colorMask(!0,!0,!0,!0);c.drawArrays(c.TRIANGLE_FAN,0,4);c.disableVertexAttribArray(d.K);c.disableVertexAttribArray(d.J);c.bindBuffer(c.ARRAY_BUFFER,null);a.h.bindTexture2d(0)}function Ac(a){this.g=a};var Bc=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11]);function Cc(a,b){return b+a}function Dc(a,b){window[a]=b}function Ec(a){var b=document.createElement(\"script\");b.setAttribute(\"src\",a);b.setAttribute(\"crossorigin\",\"anonymous\");return new Promise(function(c){b.addEventListener(\"load\",function(){c()},!1);b.addEventListener(\"error\",function(){c()},!1);document.body.appendChild(b)})}\nfunction Fc(){return J(function(a){switch(a.g){case 1:return a.o=2,G(a,WebAssembly.instantiate(Bc),4);case 4:a.g=3;a.o=0;break;case 2:return a.o=0,a.j=null,a.return(!1);case 3:return a.return(!0)}})}\nfunction Gc(a){this.g=a;this.listeners={};this.j={};this.H={};this.o={};this.u={};this.I=this.s=this.Z=!0;this.D=Promise.resolve();this.Y=\"\";this.C={};this.locateFile=a&&a.locateFile||Cc;if(\"object\"===typeof window)var b=window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf(\"/\"))+\"/\";else if(\"undefined\"!==typeof location)b=location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf(\"/\"))+\"/\";else throw Error(\"solutions can only be loaded on a web page or in a web worker\");\nthis.$=b;if(a.options){b=C(Object.keys(a.options));for(var c=b.next();!c.done;c=b.next()){c=c.value;var d=a.options[c].default;void 0!==d&&(this.j[c]=\"function\"===typeof d?d():d)}}}x=Gc.prototype;x.close=function(){this.i&&this.i.delete();return Promise.resolve()};\nfunction Hc(a){var b,c,d,e,g,f,h,k,l,m,q;return J(function(p){switch(p.g){case 1:if(!a.Z)return p.return();b=void 0===a.g.files?[]:\"function\"===typeof a.g.files?a.g.files(a.j):a.g.files;return G(p,Fc(),2);case 2:c=p.h;if(\"object\"===typeof window)return Dc(\"createMediapipeSolutionsWasm\",{locateFile:a.locateFile}),Dc(\"createMediapipeSolutionsPackedAssets\",{locateFile:a.locateFile}),f=b.filter(function(n){return void 0!==n.data}),h=b.filter(function(n){return void 0===n.data}),k=Promise.all(f.map(function(n){var r=\nIc(a,n.url);if(void 0!==n.path){var t=n.path;r=r.then(function(w){a.overrideFile(t,w);return Promise.resolve(w)})}return r})),l=Promise.all(h.map(function(n){return void 0===n.simd||n.simd&&c||!n.simd&&!c?Ec(a.locateFile(n.url,a.$)):Promise.resolve()})).then(function(){var n,r,t;return J(function(w){if(1==w.g)return n=window.createMediapipeSolutionsWasm,r=window.createMediapipeSolutionsPackedAssets,t=a,G(w,n(r),2);t.h=w.h;w.g=0})}),m=function(){return J(function(n){a.g.graph&&a.g.graph.url?n=G(n,\nIc(a,a.g.graph.url),0):(n.g=0,n=void 0);return n})}(),G(p,Promise.all([l,k,m]),7);if(\"function\"!==typeof importScripts)throw Error(\"solutions can only be loaded on a web page or in a web worker\");d=b.filter(function(n){return void 0===n.simd||n.simd&&c||!n.simd&&!c}).map(function(n){return a.locateFile(n.url,a.$)});importScripts.apply(null,D(d));e=a;return G(p,createMediapipeSolutionsWasm(Module),6);case 6:e.h=p.h;a.l=new OffscreenCanvas(1,1);a.h.canvas=a.l;g=a.h.GL.createContext(a.l,{antialias:!1,\nalpha:!1,ja:\"undefined\"!==typeof WebGL2RenderingContext?2:1});a.h.GL.makeContextCurrent(g);p.g=4;break;case 7:a.l=document.createElement(\"canvas\");q=a.l.getContext(\"webgl2\",{});if(!q&&(q=a.l.getContext(\"webgl\",{}),!q))return alert(\"Failed to create WebGL canvas context when passing video frame.\"),p.return();a.G=q;a.h.canvas=a.l;a.h.createContext(a.l,!0,!0,{});case 4:a.i=new a.h.SolutionWasm,a.Z=!1,p.g=0}})}\nfunction Jc(a){var b,c,d,e,g,f,h,k;return J(function(l){if(1==l.g){if(a.g.graph&&a.g.graph.url&&a.Y===a.g.graph.url)return l.return();a.s=!0;if(!a.g.graph||!a.g.graph.url){l.g=2;return}a.Y=a.g.graph.url;return G(l,Ic(a,a.g.graph.url),3)}2!=l.g&&(b=l.h,a.i.loadGraph(b));c=C(Object.keys(a.C));for(d=c.next();!d.done;d=c.next())e=d.value,a.i.overrideFile(e,a.C[e]);a.C={};if(a.g.listeners)for(g=C(a.g.listeners),f=g.next();!f.done;f=g.next())h=f.value,Kc(a,h);k=a.j;a.j={};a.setOptions(k);l.g=0})}\nx.reset=function(){var a=this;return J(function(b){a.i&&(a.i.reset(),a.o={},a.u={});b.g=0})};\nx.setOptions=function(a,b){var c=this;if(b=b||this.g.options){for(var d=[],e=[],g={},f=C(Object.keys(a)),h=f.next();!h.done;g={R:g.R,S:g.S},h=f.next()){var k=h.value;k in this.j&&this.j[k]===a[k]||(this.j[k]=a[k],h=b[k],void 0!==h&&(h.onChange&&(g.R=h.onChange,g.S=a[k],d.push(function(l){return function(){var m;return J(function(q){if(1==q.g)return G(q,l.R(l.S),2);m=q.h;!0===m&&(c.s=!0);q.g=0})}}(g))),h.graphOptionXref&&(k={valueNumber:1===h.type?a[k]:0,valueBoolean:0===h.type?a[k]:!1,valueString:2===\nh.type?a[k]:\"\"},h=Object.assign(Object.assign(Object.assign({},{calculatorName:\"\",calculatorIndex:0}),h.graphOptionXref),k),e.push(h))))}if(0!==d.length||0!==e.length)this.s=!0,this.B=(void 0===this.B?[]:this.B).concat(e),this.A=(void 0===this.A?[]:this.A).concat(d)}};\nfunction Lc(a){var b,c,d,e,g,f,h;return J(function(k){switch(k.g){case 1:if(!a.s)return k.return();if(!a.A){k.g=2;break}b=C(a.A);c=b.next();case 3:if(c.done){k.g=5;break}d=c.value;return G(k,d(),4);case 4:c=b.next();k.g=3;break;case 5:a.A=void 0;case 2:if(a.B){e=new a.h.GraphOptionChangeRequestList;g=C(a.B);for(f=g.next();!f.done;f=g.next())h=f.value,e.push_back(h);a.i.changeOptions(e);e.delete();a.B=void 0}a.s=!1;k.g=0}})}\nx.initialize=function(){var a=this;return J(function(b){return 1==b.g?G(b,Hc(a),2):3!=b.g?G(b,Jc(a),3):G(b,Lc(a),0)})};function Ic(a,b){var c,d;return J(function(e){if(b in a.H)return e.return(a.H[b]);c=a.locateFile(b,\"\");d=fetch(c).then(function(g){return g.arrayBuffer()});a.H[b]=d;return e.return(d)})}x.overrideFile=function(a,b){this.i?this.i.overrideFile(a,b):this.C[a]=b};x.clearOverriddenFiles=function(){this.C={};this.i&&this.i.clearOverriddenFiles()};\nx.send=function(a,b){var c=this,d,e,g,f,h,k,l,m,q;return J(function(p){switch(p.g){case 1:if(!c.g.inputs)return p.return();d=1E3*(void 0===b||null===b?performance.now():b);return G(p,c.D,2);case 2:return G(p,c.initialize(),3);case 3:e=new c.h.PacketDataList;g=C(Object.keys(a));for(f=g.next();!f.done;f=g.next())if(h=f.value,k=c.g.inputs[h]){a:{var n=a[h];switch(k.type){case \"video\":var r=c.o[k.stream];r||(r=new xc(c.h,c.G),c.o[k.stream]=r);0===r.l&&(r.l=r.h.createTexture());if(\"undefined\"!==typeof HTMLVideoElement&&\nn instanceof HTMLVideoElement){var t=n.videoWidth;var w=n.videoHeight}else\"undefined\"!==typeof HTMLImageElement&&n instanceof HTMLImageElement?(t=n.naturalWidth,w=n.naturalHeight):(t=n.width,w=n.height);w={glName:r.l,width:t,height:w};t=r.g;t.canvas.width=w.width;t.canvas.height=w.height;t.activeTexture(t.TEXTURE0);r.h.bindTexture2d(r.l);t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,n);r.h.bindTexture2d(0);r=w;break a;case \"detections\":r=c.o[k.stream];r||(r=new Ac(c.h),c.o[k.stream]=r);\nr.data||(r.data=new r.g.DetectionListData);r.data.reset(n.length);for(w=0;w<n.length;++w){t=n[w];var v=r.data,A=v.setBoundingBox,I=w;var F=t.boundingBox;var u=new lc;W(u,1,F.xCenter);W(u,2,F.yCenter);W(u,3,F.height);W(u,4,F.width);W(u,5,F.rotation);W(u,6,F.rectId);F=Vb(u,mc);A.call(v,I,F);if(t.landmarks)for(v=0;v<t.landmarks.length;++v){u=t.landmarks[v];var z=u.visibility?!0:!1;A=r.data;I=A.addNormalizedLandmark;F=w;u=Object.assign(Object.assign({},u),{visibility:z?u.visibility:0});z=new gc;W(z,1,\nu.x);W(z,2,u.y);W(z,3,u.z);u.visibility&&W(z,4,u.visibility);u=Vb(z,hc);I.call(A,F,u)}if(t.V)for(v=0;v<t.V.length;++v)A=r.data,I=A.addClassification,F=w,u=t.V[v],z=new bc,W(z,2,u.ga),u.index&&W(z,1,u.index),u.label&&W(z,3,u.label),u.displayName&&W(z,4,u.displayName),u=Vb(z,cc),I.call(A,F,u)}r=r.data;break a;default:r={}}}l=r;m=k.stream;switch(k.type){case \"video\":e.pushTexture2d(Object.assign(Object.assign({},l),{stream:m,timestamp:d}));break;case \"detections\":q=l;q.stream=m;q.timestamp=d;e.pushDetectionList(q);\nbreak;default:throw Error(\"Unknown input config type: '\"+k.type+\"'\");}}c.i.send(e);return G(p,c.D,4);case 4:e.delete(),p.g=0}})};\nfunction Mc(a,b,c){var d,e,g,f,h,k,l,m,q,p,n,r,t,w;return J(function(v){switch(v.g){case 1:if(!c)return v.return(b);d={};e=0;g=C(Object.keys(c));for(f=g.next();!f.done;f=g.next())h=f.value,k=c[h],\"string\"!==typeof k&&\"texture\"===k.type&&void 0!==b[k.stream]&&++e;1<e&&(a.I=!1);l=C(Object.keys(c));f=l.next();case 2:if(f.done){v.g=4;break}m=f.value;q=c[m];if(\"string\"===typeof q)return t=d,w=m,G(v,Nc(a,m,b[q]),14);p=b[q.stream];if(\"detection_list\"===q.type){if(p){var A=p.getRectList();for(var I=p.getLandmarksList(),\nF=p.getClassificationsList(),u=[],z=0;z<A.size();++z){var R=Ub(A.get(z),lc,mc);R={boundingBox:{xCenter:X(R,1),yCenter:X(R,2),height:X(R,3),width:X(R,4),rotation:X(R,5,0),rectId:kb(R,6)},landmarks:ib(Ub(I.get(z),ic,kc),gc,1).map(wc),V:vc(Ub(F.get(z),dc,fc))};u.push(R)}A=u}else A=[];d[m]=A;v.g=7;break}if(\"proto_list\"===q.type){if(p){A=Array(p.size());for(I=0;I<p.size();I++)A[I]=p.get(I);p.delete()}else A=[];d[m]=A;v.g=7;break}if(void 0===p){v.g=3;break}if(\"float_list\"===q.type){d[m]=p;v.g=7;break}if(\"proto\"===\nq.type){d[m]=p;v.g=7;break}if(\"texture\"!==q.type)throw Error(\"Unknown output config type: '\"+q.type+\"'\");n=a.u[m];n||(n=new xc(a.h,a.G),a.u[m]=n);return G(v,yc(n,p,a.I),13);case 13:r=v.h,d[m]=r;case 7:q.transform&&d[m]&&(d[m]=q.transform(d[m]));v.g=3;break;case 14:t[w]=v.h;case 3:f=l.next();v.g=2;break;case 4:return v.return(d)}})}\nfunction Nc(a,b,c){var d;return J(function(e){return\"number\"===typeof c||c instanceof Uint8Array||c instanceof a.h.Uint8BlobList?e.return(c):c instanceof a.h.Texture2dDataOut?(d=a.u[b],d||(d=new xc(a.h,a.G),a.u[b]=d),e.return(yc(d,c,a.I))):e.return(void 0)})}\nfunction Kc(a,b){for(var c=b.name||\"$\",d=[].concat(D(b.wants)),e=new a.h.StringList,g=C(b.wants),f=g.next();!f.done;f=g.next())e.push_back(f.value);g=a.h.PacketListener.implement({onResults:function(h){for(var k={},l=0;l<b.wants.length;++l)k[d[l]]=h.get(l);var m=a.listeners[c];m&&(a.D=Mc(a,k,b.outs).then(function(q){q=m(q);for(var p=0;p<b.wants.length;++p){var n=k[d[p]];\"object\"===typeof n&&n.hasOwnProperty&&n.hasOwnProperty(\"delete\")&&n.delete()}q&&(a.D=q)}))}});a.i.attachMultiListener(e,g);e.delete()}\nx.onResults=function(a,b){this.listeners[b||\"$\"]=a};K(\"Solution\",Gc);K(\"OptionType\",{BOOL:0,NUMBER:1,ia:2,0:\"BOOL\",1:\"NUMBER\",2:\"STRING\"});function Oc(a){var b=this;a=a||{};var c={url:\"face_detection_short.binarypb\"},d={type:1,graphOptionXref:{calculatorType:\"TensorsToDetectionsCalculator\",calculatorName:\"facedetectionshortrangegpu__facedetectionshortrangecommon__TensorsToDetectionsCalculator\",fieldName:\"min_score_thresh\"}};this.g=new Gc({locateFile:a.locateFile,files:[{data:!0,url:\"face_detection_short.binarypb\"},{data:!0,url:\"face_detection_short_range.tflite\"},{simd:!0,url:\"face_detection_solution_simd_wasm_bin.js\"},{simd:!1,url:\"face_detection_solution_wasm_bin.js\"}],\ngraph:c,listeners:[{wants:[\"detections\",\"image_transformed\"],outs:{image:\"image_transformed\",detections:{type:\"detection_list\",stream:\"detections\"}}}],inputs:{image:{type:\"video\",stream:\"input_frames_gpu\"}},options:{useCpuInference:{type:0,graphOptionXref:{calculatorType:\"InferenceCalculator\",fieldName:\"use_cpu_inference\"},default:\"object\"!==typeof window||void 0===window.navigator?!1:\"iPad Simulator;iPhone Simulator;iPod Simulator;iPad;iPhone;iPod\".split(\";\").includes(navigator.platform)||navigator.userAgent.includes(\"Mac\")&&\n\"ontouchend\"in document},selfieMode:{type:0,graphOptionXref:{calculatorType:\"GlScalerCalculator\",calculatorIndex:1,fieldName:\"flip_horizontal\"}},model:{type:0,onChange:function(e){var g,f,h,k,l,m;return J(function(q){switch(q.g){case 1:g=\"short\"===e?[\"face_detection_short_range.tflite\"]:[\"face_detection_full_range_sparse.tflite\"],f=C(g),h=f.next();case 2:if(h.done){q.g=4;break}k=h.value;l=\"third_party/mediapipe/modules/face_detection/\"+k;return G(q,Ic(b.g,k),5);case 5:m=q.h;b.g.overrideFile(l,m);\nh=f.next();q.g=2;break;case 4:return c.url=\"short\"===e?\"face_detection_short.binarypb\":\"face_detection_full.binarypb\",d.graphOptionXref.calculatorName=\"short\"===e?\"facedetectionshortrangegpu__facedetectionshortrangecommon__TensorsToDetectionsCalculator\":\"facedetectionfullrangegpu__facedetectionfullrangecommon__TensorsToDetectionsCalculator\",q.return(!0)}})}},minDetectionConfidence:d}})}x=Oc.prototype;x.close=function(){this.g.close();return Promise.resolve()};x.onResults=function(a){this.g.onResults(a)};\nx.initialize=function(){var a=this;return J(function(b){return G(b,a.g.initialize(),0)})};x.reset=function(){this.g.reset()};x.send=function(a){var b=this;return J(function(c){return G(c,b.g.send(a),0)})};x.setOptions=function(a){this.g.setOptions(a)};K(\"FaceDetection\",Oc);K(\"FACEDETECTION_LIPS\",nc);K(\"FACEDETECTION_LEFT_EYE\",oc);K(\"FACEDETECTION_LEFT_EYEBROW\",pc);K(\"FACEDETECTION_RIGHT_EYE\",qc);K(\"FACEDETECTION_RIGHT_EYEBROW\",rc);K(\"FACEDETECTION_FACE_OVAL\",sc);K(\"FACEDETECTION_CONTOURS\",tc);\nK(\"FACEDETECTION_TESSELATION\",[[127,34],[34,139],[139,127],[11,0],[0,37],[37,11],[232,231],[231,120],[120,232],[72,37],[37,39],[39,72],[128,121],[121,47],[47,128],[232,121],[121,128],[128,232],[104,69],[69,67],[67,104],[175,171],[171,148],[148,175],[118,50],[50,101],[101,118],[73,39],[39,40],[40,73],[9,151],[151,108],[108,9],[48,115],[115,131],[131,48],[194,204],[204,211],[211,194],[74,40],[40,185],[185,74],[80,42],[42,183],[183,80],[40,92],[92,186],[186,40],[230,229],[229,118],[118,230],[202,212],\n[212,214],[214,202],[83,18],[18,17],[17,83],[76,61],[61,146],[146,76],[160,29],[29,30],[30,160],[56,157],[157,173],[173,56],[106,204],[204,194],[194,106],[135,214],[214,192],[192,135],[203,165],[165,98],[98,203],[21,71],[71,68],[68,21],[51,45],[45,4],[4,51],[144,24],[24,23],[23,144],[77,146],[146,91],[91,77],[205,50],[50,187],[187,205],[201,200],[200,18],[18,201],[91,106],[106,182],[182,91],[90,91],[91,181],[181,90],[85,84],[84,17],[17,85],[206,203],[203,36],[36,206],[148,171],[171,140],[140,148],\n[92,40],[40,39],[39,92],[193,189],[189,244],[244,193],[159,158],[158,28],[28,159],[247,246],[246,161],[161,247],[236,3],[3,196],[196,236],[54,68],[68,104],[104,54],[193,168],[168,8],[8,193],[117,228],[228,31],[31,117],[189,193],[193,55],[55,189],[98,97],[97,99],[99,98],[126,47],[47,100],[100,126],[166,79],[79,218],[218,166],[155,154],[154,26],[26,155],[209,49],[49,131],[131,209],[135,136],[136,150],[150,135],[47,126],[126,217],[217,47],[223,52],[52,53],[53,223],[45,51],[51,134],[134,45],[211,170],\n[170,140],[140,211],[67,69],[69,108],[108,67],[43,106],[106,91],[91,43],[230,119],[119,120],[120,230],[226,130],[130,247],[247,226],[63,53],[53,52],[52,63],[238,20],[20,242],[242,238],[46,70],[70,156],[156,46],[78,62],[62,96],[96,78],[46,53],[53,63],[63,46],[143,34],[34,227],[227,143],[123,117],[117,111],[111,123],[44,125],[125,19],[19,44],[236,134],[134,51],[51,236],[216,206],[206,205],[205,216],[154,153],[153,22],[22,154],[39,37],[37,167],[167,39],[200,201],[201,208],[208,200],[36,142],[142,100],\n[100,36],[57,212],[212,202],[202,57],[20,60],[60,99],[99,20],[28,158],[158,157],[157,28],[35,226],[226,113],[113,35],[160,159],[159,27],[27,160],[204,202],[202,210],[210,204],[113,225],[225,46],[46,113],[43,202],[202,204],[204,43],[62,76],[76,77],[77,62],[137,123],[123,116],[116,137],[41,38],[38,72],[72,41],[203,129],[129,142],[142,203],[64,98],[98,240],[240,64],[49,102],[102,64],[64,49],[41,73],[73,74],[74,41],[212,216],[216,207],[207,212],[42,74],[74,184],[184,42],[169,170],[170,211],[211,169],\n[170,149],[149,176],[176,170],[105,66],[66,69],[69,105],[122,6],[6,168],[168,122],[123,147],[147,187],[187,123],[96,77],[77,90],[90,96],[65,55],[55,107],[107,65],[89,90],[90,180],[180,89],[101,100],[100,120],[120,101],[63,105],[105,104],[104,63],[93,137],[137,227],[227,93],[15,86],[86,85],[85,15],[129,102],[102,49],[49,129],[14,87],[87,86],[86,14],[55,8],[8,9],[9,55],[100,47],[47,121],[121,100],[145,23],[23,22],[22,145],[88,89],[89,179],[179,88],[6,122],[122,196],[196,6],[88,95],[95,96],[96,88],[138,\n172],[172,136],[136,138],[215,58],[58,172],[172,215],[115,48],[48,219],[219,115],[42,80],[80,81],[81,42],[195,3],[3,51],[51,195],[43,146],[146,61],[61,43],[171,175],[175,199],[199,171],[81,82],[82,38],[38,81],[53,46],[46,225],[225,53],[144,163],[163,110],[110,144],[52,65],[65,66],[66,52],[229,228],[228,117],[117,229],[34,127],[127,234],[234,34],[107,108],[108,69],[69,107],[109,108],[108,151],[151,109],[48,64],[64,235],[235,48],[62,78],[78,191],[191,62],[129,209],[209,126],[126,129],[111,35],[35,143],\n[143,111],[117,123],[123,50],[50,117],[222,65],[65,52],[52,222],[19,125],[125,141],[141,19],[221,55],[55,65],[65,221],[3,195],[195,197],[197,3],[25,7],[7,33],[33,25],[220,237],[237,44],[44,220],[70,71],[71,139],[139,70],[122,193],[193,245],[245,122],[247,130],[130,33],[33,247],[71,21],[21,162],[162,71],[170,169],[169,150],[150,170],[188,174],[174,196],[196,188],[216,186],[186,92],[92,216],[2,97],[97,167],[167,2],[141,125],[125,241],[241,141],[164,167],[167,37],[37,164],[72,38],[38,12],[12,72],[38,\n82],[82,13],[13,38],[63,68],[68,71],[71,63],[226,35],[35,111],[111,226],[101,50],[50,205],[205,101],[206,92],[92,165],[165,206],[209,198],[198,217],[217,209],[165,167],[167,97],[97,165],[220,115],[115,218],[218,220],[133,112],[112,243],[243,133],[239,238],[238,241],[241,239],[214,135],[135,169],[169,214],[190,173],[173,133],[133,190],[171,208],[208,32],[32,171],[125,44],[44,237],[237,125],[86,87],[87,178],[178,86],[85,86],[86,179],[179,85],[84,85],[85,180],[180,84],[83,84],[84,181],[181,83],[201,\n83],[83,182],[182,201],[137,93],[93,132],[132,137],[76,62],[62,183],[183,76],[61,76],[76,184],[184,61],[57,61],[61,185],[185,57],[212,57],[57,186],[186,212],[214,207],[207,187],[187,214],[34,143],[143,156],[156,34],[79,239],[239,237],[237,79],[123,137],[137,177],[177,123],[44,1],[1,4],[4,44],[201,194],[194,32],[32,201],[64,102],[102,129],[129,64],[213,215],[215,138],[138,213],[59,166],[166,219],[219,59],[242,99],[99,97],[97,242],[2,94],[94,141],[141,2],[75,59],[59,235],[235,75],[24,110],[110,228],\n[228,24],[25,130],[130,226],[226,25],[23,24],[24,229],[229,23],[22,23],[23,230],[230,22],[26,22],[22,231],[231,26],[112,26],[26,232],[232,112],[189,190],[190,243],[243,189],[221,56],[56,190],[190,221],[28,56],[56,221],[221,28],[27,28],[28,222],[222,27],[29,27],[27,223],[223,29],[30,29],[29,224],[224,30],[247,30],[30,225],[225,247],[238,79],[79,20],[20,238],[166,59],[59,75],[75,166],[60,75],[75,240],[240,60],[147,177],[177,215],[215,147],[20,79],[79,166],[166,20],[187,147],[147,213],[213,187],[112,\n233],[233,244],[244,112],[233,128],[128,245],[245,233],[128,114],[114,188],[188,128],[114,217],[217,174],[174,114],[131,115],[115,220],[220,131],[217,198],[198,236],[236,217],[198,131],[131,134],[134,198],[177,132],[132,58],[58,177],[143,35],[35,124],[124,143],[110,163],[163,7],[7,110],[228,110],[110,25],[25,228],[356,389],[389,368],[368,356],[11,302],[302,267],[267,11],[452,350],[350,349],[349,452],[302,303],[303,269],[269,302],[357,343],[343,277],[277,357],[452,453],[453,357],[357,452],[333,332],\n[332,297],[297,333],[175,152],[152,377],[377,175],[347,348],[348,330],[330,347],[303,304],[304,270],[270,303],[9,336],[336,337],[337,9],[278,279],[279,360],[360,278],[418,262],[262,431],[431,418],[304,408],[408,409],[409,304],[310,415],[415,407],[407,310],[270,409],[409,410],[410,270],[450,348],[348,347],[347,450],[422,430],[430,434],[434,422],[313,314],[314,17],[17,313],[306,307],[307,375],[375,306],[387,388],[388,260],[260,387],[286,414],[414,398],[398,286],[335,406],[406,418],[418,335],[364,367],\n[367,416],[416,364],[423,358],[358,327],[327,423],[251,284],[284,298],[298,251],[281,5],[5,4],[4,281],[373,374],[374,253],[253,373],[307,320],[320,321],[321,307],[425,427],[427,411],[411,425],[421,313],[313,18],[18,421],[321,405],[405,406],[406,321],[320,404],[404,405],[405,320],[315,16],[16,17],[17,315],[426,425],[425,266],[266,426],[377,400],[400,369],[369,377],[322,391],[391,269],[269,322],[417,465],[465,464],[464,417],[386,257],[257,258],[258,386],[466,260],[260,388],[388,466],[456,399],[399,\n419],[419,456],[284,332],[332,333],[333,284],[417,285],[285,8],[8,417],[346,340],[340,261],[261,346],[413,441],[441,285],[285,413],[327,460],[460,328],[328,327],[355,371],[371,329],[329,355],[392,439],[439,438],[438,392],[382,341],[341,256],[256,382],[429,420],[420,360],[360,429],[364,394],[394,379],[379,364],[277,343],[343,437],[437,277],[443,444],[444,283],[283,443],[275,440],[440,363],[363,275],[431,262],[262,369],[369,431],[297,338],[338,337],[337,297],[273,375],[375,321],[321,273],[450,451],\n[451,349],[349,450],[446,342],[342,467],[467,446],[293,334],[334,282],[282,293],[458,461],[461,462],[462,458],[276,353],[353,383],[383,276],[308,324],[324,325],[325,308],[276,300],[300,293],[293,276],[372,345],[345,447],[447,372],[352,345],[345,340],[340,352],[274,1],[1,19],[19,274],[456,248],[248,281],[281,456],[436,427],[427,425],[425,436],[381,256],[256,252],[252,381],[269,391],[391,393],[393,269],[200,199],[199,428],[428,200],[266,330],[330,329],[329,266],[287,273],[273,422],[422,287],[250,462],\n[462,328],[328,250],[258,286],[286,384],[384,258],[265,353],[353,342],[342,265],[387,259],[259,257],[257,387],[424,431],[431,430],[430,424],[342,353],[353,276],[276,342],[273,335],[335,424],[424,273],[292,325],[325,307],[307,292],[366,447],[447,345],[345,366],[271,303],[303,302],[302,271],[423,266],[266,371],[371,423],[294,455],[455,460],[460,294],[279,278],[278,294],[294,279],[271,272],[272,304],[304,271],[432,434],[434,427],[427,432],[272,407],[407,408],[408,272],[394,430],[430,431],[431,394],[395,\n369],[369,400],[400,395],[334,333],[333,299],[299,334],[351,417],[417,168],[168,351],[352,280],[280,411],[411,352],[325,319],[319,320],[320,325],[295,296],[296,336],[336,295],[319,403],[403,404],[404,319],[330,348],[348,349],[349,330],[293,298],[298,333],[333,293],[323,454],[454,447],[447,323],[15,16],[16,315],[315,15],[358,429],[429,279],[279,358],[14,15],[15,316],[316,14],[285,336],[336,9],[9,285],[329,349],[349,350],[350,329],[374,380],[380,252],[252,374],[318,402],[402,403],[403,318],[6,197],\n[197,419],[419,6],[318,319],[319,325],[325,318],[367,364],[364,365],[365,367],[435,367],[367,397],[397,435],[344,438],[438,439],[439,344],[272,271],[271,311],[311,272],[195,5],[5,281],[281,195],[273,287],[287,291],[291,273],[396,428],[428,199],[199,396],[311,271],[271,268],[268,311],[283,444],[444,445],[445,283],[373,254],[254,339],[339,373],[282,334],[334,296],[296,282],[449,347],[347,346],[346,449],[264,447],[447,454],[454,264],[336,296],[296,299],[299,336],[338,10],[10,151],[151,338],[278,439],\n[439,455],[455,278],[292,407],[407,415],[415,292],[358,371],[371,355],[355,358],[340,345],[345,372],[372,340],[346,347],[347,280],[280,346],[442,443],[443,282],[282,442],[19,94],[94,370],[370,19],[441,442],[442,295],[295,441],[248,419],[419,197],[197,248],[263,255],[255,359],[359,263],[440,275],[275,274],[274,440],[300,383],[383,368],[368,300],[351,412],[412,465],[465,351],[263,467],[467,466],[466,263],[301,368],[368,389],[389,301],[395,378],[378,379],[379,395],[412,351],[351,419],[419,412],[436,\n426],[426,322],[322,436],[2,164],[164,393],[393,2],[370,462],[462,461],[461,370],[164,0],[0,267],[267,164],[302,11],[11,12],[12,302],[268,12],[12,13],[13,268],[293,300],[300,301],[301,293],[446,261],[261,340],[340,446],[330,266],[266,425],[425,330],[426,423],[423,391],[391,426],[429,355],[355,437],[437,429],[391,327],[327,326],[326,391],[440,457],[457,438],[438,440],[341,382],[382,362],[362,341],[459,457],[457,461],[461,459],[434,430],[430,394],[394,434],[414,463],[463,362],[362,414],[396,369],[369,\n262],[262,396],[354,461],[461,457],[457,354],[316,403],[403,402],[402,316],[315,404],[404,403],[403,315],[314,405],[405,404],[404,314],[313,406],[406,405],[405,313],[421,418],[418,406],[406,421],[366,401],[401,361],[361,366],[306,408],[408,407],[407,306],[291,409],[409,408],[408,291],[287,410],[410,409],[409,287],[432,436],[436,410],[410,432],[434,416],[416,411],[411,434],[264,368],[368,383],[383,264],[309,438],[438,457],[457,309],[352,376],[376,401],[401,352],[274,275],[275,4],[4,274],[421,428],\n[428,262],[262,421],[294,327],[327,358],[358,294],[433,416],[416,367],[367,433],[289,455],[455,439],[439,289],[462,370],[370,326],[326,462],[2,326],[326,370],[370,2],[305,460],[460,455],[455,305],[254,449],[449,448],[448,254],[255,261],[261,446],[446,255],[253,450],[450,449],[449,253],[252,451],[451,450],[450,252],[256,452],[452,451],[451,256],[341,453],[453,452],[452,341],[413,464],[464,463],[463,413],[441,413],[413,414],[414,441],[258,442],[442,441],[441,258],[257,443],[443,442],[442,257],[259,\n444],[444,443],[443,259],[260,445],[445,444],[444,260],[467,342],[342,445],[445,467],[459,458],[458,250],[250,459],[289,392],[392,290],[290,289],[290,328],[328,460],[460,290],[376,433],[433,435],[435,376],[250,290],[290,392],[392,250],[411,416],[416,433],[433,411],[341,463],[463,464],[464,341],[453,464],[464,465],[465,453],[357,465],[465,412],[412,357],[343,412],[412,399],[399,343],[360,363],[363,440],[440,360],[437,399],[399,456],[456,437],[420,456],[456,363],[363,420],[401,435],[435,288],[288,401],\n[372,383],[383,353],[353,372],[339,255],[255,249],[249,339],[448,261],[261,255],[255,448],[133,243],[243,190],[190,133],[133,155],[155,112],[112,133],[33,246],[246,247],[247,33],[33,130],[130,25],[25,33],[398,384],[384,286],[286,398],[362,398],[398,414],[414,362],[362,463],[463,341],[341,362],[263,359],[359,467],[467,263],[263,249],[249,255],[255,263],[466,467],[467,260],[260,466],[75,60],[60,166],[166,75],[238,239],[239,79],[79,238],[162,127],[127,139],[139,162],[72,11],[11,37],[37,72],[121,232],\n[232,120],[120,121],[73,72],[72,39],[39,73],[114,128],[128,47],[47,114],[233,232],[232,128],[128,233],[103,104],[104,67],[67,103],[152,175],[175,148],[148,152],[119,118],[118,101],[101,119],[74,73],[73,40],[40,74],[107,9],[9,108],[108,107],[49,48],[48,131],[131,49],[32,194],[194,211],[211,32],[184,74],[74,185],[185,184],[191,80],[80,183],[183,191],[185,40],[40,186],[186,185],[119,230],[230,118],[118,119],[210,202],[202,214],[214,210],[84,83],[83,17],[17,84],[77,76],[76,146],[146,77],[161,160],[160,\n30],[30,161],[190,56],[56,173],[173,190],[182,106],[106,194],[194,182],[138,135],[135,192],[192,138],[129,203],[203,98],[98,129],[54,21],[21,68],[68,54],[5,51],[51,4],[4,5],[145,144],[144,23],[23,145],[90,77],[77,91],[91,90],[207,205],[205,187],[187,207],[83,201],[201,18],[18,83],[181,91],[91,182],[182,181],[180,90],[90,181],[181,180],[16,85],[85,17],[17,16],[205,206],[206,36],[36,205],[176,148],[148,140],[140,176],[165,92],[92,39],[39,165],[245,193],[193,244],[244,245],[27,159],[159,28],[28,27],\n[30,247],[247,161],[161,30],[174,236],[236,196],[196,174],[103,54],[54,104],[104,103],[55,193],[193,8],[8,55],[111,117],[117,31],[31,111],[221,189],[189,55],[55,221],[240,98],[98,99],[99,240],[142,126],[126,100],[100,142],[219,166],[166,218],[218,219],[112,155],[155,26],[26,112],[198,209],[209,131],[131,198],[169,135],[135,150],[150,169],[114,47],[47,217],[217,114],[224,223],[223,53],[53,224],[220,45],[45,134],[134,220],[32,211],[211,140],[140,32],[109,67],[67,108],[108,109],[146,43],[43,91],[91,\n146],[231,230],[230,120],[120,231],[113,226],[226,247],[247,113],[105,63],[63,52],[52,105],[241,238],[238,242],[242,241],[124,46],[46,156],[156,124],[95,78],[78,96],[96,95],[70,46],[46,63],[63,70],[116,143],[143,227],[227,116],[116,123],[123,111],[111,116],[1,44],[44,19],[19,1],[3,236],[236,51],[51,3],[207,216],[216,205],[205,207],[26,154],[154,22],[22,26],[165,39],[39,167],[167,165],[199,200],[200,208],[208,199],[101,36],[36,100],[100,101],[43,57],[57,202],[202,43],[242,20],[20,99],[99,242],[56,\n28],[28,157],[157,56],[124,35],[35,113],[113,124],[29,160],[160,27],[27,29],[211,204],[204,210],[210,211],[124,113],[113,46],[46,124],[106,43],[43,204],[204,106],[96,62],[62,77],[77,96],[227,137],[137,116],[116,227],[73,41],[41,72],[72,73],[36,203],[203,142],[142,36],[235,64],[64,240],[240,235],[48,49],[49,64],[64,48],[42,41],[41,74],[74,42],[214,212],[212,207],[207,214],[183,42],[42,184],[184,183],[210,169],[169,211],[211,210],[140,170],[170,176],[176,140],[104,105],[105,69],[69,104],[193,122],[122,\n168],[168,193],[50,123],[123,187],[187,50],[89,96],[96,90],[90,89],[66,65],[65,107],[107,66],[179,89],[89,180],[180,179],[119,101],[101,120],[120,119],[68,63],[63,104],[104,68],[234,93],[93,227],[227,234],[16,15],[15,85],[85,16],[209,129],[129,49],[49,209],[15,14],[14,86],[86,15],[107,55],[55,9],[9,107],[120,100],[100,121],[121,120],[153,145],[145,22],[22,153],[178,88],[88,179],[179,178],[197,6],[6,196],[196,197],[89,88],[88,96],[96,89],[135,138],[138,136],[136,135],[138,215],[215,172],[172,138],\n[218,115],[115,219],[219,218],[41,42],[42,81],[81,41],[5,195],[195,51],[51,5],[57,43],[43,61],[61,57],[208,171],[171,199],[199,208],[41,81],[81,38],[38,41],[224,53],[53,225],[225,224],[24,144],[144,110],[110,24],[105,52],[52,66],[66,105],[118,229],[229,117],[117,118],[227,34],[34,234],[234,227],[66,107],[107,69],[69,66],[10,109],[109,151],[151,10],[219,48],[48,235],[235,219],[183,62],[62,191],[191,183],[142,129],[129,126],[126,142],[116,111],[111,143],[143,116],[118,117],[117,50],[50,118],[223,222],\n[222,52],[52,223],[94,19],[19,141],[141,94],[222,221],[221,65],[65,222],[196,3],[3,197],[197,196],[45,220],[220,44],[44,45],[156,70],[70,139],[139,156],[188,122],[122,245],[245,188],[139,71],[71,162],[162,139],[149,170],[170,150],[150,149],[122,188],[188,196],[196,122],[206,216],[216,92],[92,206],[164,2],[2,167],[167,164],[242,141],[141,241],[241,242],[0,164],[164,37],[37,0],[11,72],[72,12],[12,11],[12,38],[38,13],[13,12],[70,63],[63,71],[71,70],[31,226],[226,111],[111,31],[36,101],[101,205],[205,\n36],[203,206],[206,165],[165,203],[126,209],[209,217],[217,126],[98,165],[165,97],[97,98],[237,220],[220,218],[218,237],[237,239],[239,241],[241,237],[210,214],[214,169],[169,210],[140,171],[171,32],[32,140],[241,125],[125,237],[237,241],[179,86],[86,178],[178,179],[180,85],[85,179],[179,180],[181,84],[84,180],[180,181],[182,83],[83,181],[181,182],[194,201],[201,182],[182,194],[177,137],[137,132],[132,177],[184,76],[76,183],[183,184],[185,61],[61,184],[184,185],[186,57],[57,185],[185,186],[216,212],\n[212,186],[186,216],[192,214],[214,187],[187,192],[139,34],[34,156],[156,139],[218,79],[79,237],[237,218],[147,123],[123,177],[177,147],[45,44],[44,4],[4,45],[208,201],[201,32],[32,208],[98,64],[64,129],[129,98],[192,213],[213,138],[138,192],[235,59],[59,219],[219,235],[141,242],[242,97],[97,141],[97,2],[2,141],[141,97],[240,75],[75,235],[235,240],[229,24],[24,228],[228,229],[31,25],[25,226],[226,31],[230,23],[23,229],[229,230],[231,22],[22,230],[230,231],[232,26],[26,231],[231,232],[233,112],[112,\n232],[232,233],[244,189],[189,243],[243,244],[189,221],[221,190],[190,189],[222,28],[28,221],[221,222],[223,27],[27,222],[222,223],[224,29],[29,223],[223,224],[225,30],[30,224],[224,225],[113,247],[247,225],[225,113],[99,60],[60,240],[240,99],[213,147],[147,215],[215,213],[60,20],[20,166],[166,60],[192,187],[187,213],[213,192],[243,112],[112,244],[244,243],[244,233],[233,245],[245,244],[245,128],[128,188],[188,245],[188,114],[114,174],[174,188],[134,131],[131,220],[220,134],[174,217],[217,236],[236,\n174],[236,198],[198,134],[134,236],[215,177],[177,58],[58,215],[156,143],[143,124],[124,156],[25,110],[110,7],[7,25],[31,228],[228,25],[25,31],[264,356],[356,368],[368,264],[0,11],[11,267],[267,0],[451,452],[452,349],[349,451],[267,302],[302,269],[269,267],[350,357],[357,277],[277,350],[350,452],[452,357],[357,350],[299,333],[333,297],[297,299],[396,175],[175,377],[377,396],[280,347],[347,330],[330,280],[269,303],[303,270],[270,269],[151,9],[9,337],[337,151],[344,278],[278,360],[360,344],[424,418],\n[418,431],[431,424],[270,304],[304,409],[409,270],[272,310],[310,407],[407,272],[322,270],[270,410],[410,322],[449,450],[450,347],[347,449],[432,422],[422,434],[434,432],[18,313],[313,17],[17,18],[291,306],[306,375],[375,291],[259,387],[387,260],[260,259],[424,335],[335,418],[418,424],[434,364],[364,416],[416,434],[391,423],[423,327],[327,391],[301,251],[251,298],[298,301],[275,281],[281,4],[4,275],[254,373],[373,253],[253,254],[375,307],[307,321],[321,375],[280,425],[425,411],[411,280],[200,421],\n[421,18],[18,200],[335,321],[321,406],[406,335],[321,320],[320,405],[405,321],[314,315],[315,17],[17,314],[423,426],[426,266],[266,423],[396,377],[377,369],[369,396],[270,322],[322,269],[269,270],[413,417],[417,464],[464,413],[385,386],[386,258],[258,385],[248,456],[456,419],[419,248],[298,284],[284,333],[333,298],[168,417],[417,8],[8,168],[448,346],[346,261],[261,448],[417,413],[413,285],[285,417],[326,327],[327,328],[328,326],[277,355],[355,329],[329,277],[309,392],[392,438],[438,309],[381,382],\n[382,256],[256,381],[279,429],[429,360],[360,279],[365,364],[364,379],[379,365],[355,277],[277,437],[437,355],[282,443],[443,283],[283,282],[281,275],[275,363],[363,281],[395,431],[431,369],[369,395],[299,297],[297,337],[337,299],[335,273],[273,321],[321,335],[348,450],[450,349],[349,348],[359,446],[446,467],[467,359],[283,293],[293,282],[282,283],[250,458],[458,462],[462,250],[300,276],[276,383],[383,300],[292,308],[308,325],[325,292],[283,276],[276,293],[293,283],[264,372],[372,447],[447,264],[346,\n352],[352,340],[340,346],[354,274],[274,19],[19,354],[363,456],[456,281],[281,363],[426,436],[436,425],[425,426],[380,381],[381,252],[252,380],[267,269],[269,393],[393,267],[421,200],[200,428],[428,421],[371,266],[266,329],[329,371],[432,287],[287,422],[422,432],[290,250],[250,328],[328,290],[385,258],[258,384],[384,385],[446,265],[265,342],[342,446],[386,387],[387,257],[257,386],[422,424],[424,430],[430,422],[445,342],[342,276],[276,445],[422,273],[273,424],[424,422],[306,292],[292,307],[307,306],\n[352,366],[366,345],[345,352],[268,271],[271,302],[302,268],[358,423],[423,371],[371,358],[327,294],[294,460],[460,327],[331,279],[279,294],[294,331],[303,271],[271,304],[304,303],[436,432],[432,427],[427,436],[304,272],[272,408],[408,304],[395,394],[394,431],[431,395],[378,395],[395,400],[400,378],[296,334],[334,299],[299,296],[6,351],[351,168],[168,6],[376,352],[352,411],[411,376],[307,325],[325,320],[320,307],[285,295],[295,336],[336,285],[320,319],[319,404],[404,320],[329,330],[330,349],[349,\n329],[334,293],[293,333],[333,334],[366,323],[323,447],[447,366],[316,15],[15,315],[315,316],[331,358],[358,279],[279,331],[317,14],[14,316],[316,317],[8,285],[285,9],[9,8],[277,329],[329,350],[350,277],[253,374],[374,252],[252,253],[319,318],[318,403],[403,319],[351,6],[6,419],[419,351],[324,318],[318,325],[325,324],[397,367],[367,365],[365,397],[288,435],[435,397],[397,288],[278,344],[344,439],[439,278],[310,272],[272,311],[311,310],[248,195],[195,281],[281,248],[375,273],[273,291],[291,375],[175,\n396],[396,199],[199,175],[312,311],[311,268],[268,312],[276,283],[283,445],[445,276],[390,373],[373,339],[339,390],[295,282],[282,296],[296,295],[448,449],[449,346],[346,448],[356,264],[264,454],[454,356],[337,336],[336,299],[299,337],[337,338],[338,151],[151,337],[294,278],[278,455],[455,294],[308,292],[292,415],[415,308],[429,358],[358,355],[355,429],[265,340],[340,372],[372,265],[352,346],[346,280],[280,352],[295,442],[442,282],[282,295],[354,19],[19,370],[370,354],[285,441],[441,295],[295,285],\n[195,248],[248,197],[197,195],[457,440],[440,274],[274,457],[301,300],[300,368],[368,301],[417,351],[351,465],[465,417],[251,301],[301,389],[389,251],[394,395],[395,379],[379,394],[399,412],[412,419],[419,399],[410,436],[436,322],[322,410],[326,2],[2,393],[393,326],[354,370],[370,461],[461,354],[393,164],[164,267],[267,393],[268,302],[302,12],[12,268],[312,268],[268,13],[13,312],[298,293],[293,301],[301,298],[265,446],[446,340],[340,265],[280,330],[330,425],[425,280],[322,426],[426,391],[391,322],\n[420,429],[429,437],[437,420],[393,391],[391,326],[326,393],[344,440],[440,438],[438,344],[458,459],[459,461],[461,458],[364,434],[434,394],[394,364],[428,396],[396,262],[262,428],[274,354],[354,457],[457,274],[317,316],[316,402],[402,317],[316,315],[315,403],[403,316],[315,314],[314,404],[404,315],[314,313],[313,405],[405,314],[313,421],[421,406],[406,313],[323,366],[366,361],[361,323],[292,306],[306,407],[407,292],[306,291],[291,408],[408,306],[291,287],[287,409],[409,291],[287,432],[432,410],[410,\n287],[427,434],[434,411],[411,427],[372,264],[264,383],[383,372],[459,309],[309,457],[457,459],[366,352],[352,401],[401,366],[1,274],[274,4],[4,1],[418,421],[421,262],[262,418],[331,294],[294,358],[358,331],[435,433],[433,367],[367,435],[392,289],[289,439],[439,392],[328,462],[462,326],[326,328],[94,2],[2,370],[370,94],[289,305],[305,455],[455,289],[339,254],[254,448],[448,339],[359,255],[255,446],[446,359],[254,253],[253,449],[449,254],[253,252],[252,450],[450,253],[252,256],[256,451],[451,252],\n[256,341],[341,452],[452,256],[414,413],[413,463],[463,414],[286,441],[441,414],[414,286],[286,258],[258,441],[441,286],[258,257],[257,442],[442,258],[257,259],[259,443],[443,257],[259,260],[260,444],[444,259],[260,467],[467,445],[445,260],[309,459],[459,250],[250,309],[305,289],[289,290],[290,305],[305,290],[290,460],[460,305],[401,376],[376,435],[435,401],[309,250],[250,392],[392,309],[376,411],[411,433],[433,376],[453,341],[341,464],[464,453],[357,453],[453,465],[465,357],[343,357],[357,412],[412,\n343],[437,343],[343,399],[399,437],[344,360],[360,440],[440,344],[420,437],[437,456],[456,420],[360,420],[420,363],[363,360],[361,401],[401,288],[288,361],[265,372],[372,353],[353,265],[390,339],[339,249],[249,390],[339,448],[448,255],[255,339]]);K(\"VERSION\",\"0.4.1646425229\");}).call(this);\n","import '@mediapipe/face_detection'\nimport {\n FaceDetector,\n FaceDetectorResult,\n FilesetResolver,\n} from '@mediapipe/tasks-vision'\nimport {\n preloadFaceDetectorDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { modelCapabilities } from './CapabilityProbing'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { useContext, useEffect, useRef, useState } from 'react'\nimport { Frame } from '../utils/getFrameDimensions'\nimport { convertBoundingBox, waitForVideoReady } from './helpers'\nimport { CameraStateContext } from '../../components/camera/CameraProvider'\n\nexport const defaultFaceDetectorModelPath =\n 'https://websdk-cdn-dev.idmission.com/assets/models/blazeface20240207/blaze_face_short_range.tflite'\nexport const defaultSelfieCaptureModelLoadTimeoutMs = 45000\n\nexport type FaceKeypoint = { x: number; y: number; name: string }\nexport type Face = {\n keypoints: FaceKeypoint[]\n box: {\n xMin: number\n xMax: number\n yMin: number\n yMax: number\n width: number\n height: number\n }\n}\n\nlet detector: FaceDetector\n\nexport async function loadFaceDetector(): Promise<FaceDetector> {\n if (detector) return detector\n\n await preloadFaceDetectorDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for face detector.')\n }\n\n detector = await FaceDetector.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: {\n modelAssetPath: defaultFaceDetectorModelPath,\n delegate: modelCapabilities.delegate,\n },\n runningMode: 'VIDEO',\n },\n )\n\n return detector\n}\n\nexport function useLoadFaceDetector({\n onModelError,\n modelLoadTimeoutMs = defaultSelfieCaptureModelLoadTimeoutMs,\n}: {\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}) {\n const detector = useRef<FaceDetector | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n const { videoRef } = useContext(CameraStateContext)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.faceDetection',\n handleDownloadProgress,\n )\n\n loadFaceDetector()\n .then(async (model) => {\n detector.current = model\n setModelDownloadProgress(100)\n clearTimeout(modelLoadTimeout)\n await waitForVideoReady(videoRef)\n model.detectForVideo(videoRef.current!, performance.now())\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.faceDetection',\n handleDownloadProgress,\n )\n }\n },\n [modelLoadTimeoutMs, videoRef],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { detector, ready, modelDownloadProgress, modelError }\n}\n\nexport function makeFaceDetectorPrediction(\n model: FaceDetector,\n imageData: Frame,\n): FaceDetectorResult & { faces: Face[] } {\n const prediction = model.detectForVideo(imageData, performance.now())\n\n const faces = prediction.detections.map<Face>((d) => ({\n box: convertBoundingBox(d.boundingBox),\n keypoints: d.keypoints.map((k) => ({\n ...k,\n x: k.x * imageData.width,\n y: k.y * imageData.height,\n name: k.label ?? '',\n })),\n }))\n\n return { ...prediction, faces }\n}\n","import { defaultDocumentDetectorModelPath } from './DocumentDetection'\nimport { defaultFocusModelPath } from './Focus'\nimport { defaultFaceDetectorModelPath } from './FaceDetection'\nimport { modelCapabilities, probeModelCapabilities } from './CapabilityProbing'\n\nexport const preloadModels = async ({\n documentDetectionModel = true,\n focusModel = true,\n faceDetectionModel = true,\n}: {\n documentDetectionModel?: string | boolean\n focusModel?: string | boolean\n faceDetectionModel?: boolean\n}): Promise<void> => {\n await probeModelCapabilities()\n\n const preloadTasks = []\n\n if (documentDetectionModel) {\n preloadTasks.push(preloadDocumentDetectorDependencies)\n }\n\n if (focusModel) {\n preloadTasks.push(preloadFocusModelDependencies)\n }\n\n if (faceDetectionModel) {\n preloadTasks.push(preloadFaceDetectorDependencies)\n }\n\n await Promise.all(preloadTasks)\n}\n\nexport type PreloadProgress = {\n loaded: number\n total: number\n}\n\nconst progressByUrl: { [url: string]: PreloadProgress } = {}\nexport const progressByUseCase: {\n visionRuntime: PreloadProgress\n documentDetection: PreloadProgress\n focus: PreloadProgress\n faceDetection: PreloadProgress\n} = {\n visionRuntime: { loaded: 0, total: 0 },\n documentDetection: { loaded: 0, total: 0 },\n focus: { loaded: 0, total: 0 },\n faceDetection: { loaded: 0, total: 0 },\n}\n\nexport async function preloadDependency(url: string) {\n const xhr = new XMLHttpRequest()\n return new Promise((resolve) => {\n xhr.addEventListener('progress', (event) => {\n if (!event.lengthComputable) return\n\n progressByUrl[url] = event\n\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress', {\n detail: { url, loaded: event.loaded, total: event.total },\n }),\n )\n })\n\n xhr.addEventListener('loadend', () => {\n resolve(xhr.readyState === 4 && xhr.status === 200)\n })\n xhr.open('GET', url, true)\n xhr.send()\n })\n}\n\nlet documentDetectorPreloading = false,\n focusModelPreloading = false,\n faceDetectorPreloading = false\n\nexport async function preloadDocumentDetectorDependencies(): Promise<void> {\n if (documentDetectorPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!documentDetectorPreloading) resolve()\n }, 100)\n })\n\n documentDetectorPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultDocumentDetectorModelPath]\n\n function handleDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.documentDetection =\n sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.documentDetection', {\n detail: progressByUseCase.documentDetection,\n }),\n )\n }\n\n document.addEventListener('idmission.preloadProgress', handleDownloadProgress)\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleDownloadProgress,\n )\n documentDetectorPreloading = false\n }\n}\n\nexport async function preloadFocusModelDependencies(): Promise<void> {\n if (focusModelPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!focusModelPreloading) resolve()\n }, 100)\n })\n\n focusModelPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultFocusModelPath]\n\n function handleModelDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.focus = sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.focus', {\n detail: progressByUseCase.focus,\n }),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n focusModelPreloading = false\n }\n}\n\nexport async function preloadFaceDetectorDependencies(): Promise<void> {\n if (faceDetectorPreloading)\n return new Promise((resolve) => {\n setInterval(() => {\n if (!faceDetectorPreloading) resolve()\n }, 100)\n })\n\n faceDetectorPreloading = true\n\n await probeModelCapabilities()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n const dependencies = [defaultFaceDetectorModelPath]\n\n function handleModelDownloadProgress(event: Event) {\n const detail = (event as CustomEvent).detail\n if (!dependencies.includes(detail.url)) return\n progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies)\n document.dispatchEvent(\n new CustomEvent('idmission.preloadProgress.faceDetection', {\n detail: progressByUseCase.faceDetection,\n }),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n\n try {\n await Promise.all(dependencies.map(preloadDependency))\n } finally {\n document.removeEventListener(\n 'idmission.preloadProgress',\n handleModelDownloadProgress,\n )\n faceDetectorPreloading = false\n }\n}\n\nexport function progressToPercentage(progress: PreloadProgress) {\n return progress.total > 0\n ? Math.round((100.0 * progress.loaded) / progress.total)\n : 0\n}\n\nexport function sumUpProgressForDependencies(\n dependencies: string[],\n): PreloadProgress {\n return dependencies.reduce(\n (result, dependency) => {\n const dependencyProgress = progressByUrl[dependency]\n if (!dependencyProgress) return result\n result.loaded += dependencyProgress.loaded\n result.total += dependencyProgress.total\n return result\n },\n { loaded: 0, total: 0 },\n )\n}\n","import {\n FilesetResolver,\n ObjectDetector,\n ObjectDetectorResult,\n} from '@mediapipe/tasks-vision'\nimport {\n preloadDocumentDetectorDependencies,\n progressToPercentage,\n} from './preloadModels'\nimport { modelCapabilities } from './CapabilityProbing'\nimport { visionTasksBasePath } from './VisionRuntime'\nimport { error as logError } from '../utils/logger'\nimport { convertBoundingBox, waitForVideoReady } from './helpers'\nimport { useContext, useEffect, useRef, useState } from 'react'\nimport { CameraStateContext } from '../../components/camera/CameraProvider'\n\nexport const defaultDocumentDetectorModelPath = `https://websdk-cdn-dev.idmission.com/assets/models/docdetectmp20240611/model_fp16.tflite`\nexport const defaultDocumentDetectionScoreThreshold = 0.1\nexport const defaultDocumentDetectionModelLoadTimeoutMs = 45000\nexport const defaultDocumentDetectionThresholds: DocumentDetectionThresholds = {\n idCard: 0.8,\n passport: 0.5,\n mrz: 0.5,\n pdf417: 0.15,\n}\n\nexport type DocumentType = 'none' | 'idCard' | 'passport'\n\nexport type Label =\n | 'Document'\n | 'MRZ'\n | 'PDF417'\n | 'Primary face'\n | 'Secondary face'\n | 'Glare'\n | 'Punch Hole'\n | 'Passport page'\n\nexport type DetectedObjectBox = {\n xMin: number\n xMax: number\n yMin: number\n yMax: number\n width: number\n height: number\n}\n\nexport type DetectedObject = {\n box: DetectedObjectBox\n label: Label\n score: number\n}\n\nexport type DocumentDetectionThresholds = {\n idCard?: number\n passport?: number\n mrz?: number\n pdf417?: number\n}\n\nconst detectors: { [id: string]: ObjectDetector } = {}\n\nexport async function loadDocumentDetector(\n modelAssetPath = defaultDocumentDetectorModelPath,\n scoreThreshold = defaultDocumentDetectionScoreThreshold,\n): Promise<ObjectDetector> {\n const id = `${modelAssetPath}:${scoreThreshold}`\n if (detectors[id]) return detectors[id]\n\n await preloadDocumentDetectorDependencies()\n if (modelCapabilities.delegate === 'NONE') {\n throw new Error('No available delegate for document detector.')\n }\n\n detectors[id] = await ObjectDetector.createFromOptions(\n await FilesetResolver.forVisionTasks(visionTasksBasePath),\n {\n baseOptions: { modelAssetPath, delegate: modelCapabilities.delegate },\n scoreThreshold,\n runningMode: 'VIDEO',\n },\n )\n\n return detectors[id]\n}\n\nexport function useLoadDocumentDetector({\n modelPath = defaultDocumentDetectorModelPath,\n modelLoadTimeoutMs = defaultDocumentDetectionModelLoadTimeoutMs,\n scoreThreshold = defaultDocumentDetectionScoreThreshold,\n onModelError,\n}: {\n modelPath?: string\n modelLoadTimeoutMs?: number\n scoreThreshold?: number\n onModelError?: (error: Error) => void\n}) {\n const detector = useRef<ObjectDetector | null>(null)\n const [ready, setReady] = useState(false)\n const [modelDownloadProgress, setModelDownloadProgress] = useState(0)\n const [modelError, setModelError] = useState<Error | null>(null)\n const { videoRef } = useContext(CameraStateContext)\n\n useEffect(\n function loadModel() {\n setReady(false)\n\n function handleDownloadProgress(event: Event) {\n setModelDownloadProgress(\n progressToPercentage((event as CustomEvent).detail),\n )\n }\n\n document.addEventListener(\n 'idmission.preloadProgress.documentDetection',\n handleDownloadProgress,\n )\n\n const modelLoadTimeout = setTimeout(() => {\n setModelError(new Error('Model loading time limit exceeded.'))\n }, modelLoadTimeoutMs)\n\n loadDocumentDetector(modelPath, scoreThreshold)\n .then(async (model) => {\n detector.current = model\n setModelDownloadProgress(100)\n clearTimeout(modelLoadTimeout)\n await waitForVideoReady(videoRef)\n model.detectForVideo(videoRef.current!, performance.now())\n setReady(true)\n })\n .catch((e) => {\n setModelError(e as Error)\n })\n .finally(() => {\n clearTimeout(modelLoadTimeout)\n })\n\n return () => {\n clearTimeout(modelLoadTimeout)\n document.removeEventListener(\n 'idmission.preloadProgress.documentDetection',\n handleDownloadProgress,\n )\n }\n },\n [modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef],\n )\n\n useEffect(\n function handleModelError() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n return { detector, ready, modelDownloadProgress, modelError, setModelError }\n}\n\nexport type DocumentDetectionPrediction = {\n detectedObjects: DetectedObject[]\n detectionTime: number\n detectionScore: number\n detectionThresholdMet: boolean\n detectedDocumentType: DocumentType\n\n passportDetectionScore: number\n passportDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentInBounds: boolean\n documentTooClose: boolean\n\n frameWidth: number\n frameHeight: number\n\n allZero: boolean\n frameId?: number\n}\n\nexport type ObjectDetectorPrediction = ObjectDetectorResult & {\n time: number\n frameWidth: number\n frameHeight: number\n}\n\nexport async function makeDocumentDetectorPrediction(\n detector: ObjectDetector,\n frame: HTMLCanvasElement,\n): Promise<ObjectDetectorPrediction | null> {\n const startedAt = new Date()\n let prediction: ObjectDetectorResult | null\n\n // Detectors can throw errors, for example when using custom URLs that\n // contain a model that doesn't provide the expected output.\n try {\n prediction = detector.detectForVideo(frame, performance.now())\n const time = new Date().getTime() - startedAt.getTime()\n const frameWidth = frame.width\n const frameHeight = frame.height\n return { ...prediction, time, frameWidth, frameHeight }\n } catch (e) {\n logError('caught object detection error', e)\n }\n\n return null\n}\n\nexport function processDocumentDetectorPrediction(\n prediction: ObjectDetectorPrediction,\n thresholds: DocumentDetectionThresholds,\n): DocumentDetectionPrediction {\n const { detections, frameWidth, frameHeight, time } = prediction\n const detectedObjects = applyNonMaxSuppression(\n detections.map<DetectedObject>((d) => {\n const category = d.categories?.[0]\n\n return {\n label: category?.categoryName as Label,\n score: category?.score,\n box: convertBoundingBox(d.boundingBox),\n }\n }),\n )\n\n const allZero =\n detections.length > 0 &&\n !detections.some(({ boundingBox }) =>\n Object.values(boundingBox ?? {}).some((n) => n > 0),\n )\n\n const bestIdCard = detectedObjects.find((obj) => obj.label === 'Document')\n const bestPassportPage = detectedObjects.find(\n (obj) => obj.label === 'Passport page',\n )\n const passportDetectionScore = bestPassportPage?.score ?? 0\n const passportDetectionThresholdMet =\n passportDetectionScore >= (thresholds.passport ?? 0)\n const bestDocument = passportDetectionThresholdMet\n ? bestPassportPage\n : bestIdCard\n const detectionScore = bestDocument?.score ?? 0\n const detectionThreshold = passportDetectionThresholdMet\n ? thresholds.passport\n : thresholds.idCard\n const detectionThresholdMet = detectionScore >= (detectionThreshold ?? 0)\n\n let detectedDocumentType: DocumentType = 'none'\n if (passportDetectionThresholdMet) {\n detectedDocumentType = 'passport'\n } else if (detectionThresholdMet) {\n detectedDocumentType = 'idCard'\n }\n\n const bestMrz = detectedObjects.find((obj) => obj.label === 'MRZ')\n const mrzDetectionScore = bestMrz?.score ?? 0\n const mrzDetectionThresholdMet = mrzDetectionScore >= (thresholds.mrz ?? 0)\n\n const bestPdf417 = detectedObjects.find((obj) => obj.label === 'PDF417')\n const pdf417DetectionScore = bestPdf417?.score ?? 0\n const pdf417DetectionThresholdMet =\n pdf417DetectionScore >= (thresholds.pdf417 ?? 0)\n\n let documentInBounds = false\n if (bestDocument) {\n const boundaryPx = 20\n const {\n xMin: boundaryX,\n yMin: boundaryY,\n width: boundaryWidth,\n height: boundaryHeight,\n } = bestDocument.box\n\n documentInBounds =\n boundaryY > boundaryPx && // Is it valid top edge of ID detected?\n boundaryY + boundaryHeight + boundaryPx < frameHeight && // Is it valid bottom edge less than max video height\n (boundaryX > boundaryPx ||\n (boundaryX < boundaryPx &&\n boundaryX + boundaryWidth > frameWidth * 0.8)) && // If either the left side visible or if not, right edge of ID should be more than 80% of width.\n boundaryX + boundaryWidth + boundaryPx < frameWidth // Valid right edge if it's less than video width.\n }\n\n let documentTooClose = false\n if (bestDocument) {\n const [docWidth, docHeight] = [\n bestDocument.box.width / frameWidth,\n bestDocument.box.height / frameHeight,\n ]\n documentTooClose = docWidth > 0.85 || docHeight > 0.85\n }\n\n return {\n detectedObjects,\n detectionScore,\n detectionTime: time,\n detectionThresholdMet,\n detectedDocumentType,\n passportDetectionScore,\n passportDetectionThresholdMet,\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n bestDocument,\n bestMrz,\n bestPdf417,\n documentInBounds,\n documentTooClose,\n frameWidth,\n frameHeight,\n allZero,\n }\n}\n\nfunction applyNonMaxSuppression(\n detectedObjects: DetectedObject[],\n): DetectedObject[] {\n const maxes: { [label: string]: [number, number] } = {}\n detectedObjects.forEach((obj, i) => {\n if (obj) {\n if (!maxes[obj.label]) maxes[obj.label] = [0, -1]\n if (obj.score > maxes[obj.label][0]) maxes[obj.label] = [obj.score, i]\n }\n })\n return Object.keys(maxes)\n .map((label) => detectedObjects[maxes[label][1]])\n .filter((obj) => !!obj)\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nexport function useFrameLoop(\n fn: (frameId: number) => Promise<void>,\n { throttleMs = 0, autoStart = false },\n) {\n const [running, setRunning] = useState(false)\n const loopId = useRef(0)\n const frameId = useRef(0)\n\n useEffect(\n function runFrameLoop() {\n if (!running) return\n\n let timer: NodeJS.Timeout\n const currentLoopId = loopId.current\n\n async function renderPrediction() {\n if (currentLoopId !== loopId.current) return\n await fn(frameId.current)\n timer = setTimeout(() => {\n frameId.current = requestAnimationFrame(renderPrediction)\n }, throttleMs ?? 0)\n }\n\n renderPrediction().then()\n\n return () => {\n loopId.current += 1\n frameId.current && cancelAnimationFrame(frameId.current)\n timer && clearTimeout(timer)\n }\n },\n [fn, running, throttleMs],\n )\n\n const start = useCallback(() => {\n setRunning(true)\n }, [])\n\n const stop = useCallback(() => {\n loopId.current += 1 // force the loop to stop immediately.\n setRunning(false)\n }, [])\n\n useEffect(\n function startAutomatically() {\n if (autoStart) start()\n return () => {\n stop()\n }\n },\n [autoStart, start, stop],\n )\n\n return { start, stop }\n}\n","import * as React from 'react'\nimport {\n createContext,\n MutableRefObject,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { log } from '../../lib/utils/logger'\nimport {\n defaultDocumentDetectionModelLoadTimeoutMs,\n defaultDocumentDetectionScoreThreshold,\n defaultDocumentDetectorModelPath,\n DocumentDetectionPrediction,\n DocumentDetectionThresholds,\n makeDocumentDetectorPrediction,\n processDocumentDetectorPrediction,\n useLoadDocumentDetector,\n} from '../../lib/models/DocumentDetection'\nimport { useFrameLoop } from '../../lib/models/FrameLoop'\n\ntype PredictionHandler = (\n prediction: DocumentDetectionPrediction,\n) => Promise<void>\n\ntype DocumentDetectionModelState = {\n startDocumentDetection: () => void\n stopDocumentDetection: () => void\n\n documentDetectionModelReady: boolean\n documentDetectionModelDownloadProgress: number\n documentDetectionModelError: Error | null\n\n onDocumentDetected: (handler: PredictionHandler) => void\n detectionTime: number\n\n documentDetectionThresholds: DocumentDetectionThresholds\n setDocumentDetectionThresholds: (value: DocumentDetectionThresholds) => void\n\n documentDetectionLastPredictionCanvas: MutableRefObject<HTMLCanvasElement | null>\n clearDocumentDetectionLastPredictionCanvas: () => void\n}\n\nexport const DocumentDetectionModelContext =\n createContext<DocumentDetectionModelState>({\n startDocumentDetection: () => null,\n stopDocumentDetection: () => null,\n\n documentDetectionModelReady: false,\n documentDetectionModelDownloadProgress: 0,\n documentDetectionModelError: null,\n\n onDocumentDetected: () => null,\n detectionTime: 0,\n\n documentDetectionThresholds: {},\n setDocumentDetectionThresholds: () => null,\n\n documentDetectionLastPredictionCanvas: { current: null },\n clearDocumentDetectionLastPredictionCanvas: () => null,\n })\n\nexport type DocumentDetectionModelProviderProps = {\n autoStart?: boolean\n children: ReactNode\n throttleMs?: number\n documentDetectionModelPath?: string\n documentDetectionModelScoreThreshold?: number\n documentDetectionModelLoadTimeoutMs?: number\n onDocumentDetectionModelError?: (error: Error) => void\n}\n\nexport function DocumentDetectionModelProvider({\n autoStart = true,\n children,\n throttleMs,\n documentDetectionModelPath = defaultDocumentDetectorModelPath,\n documentDetectionModelScoreThreshold = defaultDocumentDetectionScoreThreshold,\n documentDetectionModelLoadTimeoutMs = defaultDocumentDetectionModelLoadTimeoutMs,\n onDocumentDetectionModelError,\n}: DocumentDetectionModelProviderProps): ReactElement {\n const { videoRef, videoLoaded, cameraReady } = useContext(CameraStateContext)\n const lastPredictionCanvas = useRef<HTMLCanvasElement>(null)\n const onPredictionHandler = useRef<PredictionHandler>()\n const [documentDetectionThresholds, setDocumentDetectionThresholds] =\n useState<DocumentDetectionThresholds>({})\n const [detectionTime, setDetectionTime] = useState<number>(0)\n const [timesAllZero, setTimesAllZero] = useState(0)\n const [canvasKey, setCanvasKey] = useState(0)\n const stopDetection = useRef(0)\n\n const { detector, ready, modelDownloadProgress, modelError, setModelError } =\n useLoadDocumentDetector({\n modelPath: documentDetectionModelPath,\n modelLoadTimeoutMs: documentDetectionModelLoadTimeoutMs,\n scoreThreshold: documentDetectionModelScoreThreshold,\n onModelError: onDocumentDetectionModelError,\n })\n\n const { start, stop } = useFrameLoop(\n useCallback(\n async (frameId: number) => {\n if (\n !videoLoaded ||\n !cameraReady ||\n !ready ||\n !videoRef.current ||\n !detector.current ||\n !lastPredictionCanvas.current\n )\n return\n\n const stopDetectionAtStart = stopDetection.current\n const vw = videoRef.current.videoWidth\n const vh = videoRef.current.videoHeight\n lastPredictionCanvas.current.width = vw\n lastPredictionCanvas.current.height = vh\n\n const ctx = lastPredictionCanvas.current.getContext('2d')\n if (ctx && videoRef.current.readyState === 4) {\n if (stopDetectionAtStart !== stopDetection.current) return\n ctx.drawImage(videoRef.current, 0, 0, vw, vh)\n\n const prediction = await makeDocumentDetectorPrediction(\n detector.current,\n lastPredictionCanvas.current,\n )\n if (prediction) {\n const processedPrediction = processDocumentDetectorPrediction(\n prediction,\n documentDetectionThresholds,\n )\n processedPrediction.frameId = frameId\n setDetectionTime(prediction.time)\n log(processedPrediction)\n if (processedPrediction.allZero) setTimesAllZero((n) => n + 1)\n if (stopDetectionAtStart !== stopDetection.current) return\n await onPredictionHandler.current?.(processedPrediction)\n }\n }\n },\n [\n cameraReady,\n detector,\n documentDetectionThresholds,\n ready,\n videoLoaded,\n videoRef,\n ],\n ),\n { throttleMs, autoStart },\n )\n\n useEffect(\n function setErrorIfAllZero() {\n if (timesAllZero >= 2) {\n setModelError(new Error('model is returning all zeroes'))\n }\n },\n [setModelError, timesAllZero],\n )\n\n const onDocumentDetected = useCallback((handler: PredictionHandler) => {\n onPredictionHandler.current = handler\n }, [])\n\n const clearDocumentDetectionLastPredictionCanvas = useCallback(() => {\n stopDetection.current += 1\n setCanvasKey((n) => n + 1)\n }, [])\n\n const value = useMemo<DocumentDetectionModelState>(\n () => ({\n startDocumentDetection: start,\n stopDocumentDetection: stop,\n documentDetectionModelReady: ready,\n documentDetectionModelError: modelError,\n documentDetectionModelDownloadProgress: modelDownloadProgress,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n setDocumentDetectionThresholds,\n documentDetectionLastPredictionCanvas: lastPredictionCanvas,\n clearDocumentDetectionLastPredictionCanvas,\n }),\n [\n start,\n stop,\n ready,\n modelError,\n modelDownloadProgress,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n clearDocumentDetectionLastPredictionCanvas,\n ],\n )\n\n return (\n <DocumentDetectionModelContext.Provider value={value}>\n <InvisibleCanvas key={canvasKey} ref={lastPredictionCanvas} />\n {children}\n </DocumentDetectionModelContext.Provider>\n )\n}\n","import React, {\n createContext,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n DetectedObject,\n DetectedObjectBox,\n DocumentDetectionThresholds,\n DocumentType,\n} from '../../lib/models/DocumentDetection'\nimport { drawToCanvas, InvisibleCanvas } from '../common/InvisibleCanvas'\nimport {\n DocumentDetectionModelContext,\n DocumentDetectionModelProvider,\n DocumentDetectionModelProviderProps,\n} from './DocumentDetectionModelProvider'\nimport {\n FocusModelContext,\n FocusModelProvider,\n FocusModelProviderProps,\n} from './FocusModelProvider'\nimport { isMobile } from '../../lib/utils/isMobile'\nimport { FocusThresholds } from '../../lib/models/Focus'\n\nconst onMobile = isMobile()\n\nexport type IdCapturePrediction = {\n detectedObjects: DetectedObject[]\n detectionTime: number\n detectionScore: number\n detectionThresholdMet: boolean\n detectedDocumentType: DocumentType\n\n passportDetectionScore: number\n passportDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentInBounds: boolean\n documentTooClose: boolean\n\n focusScore: number\n focusThresholdMet: boolean\n focusPredictionTime: number\n\n frameWidth: number\n frameHeight: number\n\n allZero: boolean\n}\n\nexport type IdCaptureThresholds = DocumentDetectionThresholds & {\n focus?: FocusThresholds\n}\n\nexport type BestFrameDetails = {\n boundingBox?: DetectedObjectBox\n documentType: DocumentType\n detectionScore: number\n focusScore: number\n}\n\nexport type BestFrame = BestFrameDetails & {\n canvas: HTMLCanvasElement\n}\n\nexport type IdCaptureModelsState = {\n ready: boolean\n start: () => void\n stop: () => void\n\n modelDownloadProgress: number\n modelError: Error | null\n\n thresholds: IdCaptureThresholds\n setThresholds: (value: IdCaptureThresholds) => void\n\n onPredictionMade: (handler: (prediction: IdCapturePrediction) => void) => void\n\n detectionTime: number\n focusPredictionTime: number\n\n bestFrameDetails: BestFrameDetails | null\n getBestFrame: () => BestFrame | null\n resetBestFrame: () => void\n}\n\nexport const IdCaptureModelsContext = createContext<IdCaptureModelsState>({\n ready: false,\n start: () => null,\n stop: () => null,\n\n modelDownloadProgress: 0,\n modelError: null,\n\n thresholds: {},\n setThresholds: () => null,\n\n onPredictionMade: () => null,\n\n detectionTime: 0,\n focusPredictionTime: 0,\n\n bestFrameDetails: null,\n getBestFrame: () => null,\n resetBestFrame: () => null,\n})\n\nexport type IdCaptureModelsProviderProps = {\n children: ReactNode\n documentDetectionModelUrl?: string | undefined\n focusModelUrl?: string | undefined\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}\n\nexport function IdCaptureModelsProviderInner({\n children,\n onModelError,\n}: IdCaptureModelsProviderProps): ReactElement {\n const {\n documentDetectionModelReady,\n documentDetectionModelDownloadProgress,\n startDocumentDetection,\n stopDocumentDetection,\n documentDetectionLastPredictionCanvas: lastPredictionCanvas,\n clearDocumentDetectionLastPredictionCanvas,\n onDocumentDetected,\n detectionTime,\n documentDetectionThresholds,\n setDocumentDetectionThresholds,\n documentDetectionModelError,\n } = useContext(DocumentDetectionModelContext)\n const {\n focusModelReady,\n focusModelDownloadProgress,\n makeFocusPrediction,\n focusThresholds,\n setFocusThresholds,\n focusPredictionTime,\n focusModelError,\n } = useContext(FocusModelContext)\n const onPredictionHandler =\n useRef<(prediction: IdCapturePrediction) => void>()\n const [bestFrameDetails, setBestFrameDetails] =\n useState<BestFrameDetails | null>(null)\n const bestPredictionCanvas = useRef<HTMLCanvasElement | null>(null)\n const bestFocusScore = useRef<number>(0)\n const stopDetection = useRef(0)\n\n const thresholds = useMemo(\n () => ({ ...documentDetectionThresholds, focus: focusThresholds }),\n [documentDetectionThresholds, focusThresholds],\n )\n const setThresholds = useCallback(\n (thresholds: IdCaptureThresholds) => {\n setDocumentDetectionThresholds(thresholds)\n if (thresholds.focus) setFocusThresholds(thresholds.focus)\n },\n [setDocumentDetectionThresholds, setFocusThresholds],\n )\n\n useEffect(\n function handleDetections() {\n onDocumentDetected(async (prediction) => {\n if (!lastPredictionCanvas.current) return\n\n const stopDetectionAtStart = stopDetection.current\n let focusPredictionTime = 0,\n focusScore = 0,\n focusThresholdMet = false\n\n if (\n prediction.detectedDocumentType !== 'none' &&\n prediction.detectionThresholdMet &&\n prediction.documentInBounds &&\n !prediction.documentTooClose\n ) {\n const focusPrediction = makeFocusPrediction(\n lastPredictionCanvas.current,\n prediction.bestDocument?.box,\n )\n if (focusPrediction) {\n focusScore = focusPrediction.score\n focusPredictionTime = focusPrediction.predictionTime\n }\n\n const focusThresholdSet =\n thresholds.focus?.[prediction.detectedDocumentType]\n const focusThreshold =\n (onMobile\n ? focusThresholdSet?.mobile\n : focusThresholdSet?.desktop) ?? 0\n focusThresholdMet = focusScore >= focusThreshold\n\n if (\n bestFocusScore.current <= focusScore &&\n stopDetectionAtStart === stopDetection.current\n ) {\n bestFocusScore.current = focusScore\n drawToCanvas(\n bestPredictionCanvas.current,\n lastPredictionCanvas.current,\n )\n setBestFrameDetails({\n boundingBox: prediction.bestDocument?.box,\n documentType: prediction.detectedDocumentType,\n detectionScore: prediction.detectionScore,\n focusScore,\n })\n }\n }\n\n onPredictionHandler.current?.({\n ...prediction,\n focusScore,\n focusPredictionTime,\n focusThresholdMet,\n })\n })\n },\n [\n lastPredictionCanvas,\n makeFocusPrediction,\n onDocumentDetected,\n thresholds.focus,\n ],\n )\n\n const modelError = documentDetectionModelError ?? focusModelError\n useEffect(\n function handleModelErrors() {\n modelError && onModelError?.(modelError)\n },\n [modelError, onModelError],\n )\n\n const onPredictionMade = useCallback(\n (handler: (prediction: IdCapturePrediction) => void) => {\n onPredictionHandler.current = handler\n },\n [],\n )\n\n const getBestFrame = useCallback((): BestFrame | null => {\n if (!bestFrameDetails || !bestPredictionCanvas.current) return null\n return { ...bestFrameDetails, canvas: bestPredictionCanvas.current }\n }, [bestFrameDetails])\n\n const [canvasKey, setCanvasKey] = useState(0)\n const resetBestFrame = useCallback(() => {\n stopDetection.current += 1\n setCanvasKey((n) => n + 1)\n clearDocumentDetectionLastPredictionCanvas()\n setBestFrameDetails(null)\n bestFocusScore.current = 0\n }, [clearDocumentDetectionLastPredictionCanvas])\n\n const value = useMemo<IdCaptureModelsState>(\n () => ({\n ready: documentDetectionModelReady && focusModelReady,\n modelDownloadProgress:\n (documentDetectionModelDownloadProgress + focusModelDownloadProgress) /\n 2,\n modelError,\n start: startDocumentDetection,\n stop: stopDocumentDetection,\n thresholds,\n setThresholds,\n onPredictionMade,\n detectionTime,\n focusPredictionTime,\n getBestFrame,\n resetBestFrame,\n bestFrameDetails,\n }),\n [\n bestFrameDetails,\n detectionTime,\n documentDetectionModelDownloadProgress,\n documentDetectionModelReady,\n focusModelDownloadProgress,\n focusModelReady,\n focusPredictionTime,\n getBestFrame,\n modelError,\n onPredictionMade,\n resetBestFrame,\n setThresholds,\n startDocumentDetection,\n stopDocumentDetection,\n thresholds,\n ],\n )\n\n return (\n <IdCaptureModelsContext.Provider value={value}>\n <InvisibleCanvas key={canvasKey} ref={bestPredictionCanvas} />\n {children}\n </IdCaptureModelsContext.Provider>\n )\n}\n\nexport function IdCaptureModelsProvider({\n children,\n ...props\n}: IdCaptureModelsProviderProps &\n DocumentDetectionModelProviderProps &\n FocusModelProviderProps) {\n return (\n <DocumentDetectionModelProvider {...props}>\n <FocusModelProvider {...props}>\n <IdCaptureModelsProviderInner {...props}>\n {children}\n </IdCaptureModelsProviderInner>\n </FocusModelProvider>\n </DocumentDetectionModelProvider>\n )\n}\n","import { DetectedObjectBox } from '../../lib/models/DocumentDetection'\n\nexport const CapturedDocumentTypeValues = [\n 'idCardFront',\n 'idCardBack',\n 'passport',\n 'selfie',\n] as const\n\nexport type CapturedDocumentType = (typeof CapturedDocumentTypeValues)[number]\n\nexport type CapturedDocument = {\n imageData: string\n width: number\n height: number\n boundingBox?: DetectedObjectBox\n documentType: CapturedDocumentType\n}\n\nexport type CapturedDocuments = {\n [k in CapturedDocumentType]?: CapturedDocument\n}\n","import { CapturedDocumentType } from './CapturedDocuments'\n\nexport type IdCaptureRequirementOption =\n | 'idCardFront'\n | 'idCardBack'\n | 'passport'\n | 'idCard'\n | 'idCardOrPassport'\n | 'idCardAndPassport'\n\nexport const requiredDocumentsForOption: {\n [key in IdCaptureRequirementOption]: Array<CapturedDocumentType>\n} = {\n idCardFront: ['idCardFront'],\n idCardBack: ['idCardBack'],\n passport: ['passport'],\n idCard: ['idCardFront', 'idCardBack'],\n idCardAndPassport: ['idCardFront', 'idCardBack', 'passport'],\n idCardOrPassport: ['idCardFront', 'idCardBack', 'passport'], // this one is so weird\n}\n\nexport function requiredImageCountForOption(\n idCaptureRequirement: IdCaptureRequirementOption,\n) {\n if (idCaptureRequirement === 'idCardOrPassport') return 1\n return requiredDocumentsForOption[idCaptureRequirement].length\n}\n\nexport function allowedImageCountForOption(\n idCaptureRequirement: IdCaptureRequirementOption,\n) {\n if (idCaptureRequirement === 'idCardOrPassport') return 2\n return requiredImageCountForOption(idCaptureRequirement)\n}\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useContext,\n useLayoutEffect,\n useReducer,\n} from 'react'\nimport { useDebouncedCallback } from 'use-debounce'\nimport {\n CapturedDocument,\n CapturedDocuments,\n CapturedDocumentType,\n CapturedDocumentTypeValues,\n} from './CapturedDocuments'\nimport { IdCapturePrediction } from './IdCaptureModelsProvider'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport {\n DetectedObject,\n DocumentType,\n} from '../../lib/models/DocumentDetection'\nimport {\n IdCaptureRequirementOption,\n requiredDocumentsForOption,\n} from './IdCaptureRequirementOption'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type CaptureState = 'capturing' | 'complete' | 'requestingFlip'\n\nexport type IdCaptureState = {\n initialDrawComplete: boolean\n redrawing: boolean\n\n guideRectX: number\n guideRectY: number\n guideRectWidth: number\n guideRectHeight: number\n guideRectOffsetTop: number\n guideImageWidth: number\n guideImageHeight: number\n\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n\n detectedObjects: DetectedObject[]\n bestDocument: DetectedObject | undefined\n bestMrz: DetectedObject | undefined\n bestPdf417: DetectedObject | undefined\n\n documentType: DocumentType\n requiredDocumentType?: CapturedDocumentType\n documentInBounds: boolean\n documentTooClose: boolean\n documentDetectionScore: number\n documentDetectionThresholdMet: boolean\n\n mrzDetectionScore: number\n mrzDetectionThresholdMet: boolean\n\n passportPageDetectionScore: number\n passportPageDetectionThresholdMet: boolean\n\n focusScore: number\n focusThresholdMet: boolean\n\n pdf417DetectionScore: number\n pdf417DetectionThresholdMet: boolean\n\n barcodeScanningEnabled: boolean\n barcodeResult: PDF417DetectionResult | null\n waitingForBarcodeScan: boolean\n shouldScanBarcode: boolean\n autoCaptureBarcodeRequired: boolean | 'mobile'\n barcodeScanFailedAttempts: number\n maxBarcodeScanAttempts: number\n\n isGoodFrame: boolean\n goodFramesCount: number\n goodFramesThreshold: number\n goodFramesThresholdMet: boolean\n\n lastFrameCapturedAt: Date | null\n frameCaptureRate: number\n\n capturing: boolean\n captureFailed: boolean\n\n imageUrl: string | null\n\n captureState: CaptureState\n capturedDocuments: CapturedDocuments\n captureRequirement: IdCaptureRequirementOption\n requestedDocumentType: CapturedDocumentType\n detectedDocumentType: DocumentType\n differentDocumentTypeDetections: number\n\n operationStartedAt: Date | null\n captureStartedAt: Date | null\n}\n\nconst initialState = {\n initialDrawComplete: false,\n redrawing: false,\n\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n guideImageWidth: 0,\n guideImageHeight: 0,\n\n pageWidth: 0,\n pageHeight: 0,\n videoWidth: 0,\n videoHeight: 0,\n\n detectedObjects: [],\n bestDocument: undefined,\n bestMrz: undefined,\n bestPdf417: undefined,\n\n documentType: 'none',\n documentInBounds: false,\n documentTooClose: false,\n\n documentDetectionScore: 0,\n documentDetectionThresholdMet: false,\n passportPageDetectionScore: 0,\n passportPageDetectionThresholdMet: false,\n mrzDetectionScore: 0,\n mrzDetectionThresholdMet: false,\n pdf417DetectionScore: 0,\n pdf417DetectionThresholdMet: false,\n focusScore: 0,\n focusThresholdMet: false,\n\n barcodeScanningEnabled: false,\n barcodeResult: null,\n waitingForBarcodeScan: false,\n shouldScanBarcode: false,\n autoCaptureBarcodeRequired: 'mobile',\n barcodeScanFailedAttempts: 0,\n maxBarcodeScanAttempts: 10,\n\n isGoodFrame: false,\n goodFramesCount: 0,\n goodFramesThreshold: 3,\n goodFramesThresholdMet: false,\n\n lastFrameCapturedAt: null,\n frameCaptureRate: 0,\n\n capturing: false,\n captureFailed: false,\n\n imageUrl: null,\n\n captureState: 'capturing',\n capturedDocuments: {},\n captureRequirement: 'idCardOrPassport',\n requestedDocumentType: 'idCardFront',\n detectedDocumentType: 'none',\n differentDocumentTypeDetections: 0,\n\n operationStartedAt: null,\n captureStartedAt: null,\n} satisfies IdCaptureState\n\nexport type IdCaptureAction =\n | {\n type: 'configureWizard'\n payload: {\n captureRequirement: IdCaptureRequirementOption\n precapturedDocuments?: CapturedDocuments\n }\n }\n | {\n type: 'configureCapture'\n payload: {\n autoCaptureBarcodeRequired: boolean | 'mobile'\n barcodeScanningEnabled: boolean\n maxBarcodeScanAttempts: number\n }\n }\n | { type: 'setRequiredDocumentType'; payload: CapturedDocumentType }\n | { type: 'redrawRequested' }\n | { type: 'redrawInProgress' }\n | {\n type: 'redrawCompleted'\n payload: {\n guideRectX: number\n guideRectY: number\n guideRectWidth: number\n guideRectHeight: number\n guideRectOffsetTop: number\n }\n }\n | { type: 'pageRendered'; payload: { pageWidth: number; pageHeight: number } }\n | { type: 'guideImageLoaded'; payload: { width: number; height: number } }\n | { type: 'captureStarted' }\n | { type: 'capturing' }\n | { type: 'captured' }\n | { type: 'captureFailed' }\n | { type: 'frameCaptured'; payload: { imageUrl: string } }\n | {\n type: 'objectsDetected'\n payload: { prediction: IdCapturePrediction }\n }\n | {\n type: 'barcodeScanned'\n payload: { result: PDF417DetectionResult }\n }\n | { type: 'barcodeScanFailed' }\n | { type: 'predictionMade'; payload: IdCapturePrediction }\n | { type: 'documentCaptured'; payload: CapturedDocument }\n | { type: 'documentCapturedManually'; payload: { imageData: string } }\n | { type: 'flipRequestCompleted' }\n | { type: 'resetWizard' }\n\nexport type IdCaptureDispatch = Dispatch<IdCaptureAction>\n\nexport const IdCaptureStateContext = createContext<IdCaptureState>(initialState)\nexport const IdCaptureDispatchContext = createContext<IdCaptureDispatch>(\n () => {},\n)\n\nconst reducer = (\n state: IdCaptureState,\n action: IdCaptureAction,\n): IdCaptureState => {\n switch (action.type) {\n case 'configureWizard': {\n const { captureRequirement, precapturedDocuments } = action.payload\n let newState = { ...state, captureRequirement }\n\n if (captureRequirement === 'idCardBack')\n newState.requestedDocumentType = 'idCardBack'\n if (captureRequirement === 'passport')\n newState.requestedDocumentType = 'passport'\n\n if (precapturedDocuments) {\n for (const k of CapturedDocumentTypeValues) {\n const payload = precapturedDocuments[k]\n if (payload) {\n newState.requestedDocumentType = k\n newState = reducer(newState, { type: 'documentCaptured', payload })\n }\n }\n }\n\n newState.operationStartedAt = new Date()\n\n return newState\n }\n\n case 'configureCapture':\n return {\n ...state,\n ...action.payload,\n capturing: false,\n captureFailed: false,\n }\n\n case 'setRequiredDocumentType':\n return { ...state, requiredDocumentType: action.payload }\n\n case 'redrawRequested':\n return {\n ...state,\n redrawing: true,\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n }\n\n case 'redrawInProgress':\n return {\n ...state,\n redrawing: false,\n guideRectX: 0,\n guideRectY: 0,\n guideRectWidth: 0,\n guideRectHeight: 0,\n guideRectOffsetTop: 0,\n }\n\n case 'redrawCompleted':\n return { ...state, ...action.payload, initialDrawComplete: true }\n\n case 'pageRendered':\n return { ...state, ...action.payload }\n\n case 'guideImageLoaded':\n return {\n ...state,\n guideImageWidth: action.payload.width,\n guideImageHeight: action.payload.height,\n }\n\n case 'objectsDetected':\n const {\n prediction: {\n detectedObjects,\n detectionScore,\n detectionThresholdMet,\n detectedDocumentType,\n passportDetectionScore,\n passportDetectionThresholdMet,\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n bestDocument,\n bestMrz,\n bestPdf417,\n documentInBounds,\n documentTooClose,\n focusScore,\n focusThresholdMet,\n frameWidth,\n frameHeight,\n },\n } = action.payload\n\n const frameCapturedAt = new Date()\n let frameCaptureRate = 0\n let goodFramesThreshold = state.goodFramesThreshold\n if (state.lastFrameCapturedAt) {\n frameCaptureRate =\n 1000.0 /\n (frameCapturedAt.getTime() - state.lastFrameCapturedAt.getTime())\n\n if (frameCaptureRate > 0) {\n goodFramesThreshold = Math.ceil(3 * frameCaptureRate)\n }\n }\n\n const barcodeScanRequired =\n state.autoCaptureBarcodeRequired === true ||\n (state.autoCaptureBarcodeRequired === 'mobile' && isMobile())\n const shouldScanBarcode =\n state.barcodeScanningEnabled &&\n pdf417DetectionThresholdMet &&\n barcodeScanRequired\n const waitingForBarcodeScan = shouldScanBarcode && !state.barcodeResult\n\n const isGoodFrame =\n detectionThresholdMet &&\n documentInBounds &&\n !documentTooClose &&\n focusThresholdMet\n\n let goodFramesCount = state.goodFramesCount\n if (isGoodFrame) {\n goodFramesCount += 1\n }\n\n return {\n ...state,\n\n videoWidth: frameWidth,\n videoHeight: frameHeight,\n\n detectedObjects,\n bestDocument: bestDocument,\n bestMrz,\n bestPdf417,\n\n documentType: detectedDocumentType,\n documentInBounds,\n documentTooClose,\n documentDetectionScore: detectionScore,\n documentDetectionThresholdMet: detectionThresholdMet,\n\n mrzDetectionScore,\n mrzDetectionThresholdMet,\n\n pdf417DetectionScore,\n pdf417DetectionThresholdMet,\n\n passportPageDetectionScore: passportDetectionScore,\n passportPageDetectionThresholdMet: passportDetectionThresholdMet,\n\n focusScore,\n focusThresholdMet,\n\n shouldScanBarcode,\n waitingForBarcodeScan,\n\n isGoodFrame,\n goodFramesCount,\n goodFramesThreshold,\n goodFramesThresholdMet: goodFramesCount >= goodFramesThreshold,\n\n lastFrameCapturedAt: frameCapturedAt,\n frameCaptureRate,\n }\n\n case 'predictionMade': {\n const { detectedDocumentType, passportDetectionScore } = action.payload\n const { requestedDocumentType } = state\n const newState = { ...state, detectedDocumentType }\n\n if (state.captureRequirement === 'idCardOrPassport') {\n const predictionIsRequestedType =\n requestedDocumentType.startsWith(detectedDocumentType)\n\n if (predictionIsRequestedType) {\n newState.differentDocumentTypeDetections = 0\n }\n\n if (\n detectedDocumentType === 'passport' &&\n requestedDocumentType !== 'passport'\n ) {\n newState.requestedDocumentType = 'passport'\n }\n\n if (\n requestedDocumentType === 'passport' &&\n passportDetectionScore < 0.3\n ) {\n newState.requestedDocumentType =\n 'idCardFront' in state.capturedDocuments\n ? 'idCardBack'\n : 'idCardFront'\n }\n }\n\n return newState\n }\n\n case 'barcodeScanned':\n return {\n ...state,\n barcodeResult: action.payload.result,\n waitingForBarcodeScan: false,\n autoCaptureBarcodeRequired: false,\n }\n\n case 'barcodeScanFailed': {\n const newState = {\n ...state,\n barcodeScanFailedAttempts: state.barcodeScanFailedAttempts + 1,\n }\n\n if (\n newState.barcodeScanFailedAttempts >= newState.maxBarcodeScanAttempts\n ) {\n newState.autoCaptureBarcodeRequired = false\n newState.shouldScanBarcode = false\n newState.waitingForBarcodeScan = false\n }\n\n return newState\n }\n\n case 'captureStarted':\n return {\n ...state,\n captureStartedAt: new Date(),\n capturing: false,\n captureFailed: false,\n }\n\n case 'capturing':\n return {\n ...state,\n capturing: true,\n captureFailed: false,\n }\n\n case 'captured':\n return {\n ...state,\n capturing: false,\n captureFailed: false,\n }\n\n case 'frameCaptured':\n return { ...state, imageUrl: action.payload.imageUrl }\n\n case 'captureFailed':\n return {\n ...state,\n capturing: false,\n captureFailed: true,\n }\n\n case 'documentCaptured': {\n const newState = {\n ...state,\n capturing: false,\n captureFailed: false,\n goodFramesCount: 0,\n capturedDocuments: {\n ...state.capturedDocuments,\n [action.payload.documentType]: action.payload,\n },\n }\n\n let remainingRequirements = requiredDocumentsForOption[\n state.captureRequirement\n ].filter((v) => !(v in newState.capturedDocuments))\n\n if (state.captureRequirement === 'idCardOrPassport') {\n if (state.requestedDocumentType === 'passport') {\n remainingRequirements = []\n } else {\n remainingRequirements = remainingRequirements.filter(\n (v) => v !== 'passport',\n )\n }\n }\n\n if (remainingRequirements.length === 0) {\n newState.captureState = 'complete'\n } else {\n newState.requestedDocumentType = remainingRequirements[0]\n if (\n state.requestedDocumentType === 'idCardFront' &&\n newState.requestedDocumentType === 'idCardBack'\n ) {\n newState.captureState = 'requestingFlip'\n newState.documentDetectionThresholdMet = false\n newState.passportPageDetectionThresholdMet = false\n }\n }\n\n return newState\n }\n\n case 'documentCapturedManually': {\n const newState = {\n ...state,\n capturedDocuments: {\n ...state.capturedDocuments,\n [state.requestedDocumentType]: {\n ...action.payload,\n width: 0,\n height: 0,\n },\n },\n }\n\n let remainingRequirements = requiredDocumentsForOption[\n state.captureRequirement\n ].filter((v) => !(v in newState.capturedDocuments))\n\n if (state.captureRequirement === 'idCardOrPassport') {\n if (state.requestedDocumentType === 'passport') {\n remainingRequirements = []\n } else {\n remainingRequirements = remainingRequirements.filter(\n (v) => v !== 'passport',\n )\n }\n }\n\n if (remainingRequirements.length === 0) {\n newState.captureState = 'complete'\n } else {\n newState.requestedDocumentType = remainingRequirements[0]\n if (\n state.requestedDocumentType === 'idCardFront' &&\n newState.requestedDocumentType === 'idCardBack'\n ) {\n newState.captureState = 'requestingFlip'\n newState.documentDetectionThresholdMet = false\n newState.passportPageDetectionThresholdMet = false\n }\n }\n\n return newState\n }\n\n case 'flipRequestCompleted':\n return { ...state, captureState: 'capturing' }\n\n case 'resetWizard':\n return { ...initialState }\n\n default:\n return state\n }\n}\n\nexport const IdCaptureStateProvider = ({\n children,\n}: {\n children: ReactNode\n}) => {\n const [state, dispatch] = useReducer(reducer, initialState)\n\n const onResize = useDebouncedCallback(() => {\n dispatch({ type: 'redrawRequested' })\n }, 500)\n\n useLayoutEffect(() => {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', onResize)\n return () => {\n window.removeEventListener('resize', onResize)\n }\n }, [onResize])\n\n return (\n <IdCaptureStateContext.Provider value={state}>\n <IdCaptureDispatchContext.Provider value={dispatch}>\n {children}\n </IdCaptureDispatchContext.Provider>\n </IdCaptureStateContext.Provider>\n )\n}\n\nexport const useIdCaptureState = (): [IdCaptureState, IdCaptureDispatch] => {\n const state = useContext(IdCaptureStateContext)\n const dispatch = useContext(IdCaptureDispatchContext)\n if (!state || !dispatch)\n throw new Error(\n 'useIdCaptureState cannot be used without IdCaptureStateProvider',\n )\n\n return [state, dispatch]\n}\n","import styled from 'styled-components'\nimport React, { ReactElement, ReactNode, useMemo } from 'react'\nimport { useIdCaptureState } from '../id_capture/IdCaptureStateProvider'\nimport { DetectedObject } from '../../lib/models/DocumentDetection'\nimport { Face, FaceKeypoint } from '../../lib/models/FaceDetection'\nimport { createPortal } from 'react-dom'\n\nexport function DebugStatsPane({ children }: { children: ReactNode }) {\n const element = <DebugStatsPaneDiv>{children}</DebugStatsPaneDiv>\n const portalLocation = document.getElementById(\n 'idmission-above-guides-content',\n )\n if (!portalLocation) return element\n return createPortal(element, portalLocation)\n}\n\nexport const DebugStatsPaneDiv = styled.span`\n font-size: 16px;\n font-family: monospace;\n position: absolute;\n left: 20px;\n bottom: 20px;\n margin-right: 20px;\n padding: 8px;\n color: limegreen;\n background: rgba(0, 0, 0, 0.5);\n z-index: 10002;\n`\n\nexport const ObjectDetectionDebugOverlayDiv = styled.div<{ $flipX?: boolean }>`\n position: absolute;\n z-index: 1001;\n width: 100%;\n height: 100%;\n max-width: 100%;\n max-height: 100%;\n overflow: hidden;\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport const ObjectDetectionDebugBox = styled.div<{\n $color?: string\n $flipX?: boolean\n}>`\n font: 10px monospace;\n position: absolute;\n border: 3px solid ${({ $color }) => $color ?? 'green'};\n color: ${({ $color }) => $color ?? 'green'};\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport const FaceDetectionKeypointMarker = styled.div<{\n $color?: string\n $flipX?: boolean\n}>`\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ${({ $color }) => $color ?? 'red'};\n font: 10px monospace;\n color: ${({ $color }) => $color ?? 'red'};\n border-radius: 50%;\n ${({ $flipX }) => ($flipX ? 'transform: scaleX(-1);' : '')}\n`\n\nexport type DebugScalingDetails = {\n horizontal: boolean\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n scaledWidth: number\n scaledHeight: number\n xOffset: number\n yOffset: number\n}\n\nexport function useDebugScalingDetails({\n enabled = true,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n}: {\n enabled?: boolean\n pageWidth: number\n pageHeight: number\n videoWidth: number\n videoHeight: number\n}): DebugScalingDetails {\n return useMemo(() => {\n let horizontal = false,\n scaledWidth = 0,\n scaledHeight = 0,\n xOffset = 0,\n yOffset = 0\n\n if (enabled) {\n horizontal = pageWidth / pageHeight < videoWidth / videoHeight\n if (horizontal) {\n scaledWidth = videoWidth * (pageHeight / videoHeight)\n xOffset = (scaledWidth - pageWidth) / 2\n } else {\n scaledHeight = videoHeight * (pageWidth / videoWidth)\n yOffset = (scaledHeight - pageHeight) / 2\n }\n }\n\n return {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n }\n }, [enabled, pageHeight, pageWidth, videoHeight, videoWidth])\n}\n\nexport const DebugBoundingBoxOverlay = ({\n scaling,\n $flipX,\n children,\n}: {\n scaling?: DebugScalingDetails\n $flipX?: boolean\n children: ReactNode\n}) => {\n const [{ guideRectWidth, guideRectHeight, guideRectX, guideRectY }] =\n useIdCaptureState()\n\n return (\n <ObjectDetectionDebugOverlayDiv\n id=\"debug-overlay-div\"\n $flipX={$flipX}\n style={{\n top: guideRectY,\n left: guideRectX,\n width: guideRectWidth || scaling?.pageWidth,\n height: guideRectHeight || scaling?.pageHeight,\n }}\n >\n {children}\n </ObjectDetectionDebugOverlayDiv>\n )\n}\n\nexport type DetectedObjectDebugBoxProps = {\n obj: DetectedObject\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function IdCaptureDetectedObjectDebugBox({\n obj,\n flipX,\n color = 'green',\n scaling,\n}: DetectedObjectDebugBoxProps): ReactElement {\n const {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n } = scaling\n\n if (!videoWidth || !videoHeight || !pageWidth || !pageHeight) return <></>\n\n let top\n let left\n let width\n let height\n\n if (horizontal) {\n top = (obj.box.yMin / videoHeight) * pageHeight\n left = (obj.box.xMin / videoWidth) * scaledWidth - xOffset\n width = (obj.box.width / videoWidth) * scaledWidth\n height = (obj.box.height / videoHeight) * pageHeight\n } else {\n top = (obj.box.yMin / videoHeight) * scaledHeight - yOffset\n left = (obj.box.xMin / videoWidth) * pageWidth\n width = (obj.box.width / videoWidth) * pageWidth\n height = (obj.box.height / videoHeight) * scaledHeight\n }\n\n return (\n <ObjectDetectionDebugBox\n $flipX={flipX}\n $color={color}\n style={{ top, left, width, height }}\n />\n )\n}\n\nexport type SelfieCaptureFaceDebugBoxProps = {\n face: Face\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function SelfieCaptureFaceDebugBox({\n face,\n flipX,\n color = 'green',\n scaling,\n}: SelfieCaptureFaceDebugBoxProps): ReactElement {\n const {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n } = scaling\n\n if (!videoWidth || !videoHeight || !pageWidth || !pageHeight) return <></>\n\n let top\n let left\n let width\n let height\n\n if (horizontal) {\n top = (face.box.yMin / videoHeight) * pageHeight\n left = (face.box.xMin / videoWidth) * scaledWidth - xOffset\n width = (face.box.width / videoWidth) * scaledWidth\n height = (face.box.height / videoHeight) * pageHeight\n } else {\n top = (face.box.yMin / videoHeight) * scaledHeight - yOffset\n left = (face.box.xMin / videoWidth) * pageWidth\n width = (face.box.width / videoWidth) * pageWidth\n height = (face.box.height / videoHeight) * scaledHeight\n }\n\n return (\n <>\n <ObjectDetectionDebugBox\n $flipX={flipX}\n $color={color}\n style={{ top, left, width, height }}\n />\n\n {face.keypoints.map((point, ii) => (\n <SelfieCaptureFaceKeypoint\n key={ii}\n point={point}\n scaling={scaling}\n flipX={flipX}\n />\n ))}\n </>\n )\n}\n\ntype SelfieCaptureFaceKeypointProps = {\n point: FaceKeypoint\n scaling: DebugScalingDetails\n flipX?: boolean\n color?: string\n}\n\nexport function SelfieCaptureFaceKeypoint({\n point,\n flipX,\n color = 'red',\n scaling: {\n horizontal,\n pageWidth,\n pageHeight,\n videoWidth,\n videoHeight,\n scaledWidth,\n scaledHeight,\n xOffset,\n yOffset,\n },\n}: SelfieCaptureFaceKeypointProps): ReactElement {\n let left, top\n if (horizontal) {\n left = (point.x / videoWidth) * scaledWidth - xOffset\n top = (point.y / videoHeight) * pageHeight\n } else {\n left = (point.x / videoWidth) * pageWidth\n top = (point.y / videoHeight) * scaledHeight - yOffset\n }\n\n top -= 2\n left -= 2\n\n return (\n <FaceDetectionKeypointMarker\n $flipX={flipX}\n $color={color}\n style={{ top, left }}\n />\n )\n}\n","export default {}\n","export default {\n 'Use your device camera to capture your ID':\n 'Para capturar la identificación hay que utilizar la cámara del dispositivo.',\n\n 'Use your iPhone as a webcam': 'Usar el iPhone como cámara web',\n 'Models warming up...': 'Cargando modelos...',\n 'Camera initializing...': 'Inicializando la cámara...',\n 'Camera access blocked': 'Acceso bloqueado a la cámara',\n 'Location access blocked': 'Acceso bloqueado a la localización',\n Continue: 'Continuar',\n 'Processing...': 'Procesando...',\n\n 'Your camera permission is disabled':\n 'El permiso de la cámara está desactivado',\n 'This application requires access to your camera to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for camera permissions, you must go to settings and provide camera access to the current browser.':\n 'Esta aplicación requiere el acceso a la cámara para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso a la cámara en el explorador actual.',\n 'Your microphone permission is disabled':\n 'El permiso de la micrófono está desactivado',\n 'This application requires access to your microphone to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for microphone permissions, you must go to settings and provide microphone access to the current browser.':\n 'Esta aplicación requiere tener acceso al micrófono para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso al micrófono en el explorador actual.',\n 'Your location permission is disabled':\n 'El permiso de la localización está desactivado',\n 'This application requires access to your location to continue. Please accept the permission once prompted by the browser. If the browser does not prompt for location permissions, you must go to settings and provide location access to the current browser.':\n 'Esta aplicación requiere el acceso a la localización para continuar. Hay que aceptar el permiso una vez que se muestre la ventana en el explorador. Si no aparece la ventana para otorgar permisos, entonces hay que dirigirse a Configuración y otorgar el permiso a la localización en el explorador actual.',\n Retry: 'Reintentar',\n\n 'Scan the front of ID': 'Escanear el frente de la ID',\n 'Scan the back of ID': 'Escanear el reverso de la ID',\n 'Scan the ID page of passport': 'Escanear la página de datos del pasaporte',\n\n 'ID Card Front': 'Frente de la ID',\n 'ID Card Back': 'Reverso de la ID',\n Passport: 'Pasaporte',\n\n 'Document not detected': 'No se ha detectado el documento',\n 'Document is not centered': 'Documento no centrado',\n 'Document too close, please back up':\n 'Documento muy cerca, favor de alejarse',\n 'Document out of focus – try improving the lighting':\n 'Documento no enfocado - hay que tratar de mejorar la iluminación',\n 'Document detected, hold still...':\n 'Se ha detectado el documento, no moverse por favor...',\n\n 'Capturing...': 'Capturando...',\n 'Capture failed!': 'Falló la captura',\n\n 'Please flip your ID card...': 'Por favor voltea la identificación...',\n 'ID card front captured.': 'Se ha capturado el frente de la identificación.',\n\n 'ID Capture Successful': 'Captura Exitosa de ID',\n 'Verify the entire ID was captured clearly with no glare.':\n 'Hay que verificar que toda la ID se vea completa y sin reflejos.',\n\n Submit: 'Enviar',\n 'Submitting...': 'Enviando...',\n\n 'Use your device camera to capture your face':\n 'Hay que utilizar la cámara del dispositivo para capturar el rostro',\n\n 'Remove Sunglasses & Hat': 'Hay que quitarse lentes y/o la gorra',\n 'Avoid Excessive Backlighting': 'Hay que evitar demasiada luz en el fondo',\n\n 'Hold still for a few seconds...':\n 'Hay que permanecer quieto por unos segundos...',\n 'Look straight into the camera...':\n 'Hay que mirar directamente a la cámara...',\n 'Move back...': 'Hay que hacerse hacia atrás..',\n 'Move forward...': 'Hay que hacerse hacia adelante...',\n 'Move to the center...': 'Hay que moverse hacia el centro...',\n 'Please remove your eye coverings (sunglasses, eye patch, etc.)...':\n 'Hay que quitarse lo que cubre los ojos (lentes, parche, etc.)...',\n 'Please remove your head coverings (hat, scarf, etc.)...':\n 'Hay que quitarse lo que cubre la cabeza (gorra, mascada, etc.)...',\n 'Please remove your mask...': 'Hay que quitarse el cubrebocas...',\n 'Live face not detected, please try again':\n 'Rostro vivo no detectado. Por favor hay que intentar de nuevo.',\n Exit: 'Salir',\n 'Face liveness has been verified!':\n 'Se ha verificado la Prueba de Vida en rostro!',\n Done: 'Terminar',\n\n 'Customer has been identified!': '¡Se ha identificado al cliente!',\n 'Customer not found': 'Cliente no encontrado',\n\n 'Additional document capture': 'Captura de otro documento',\n Next: 'Siguiente',\n\n 'Please sign the box below':\n 'Por favor, hay que firmar en el recuadro de abajo',\n Accept: 'Aceptar',\n Clear: 'Borrar',\n\n 'Video signature has been successfully captured!':\n 'La video firma ha sido exitosa.',\n\n 'Network unreachable': 'No hay conexión a internet.',\n \"We're having trouble reaching our services, please check your connection and try again.\": `Estamos teniendo problemas para alcanzar nuestros servicios, por favor verificar la conexión a internet e intentar de nuevo.`,\n \"We're sorry, an unexpected error has occurred.\": `Lo sentimos, se ha producido un error inesperado.`,\n\n 'Document Capture': 'Captura de documento',\n Capture: 'Capturar',\n 'Retry capture': 'Reintentar la captura',\n Upload: 'Enviar',\n 'Uploading...': 'Procesando...',\n 'Upload succeeded!': 'Proceso completo!',\n\n 'Display the front of your ID card...':\n 'Hay que mostrar el frente de la identificación...',\n 'Display the back of your ID card...':\n 'Hay que mostrar el reverso de la identificación...',\n 'Please move your face to the center...':\n 'Por favor, hay que mover la cabeza hacia el centro...',\n 'Searching for ID card...':\n 'Localizando la identificación...',\n 'Please read the following text aloud':\n 'Hay que leer el siguiente texto en voz alta',\n 'Video ID has been successfully captured!':\n 'Video ID capturado exitosamente!',\n 'ID Front Image':\n 'Frente de ID',\n 'ID Back Image':\n 'Reverso de ID',\n\n \"We're having some trouble.\": 'Se ha presentado un problema.',\n 'On-device capture guidance failed, please capture a selfie manually.':\n 'La captura automática para toma de selfie falló. Por favor, hay que tomarse la selfie manualmente.',\n 'Verifying...': 'Verificando....',\n 'Please capture the front of your ID card.':\n 'Hay que capturar el frente de la identificación.',\n 'Please capture the back of your ID card.':\n 'Hay que capturar el reverso de la identificación.',\n 'Please capture the front of your ID card, or the ID page of your passport.':\n 'Hay que capturar el frente de la identificación o la página de datos del pasaporte.',\n 'Please capture the back of your ID card, or click Done if submitting a passport.':\n 'Hay que capturar el reverso de la identificación o hay que presionar el botón de Terminar si se trata de un pasaporte.',\n 'Please capture the ID page of your passport.':\n 'Hay que capturar la página de datos del pasaporte.',\n 'On-device capture guidance failed, please capture a photo of your ID card manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación manualmente.',\n 'On-device capture guidance failed, please capture a photo of your passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la pasaporte manualmente.',\n 'On-device capture guidance failed, please capture photos of your ID card and passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación y del pasaporte manualmente.',\n 'On-device capture guidance failed, please capture photos of your ID card or passport manually.':\n 'La captura automática falló. Por favor hay que tomar una foto de la identificación o del pasaporte manualmente.',\n 'Capture ID page of passport':\n 'Captura pasaporte (página de la foto)',\n 'Capture back of ID card':\n 'Captura del reverso',\n\n 'Downloading...': 'Descargando...',\n 'Accessing camera...': 'Accediendo a la cámara',\n 'Camera ready': 'Cámara está lista',\n 'Loading guided capture experience...':\n 'Cargando la experiencia guiada para la captura....',\n 'Guided capture experience ready': 'La experiencia guiada está lista',\n \"Let's Go!\": 'Vamos!',\n}\n","import { useEffect, useMemo } from 'react'\nimport { initReactI18next, useTranslation } from 'react-i18next'\nimport enTranslation from './en/translation'\nimport esTranslation from './es/translation'\nimport LanguageDetector from 'i18next-browser-languagedetector'\nimport i18n from 'i18next'\n\nexport const ALL_LANGUAGES = ['auto', 'en', 'es'] as const\nexport type LangOptions = typeof ALL_LANGUAGES\nexport type LangOption = LangOptions[number] | string\n\nexport const resources = {\n en: { translation: enTranslation },\n es: { translation: esTranslation },\n}\n\nexport function initializeI18n() {\n i18n\n .use(LanguageDetector)\n .use(initReactI18next)\n .init({\n resources,\n detection: { caches: [] },\n fallbackLng: 'en',\n debug: false,\n interpolation: { escapeValue: false },\n })\n}\n\nexport const useLanguage = (lang: LangOption): void => {\n const { i18n } = useTranslation()\n useEffect(() => {\n if (lang !== 'auto') {\n i18n.changeLanguage(lang)\n } else {\n i18n.changeLanguage() // call without argument to use detection\n }\n }, [i18n, lang])\n}\n\nexport type CustomerSuppliedTranslations = { [lang: string]: string }\nexport type CustomerSuppliedVerbiage =\n | string\n | CustomerSuppliedTranslations\n | undefined\nexport type RecursiveVerbiageObject =\n | CustomerSuppliedVerbiage\n | { [key: string]: RecursiveVerbiageObject }\n\nfunction evaluateVerbiage(\n t: (key: string) => string,\n currentLanguage: string,\n verbiage: CustomerSuppliedVerbiage,\n fallback: string,\n): string {\n if (typeof verbiage === 'string') return verbiage\n\n if (typeof verbiage === 'object') {\n const translations = verbiage as CustomerSuppliedTranslations\n if (translations[currentLanguage]) return translations[currentLanguage]\n\n const nonLocaleLang = currentLanguage.split('-')[0]\n if (translations[nonLocaleLang]) return translations[nonLocaleLang]\n }\n\n return t(fallback)\n}\n\nexport function useVerbiage(\n verbiage: CustomerSuppliedVerbiage,\n fallback: string,\n): string {\n const { t, i18n } = useTranslation()\n\n return useMemo(\n () => evaluateVerbiage(t, i18n.language, verbiage, fallback),\n [fallback, i18n.language, t, verbiage],\n )\n}\n\nexport function useTranslations<\n T extends { [key: string]: RecursiveVerbiageObject },\n>(\n verbiage: T | undefined,\n fallbacks: { [K in keyof T]: string },\n): { [K in keyof T]: string } {\n const { t, i18n } = useTranslation()\n\n return useMemo(\n () => ({\n ...verbiage,\n ...Object.keys(fallbacks).reduce(\n (result, key) => ({\n ...result,\n [key as keyof T]: evaluateVerbiage(\n t,\n i18n.language,\n verbiage?.[key] as CustomerSuppliedVerbiage,\n fallbacks[key],\n ),\n }),\n {} as { [K in keyof T]: string },\n ),\n }),\n [fallbacks, i18n.language, t, verbiage],\n )\n}\n","import React, { ReactNode } from 'react'\nimport styled from 'styled-components'\nimport { createPortal } from 'react-dom'\n\nexport type GuidanceMessageVariant = 'default' | 'positive' | 'negative'\n\nexport const GuidanceMessageContainerDiv = styled.div<{\n $top?: string\n $bottom?: string\n}>`\n position: absolute;\n top: calc(${({ $top }) => $top ?? '10vh'});\n ${({ $bottom }) => ($bottom ? `bottom: ${$bottom};` : ``)}\n font-weight: bold;\n width: 100%;\n display: flex;\n`\n\nexport const GuidanceMessageContainer = (props: {\n $top?: string\n $bottom?: string\n className?: string\n children?: ReactNode\n}) => {\n const element = <GuidanceMessageContainerDiv {...props} />\n const portalLocation = document.getElementById(\n 'idmission-above-guides-content',\n )\n if (!portalLocation) return element\n return createPortal(element, portalLocation)\n}\n\nexport const GuidanceMessage = styled.div<{\n $background?: string\n $textColor?: string\n $variant?: GuidanceMessageVariant\n}>`\n margin-left: auto;\n margin-right: auto;\n background: ${(props) =>\n props.$background ??\n props.theme?.guidanceMessages?.[props.$variant ?? 'default']\n ?.backgroundColor ??\n '#ccc'};\n color: ${(props) =>\n props.$textColor ??\n props.theme?.guidanceMessages?.[props.$variant ?? 'default']?.textColor ??\n 'black'};\n padding: 10px 12px 8px;\n border-radius: 8px;\n z-index: 10001;\n`\n","export const DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets'\n","import React, { useContext, useEffect } from 'react'\nimport useResizeObserver from 'use-resize-observer'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport { supportsNativeBarcodeScanning } from '../../lib/barcode/Scan'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { CaptureAttemptMetadata } from '../../contexts/SubmissionContext'\nimport { PageContainer } from '../common/Page'\nimport {\n IdCaptureModelsContext,\n IdCapturePrediction,\n} from './IdCaptureModelsProvider'\nimport {\n DebugBoundingBoxOverlay,\n DebugStatsPane,\n IdCaptureDetectedObjectDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { IdCaptureImagePreviewClassNames } from '../common/SelfieProgressPreview'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { useTheme } from 'styled-components'\nimport { CapturedDocumentType } from './CapturedDocuments'\nimport { IdCaptureFitGuideClassNames } from './IdCaptureFitGuide'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport log from '../../lib/utils/logger'\nimport { defaultDocumentDetectionThresholds } from '../../lib/models/DocumentDetection'\nimport { defaultFocusThresholds } from '../../lib/models/Focus'\n\nexport type IdCaptureAssets = {\n portraitGuidesImageUrl?: string\n landscapeGuidesImageUrl?: string\n}\n\nexport type IdCaptureClassNames = {\n container?: string\n guides?: IdCaptureFitGuideClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n imagePreview?: IdCaptureImagePreviewClassNames\n exitCaptureBtn?: string\n}\n\nexport type IdCaptureColors = {\n guideBoxUnsatisfiedColor?: string\n guideBoxSatisfiedColor?: string\n guidanceMessagesSatisfiedBackgroundColor?: string\n guidanceMessagesUnsatisfiedBackgroundColor?: string\n guidanceMessagesSatisfiedTextColor?: string\n guidanceMessagesUnsatisfiedTextColor?: string\n}\n\nexport type IdCaptureVerbiage = {\n instructionText?: CustomerSuppliedVerbiage\n processingIdCardText?: CustomerSuppliedVerbiage\n capturingText?: CustomerSuppliedVerbiage\n captureFailedText?: CustomerSuppliedVerbiage\n guidanceSatisfiedText?: CustomerSuppliedVerbiage\n guidanceTooBlurryText?: CustomerSuppliedVerbiage\n guidanceNotCenteredText?: CustomerSuppliedVerbiage\n guidanceTooCloseText?: CustomerSuppliedVerbiage\n guidanceNotDetectedText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureProps = {\n requiredDocumentType?: CapturedDocumentType\n autoCaptureEnabled?: boolean\n idCardDetectionThreshold?: number\n passportDetectionThreshold?: number\n autoCaptureBarcodeRequired?: boolean | 'mobile'\n mrzDetectionScoreThreshold?: number\n pdf417DetectionThreshold?: number\n\n barcodeScanningEnabled?: boolean\n maxBarcodeScanAttempts?: number\n\n idCardFocusScoreThreshold?: number\n passportFocusScoreThreshold?: number\n\n guidanceMessage?: string\n guidanceSatisfied?: boolean\n\n onPrediction?: (prediction: IdCapturePrediction) => void\n onBarcodeScanned?: (result: PDF417DetectionResult) => void\n onCapture?: (\n frame: string,\n width: number,\n height: number,\n documentType: CapturedDocumentType,\n metadata: CaptureAttemptMetadata,\n ) => void\n\n assets?: IdCaptureAssets\n classNames?: IdCaptureClassNames\n colors?: IdCaptureColors\n verbiage?: IdCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const IdCapture = ({\n requiredDocumentType,\n autoCaptureEnabled = true,\n autoCaptureBarcodeRequired = 'mobile',\n idCardDetectionThreshold = defaultDocumentDetectionThresholds.idCard,\n passportDetectionThreshold = defaultDocumentDetectionThresholds.passport,\n mrzDetectionScoreThreshold = defaultDocumentDetectionThresholds.mrz,\n pdf417DetectionThreshold = defaultDocumentDetectionThresholds.pdf417,\n idCardFocusScoreThreshold = defaultFocusThresholds.idCard?.mobile,\n passportFocusScoreThreshold = defaultFocusThresholds.passport?.mobile,\n barcodeScanningEnabled = true,\n maxBarcodeScanAttempts = 10,\n guidanceMessage,\n guidanceSatisfied,\n onPrediction,\n onCapture,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: IdCaptureProps): React.ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const [state, dispatch] = useIdCaptureState()\n const { cameraRef } = useContext(CameraStateContext)\n const {\n ready: modelsReady,\n setThresholds,\n onPredictionMade,\n detectionTime,\n focusPredictionTime,\n getBestFrame,\n } = useContext(IdCaptureModelsContext)\n\n useEffect(() => {\n dispatch({\n type: 'configureCapture',\n payload: {\n autoCaptureBarcodeRequired,\n barcodeScanningEnabled,\n maxBarcodeScanAttempts,\n },\n })\n }, [\n autoCaptureBarcodeRequired,\n barcodeScanningEnabled,\n dispatch,\n maxBarcodeScanAttempts,\n ])\n\n useEffect(() => {\n setThresholds({\n idCard: idCardDetectionThreshold,\n passport: passportDetectionThreshold,\n mrz: mrzDetectionScoreThreshold,\n pdf417: pdf417DetectionThreshold,\n focus: {\n idCard: { mobile: idCardFocusScoreThreshold },\n passport: { mobile: passportFocusScoreThreshold },\n },\n })\n }, [\n idCardDetectionThreshold,\n idCardFocusScoreThreshold,\n mrzDetectionScoreThreshold,\n passportDetectionThreshold,\n passportFocusScoreThreshold,\n pdf417DetectionThreshold,\n setThresholds,\n ])\n\n useEffect(() => {\n if (!requiredDocumentType) return\n dispatch({\n type: 'setRequiredDocumentType',\n payload: requiredDocumentType,\n })\n }, [dispatch, requiredDocumentType])\n\n useEffect(() => {\n dispatch({\n type: 'pageRendered',\n payload: { pageWidth: width, pageHeight: height },\n })\n }, [dispatch, height, width])\n\n useEffect(() => {\n onPredictionMade((prediction) => {\n dispatch({ type: 'objectsDetected', payload: { prediction } })\n onPrediction?.(prediction)\n })\n }, [dispatch, onPrediction, onPredictionMade])\n\n const shouldCapture =\n autoCaptureEnabled &&\n state.goodFramesThresholdMet &&\n !state.capturing &&\n !state.waitingForBarcodeScan &&\n timeSince(state.captureStartedAt) >= 3000\n\n useEffect(() => {\n if (!shouldCapture) return\n\n dispatch({ type: 'capturing' })\n\n const bestFrame = getBestFrame()\n if (!bestFrame) {\n log('uh oh, i did not get a photo')\n dispatch({ type: 'captureFailed' })\n return\n }\n\n const {\n canvas: originalCanvas,\n documentType,\n boundingBox,\n detectionScore,\n focusScore,\n } = bestFrame\n const { width, height } = originalCanvas\n let canvas = originalCanvas\n\n // resize image to 2k max if barcode is read\n const isGreaterThan2k =\n (width > 1920 && height > 1080) || (width > 1080 && height > 1920)\n if (isGreaterThan2k && !!state.barcodeResult) {\n canvas = document.createElement('canvas')\n\n if (width > height) {\n canvas.width = 1920\n canvas.height = height * (1920 / width)\n } else {\n canvas.height = 1920\n canvas.width = width * (1920 / height)\n }\n const ctx2d = canvas.getContext('2d')\n if (!ctx2d) return\n ctx2d.drawImage(originalCanvas, 0, 0, canvas.width, canvas.height)\n }\n\n const imageUrl = canvas.toDataURL('image/jpeg', 0.95)\n dispatch({ type: 'frameCaptured', payload: { imageUrl } })\n\n const capturedDocumentType: CapturedDocumentType =\n documentType === 'passport' ? 'passport' : state.requestedDocumentType\n\n setTimeout(() => {\n const captureTime =\n new Date().getTime() - (state.captureStartedAt ?? new Date()).getTime()\n const metadata: CaptureAttemptMetadata = {\n autoCapture: 'Y',\n captureTime,\n boundingBox,\n bestDetectionScore: detectionScore,\n bestFocusScore: focusScore,\n }\n onCapture?.(imageUrl, width, height, capturedDocumentType, metadata)\n dispatch({ type: 'captured' })\n }, 0)\n }, [\n dispatch,\n getBestFrame,\n onCapture,\n shouldCapture,\n state.barcodeResult,\n state.captureStartedAt,\n state.requestedDocumentType,\n ])\n\n assets.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n\n const theme = useTheme()\n colors.guideBoxUnsatisfiedColor ||=\n theme.idCapture?.guideBox?.unsatisfiedColor ?? 'white'\n colors.guideBoxSatisfiedColor ||=\n theme.idCapture?.guideBox?.satisfiedColor ?? 'green'\n\n const verbiage = useTranslations(rawVerbiage, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n capturingText: 'Capturing...',\n captureFailedText: 'Capture failed!',\n guidanceSatisfiedText: 'Document detected, hold still...',\n guidanceTooBlurryText: 'Document out of focus – try improving the lighting',\n guidanceNotCenteredText: 'Document is not centered',\n guidanceTooCloseText: 'Document too close, please back up',\n guidanceNotDetectedText: 'Document not detected',\n })\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: state.guideRectWidth,\n pageHeight: state.guideRectHeight,\n videoWidth: state.videoWidth,\n videoHeight: state.videoHeight,\n })\n\n let satisfied = state.isGoodFrame\n if (typeof guidanceSatisfied === 'boolean') satisfied = guidanceSatisfied\n\n guidanceMessage ||= satisfied\n ? verbiage.guidanceSatisfiedText\n : !state.documentDetectionThresholdMet\n ? verbiage.guidanceNotDetectedText\n : !state.documentInBounds\n ? verbiage.guidanceNotCenteredText\n : state.documentTooClose\n ? verbiage.guidanceTooCloseText\n : !state.focusThresholdMet\n ? verbiage.guidanceTooBlurryText\n : ''\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n {guidanceMessage !== '' && (\n <GuidanceMessageContainer\n $top=\"\"\n $bottom=\"12.5dvh\"\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n $variant={satisfied ? 'positive' : 'default'}\n className={classNames.guidanceMessage}\n >\n {guidanceMessage}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && (\n <DebugBoundingBoxOverlay\n $flipX={!cameraRef.current?.isRearFacing}\n scaling={debugScalingDetails}\n >\n {state.detectedObjects.map((obj, i) => (\n <IdCaptureDetectedObjectDebugBox\n key={i}\n obj={obj}\n scaling={debugScalingDetails}\n flipX={!cameraRef.current?.isRearFacing}\n />\n ))}\n </DebugBoundingBoxOverlay>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {state.frameCaptureRate > 0.75 ? '✅' : '👎'} Frame Rate:{' '}\n {Math.round((state.frameCaptureRate + Number.EPSILON) * 1000) / 1000}{' '}\n fps ({detectionTime}ms doc detect, {focusPredictionTime}ms focus)\n <br />\n {modelsReady ? (\n <>\n {state.documentDetectionThresholdMet ? '✅' : '❌'} Document\n Score: {state.documentDetectionScore.toFixed(3)} (\n {state.documentType})\n <br />\n {state.passportPageDetectionThresholdMet ? '✅' : '❌'} Passport\n Score: {state.passportPageDetectionScore.toFixed(3)}\n <br />\n {state.focusThresholdMet ? '✅' : '❌'} Focus Score:{' '}\n {state.focusScore.toFixed(3)}\n <br />\n {state.documentInBounds ? '✅' : '❌'} Document In Bounds\n <br />\n {state.goodFramesThresholdMet ? '✅' : '❌'} Good Frame Count:{' '}\n {state.goodFramesCount}/{state.goodFramesThreshold}\n {barcodeScanningEnabled && state.autoCaptureBarcodeRequired ? (\n <>\n <br />\n {state.barcodeResult ? '✅' : '❌'} Barcode Scanned (\n {supportsNativeBarcodeScanning() ? 'Native' : 'ZXing'},{' '}\n {state.barcodeScanFailedAttempts}/\n {state.maxBarcodeScanAttempts} failed attempts)\n </>\n ) : null}\n </>\n ) : (\n <>❌ Models not ready</>\n )}\n </DebugStatsPane>\n )}\n </PageContainer>\n )\n}\n\nconst timeSince = (t: Date | null): number => {\n if (!t) return 0\n return Math.abs(new Date().getTime() - t.getTime())\n}\n","import React from 'react'\nimport styled from 'styled-components'\n\nexport const ExitCaptureStyledButton = styled.button`\n position: absolute;\n top: 12px;\n right: 12px;\n font-size: 20px;\n width: 32px;\n height: 32px;\n font-family: monospace;\n z-index: 1002;\n border: none;\n border-radius: 4px;\n background: #ccc;\n cursor: pointer;\n padding: 8px;\n box-sizing: border-box;\n display: flex;\n\n &:hover {\n background: #ddd;\n }\n\n & > svg {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n`\n\nexport const ExitCaptureButton = ({\n onClick,\n className,\n}: {\n onClick?: () => void\n className?: string\n}) => {\n return (\n <ExitCaptureStyledButton onClick={onClick} className={className}>\n <svg\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n x=\"0px\"\n y=\"0px\"\n viewBox=\"19.3 19.3 25.499999999999996 25.499999999999996\"\n enableBackground=\"new 0 0 64 64\"\n width={16}\n height={16}\n >\n <g id=\"close-outline-bot_x5F_s1g1_x5F_s2g2_x5F_s3g1_x5F_s4g1\">\n <line\n fill=\"none\"\n stroke=\"#000000\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeMiterlimit=\"10\"\n x1=\"19.75\"\n y1=\"44.25\"\n x2=\"44.25\"\n y2=\"19.75\"\n />\n </g>\n <g id=\"close-outline-top_x5F_s1g1_x5F_s2g2_x5F_s3g1_x5F_s4g1\">\n <line\n fill=\"none\"\n stroke=\"#000000\"\n strokeWidth=\"1\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeMiterlimit=\"10\"\n x1=\"44.25\"\n y1=\"44.25\"\n x2=\"19.75\"\n y2=\"19.75\"\n />\n </g>\n </svg>\n </ExitCaptureStyledButton>\n )\n}\n","import styled from 'styled-components'\n\nexport const ButtonsRow = styled.div`\n display: flex;\n gap: 0 15px;\n justify-content: center;\n`\n","import React, { useEffect, useState } from 'react'\nimport { useTheme } from 'styled-components'\n\nexport type IdCaptureLoadingGraphicProps = {\n width?: number\n height?: number\n className?: string\n}\n\nexport default function IdCaptureLoadingGraphic(\n props: IdCaptureLoadingGraphicProps,\n) {\n const isMobile = window.innerHeight > window.innerWidth\n return isMobile ? (\n <IdCaptureLoadingGraphicMobile {...props} />\n ) : (\n <IdCaptureLoadingGraphicDesktop {...props} />\n )\n}\n\nexport function IdCaptureLoadingGraphicDesktop({\n width = 698,\n height = 452,\n className,\n}: IdCaptureLoadingGraphicProps) {\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 7)\n }, 1000)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n const accentOpacity =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentOpacity ?? 0.2\n\n return (\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '100%',\n }}\n >\n <svg\n className={className}\n width={width}\n height={height}\n viewBox=\"0 0 698 452\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n margin: 'auto',\n transform: `scale(${frame > 1 ? 1 : frame === 1 ? 1.25 : 0.75})`,\n transition: 'transform 0.2s linear, border-width 0.2s linear',\n border: `${frame >= 5 ? 10 : 0}px solid ${accentColor}`,\n }}\n >\n <g filter={frame === 1 ? 'url(#filter0_f_91_884)' : undefined}>\n <path\n d=\"M10 0.5L688 0.5C693.247 0.5 697.5 4.75329 697.5 10L697.5 442C697.5 447.246 693.247 451.5 688 451.5L9.99999 451.5C4.75328 451.5 0.5 447.246 0.5 442L0.5 9.99998C0.5 4.75328 4.75329 0.5 10 0.5Z\"\n fill=\"#F3F3F3\"\n stroke=\"#DCDCDC\"\n />\n <mask\n id=\"mask0_91_854\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"30\"\n y=\"60\"\n width=\"207\"\n height=\"266\"\n >\n <rect\n x=\"30.7754\"\n y=\"60.5945\"\n width=\"205.426\"\n height=\"265.304\"\n rx=\"3\"\n fill=\"#D9D9D9\"\n />\n </mask>\n <g mask=\"url(#mask0_91_854)\">\n <path\n d=\"M161.429 226.164C161.472 226.322 161.474 226.488 161.438 226.647C157.252 244.639 146.071 257.508 132.955 257.508C119.837 257.508 108.632 244.59 104.447 226.595C104.411 226.439 104.413 226.276 104.453 226.121L107.568 214.051L108.337 211.118C108.453 210.678 108.85 210.371 109.305 210.371L156.578 210.371C157.034 210.371 157.432 210.68 157.546 211.122L160.976 224.435L161.305 225.701L161.429 226.164Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M185.475 157.408C185.556 157.356 185.628 157.291 185.693 157.219C210.004 130.149 193.715 196.897 180.188 189.065C157.256 175.818 183.525 158.645 185.475 157.408Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M267.491 324.918C267.577 325.255 267.487 325.608 267.24 325.853C254.85 338.143 225.105 345.481 222.791 346.037C222.686 346.063 222.601 346.067 222.493 346.058C219.509 345.795 174.209 342.097 147.081 357.481C142.849 359.881 122.568 356.455 121.909 356.343C121.888 356.339 121.882 356.339 121.861 356.337L89.946 352.929C89.8715 352.921 89.8068 352.921 89.7323 352.929C87.9869 353.117 64.0883 355.438 45.1808 343.79C29.8522 334.346 9.55527 336.584 -1.36759 325.857C-1.61519 325.614 -1.71005 325.255 -1.62441 324.919L1.46107 312.802C6.33129 293.793 21.3654 279.026 40.5404 274.455L42.6579 273.963L66.162 268.361L72.5851 266.837C75.2907 266.181 77.8788 265.267 80.3256 264.095C82.3725 263.11 84.3253 261.962 86.1605 260.649C88.1368 259.243 89.9955 257.649 91.6659 255.891C96.1597 251.18 99.4771 245.367 101.171 238.827L103.665 229.17L104.324 226.568L104.371 226.357L107.571 214.051L108.319 211.123C108.433 210.681 108.831 210.371 109.288 210.371L156.558 210.371C157.013 210.371 157.411 210.679 157.526 211.12L160.978 224.435L161.308 225.701L161.475 226.325C161.489 226.377 161.496 226.431 161.496 226.486V226.486C161.496 226.54 161.503 226.595 161.517 226.647L162.202 229.193L164.696 238.827C167.025 247.781 172.413 255.446 179.73 260.649C183.729 263.532 188.317 265.665 193.282 266.837L199.211 268.244L225.326 274.455C244.501 279.026 259.535 293.793 264.406 312.802L267.491 324.918Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M161.429 226.164C161.472 226.322 161.474 226.488 161.438 226.647C157.252 244.639 146.071 257.508 132.955 257.508C119.837 257.508 108.632 244.59 104.447 226.595C104.411 226.439 104.413 226.276 104.453 226.121L107.568 214.051L108.337 211.118C108.453 210.678 108.85 210.371 109.305 210.371L156.578 210.371C157.034 210.371 157.432 210.68 157.546 211.122L160.976 224.435L161.305 225.701L161.429 226.164Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M80.3983 157.408C80.3166 157.356 80.2445 157.291 80.1799 157.219C55.8686 130.149 72.1582 196.897 85.685 189.065C108.616 175.818 82.3476 158.645 80.3983 157.408Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M189.527 137.873C189.52 137.873 189.515 137.879 189.515 137.885C189.515 139.944 189.397 141.956 189.162 143.968C188.974 145.796 188.15 153.601 186.692 163.54C185.895 169.048 184.865 175.184 183.649 181.346C183.638 181.398 183.635 181.447 183.631 181.5V181.5C183.625 181.607 183.575 181.713 183.554 181.818C180.568 196.836 176.367 211.751 170.881 217.193C164.67 223.381 159.682 229.007 153.988 233.062C148.295 237.14 141.919 239.672 132.978 239.672C124.038 239.672 117.662 237.14 111.968 233.062C106.298 229.007 101.286 223.381 95.0752 217.193C89.5754 211.714 85.367 196.715 82.3561 181.682C82.3499 181.651 82.3467 181.628 82.3467 181.596V181.596C82.3467 181.566 82.3438 181.526 82.338 181.496C81.9648 179.566 81.6147 177.636 81.2645 175.728C81.1233 174.932 80.9821 174.135 80.841 173.338C80.2528 169.962 79.7352 166.657 79.2646 163.563C77.5768 152.19 76.7532 143.609 76.7472 143.546C76.747 143.544 76.7471 143.545 76.7469 143.543C76.5589 141.692 76.4648 139.794 76.4648 137.873C76.4648 137.381 76.4648 136.889 76.4648 136.397C76.5825 131.967 77.1942 127.654 78.3 123.528C78.3471 123.341 78.3941 123.153 78.4412 122.966C84.723 100.089 105.121 83.0011 129.731 81.6416C130.814 81.5713 131.872 81.5479 132.978 81.5479C148.601 81.5479 162.741 87.8531 172.975 98.0494C181.822 106.839 187.75 118.559 189.186 131.615C189.42 133.674 189.538 135.756 189.539 137.862C189.539 137.868 189.533 137.873 189.527 137.873V137.873Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M141.871 188.529C141.871 192.42 137.895 195.561 132.977 195.561C128.06 195.561 124.107 192.42 124.107 188.529V188.529C124.107 188.132 124.593 188.105 124.773 188.459C126.079 191.03 129.266 192.842 132.977 192.842C136.689 192.842 139.893 191.03 141.204 188.458C141.381 188.112 141.871 188.14 141.871 188.529V188.529Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M267.512 325.037C267.599 325.374 267.509 325.727 267.264 325.974C232.886 360.672 133.16 359.767 132.956 359.765C132.95 359.765 132.962 359.765 132.956 359.765C132.752 359.767 33.0007 360.672 -1.3537 325.95C-1.59784 325.703 -1.68748 325.351 -1.60167 325.014L1.48353 312.922C6.35375 293.889 21.3879 279.122 40.5629 274.551L66.2315 268.456L72.6075 266.933C75.2325 266.311 77.7789 265.415 80.1745 264.28C80.5729 264.092 81.0485 264.176 81.3541 264.494C94.359 278.009 112.66 286.435 132.956 286.435C153.253 286.435 171.556 278.008 184.562 264.49C184.865 264.174 185.337 264.088 185.734 264.274C188.127 265.395 190.657 266.311 193.304 266.933L198.88 268.269L225.349 274.551C244.524 279.122 259.558 293.889 264.405 312.922L267.512 325.037Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M197.318 267.895C198.038 268.068 198.334 268.924 197.847 269.481C190.872 277.457 169.982 297.251 132.954 298.717C92.046 300.357 71.408 275.554 67.0543 269.627C66.6418 269.065 66.9505 268.284 67.6281 268.122L72.606 266.933C75.231 266.311 77.7773 265.415 80.173 264.28C80.5713 264.092 81.0469 264.176 81.3526 264.494C94.3575 278.009 112.659 286.435 132.954 286.435C153.252 286.435 171.555 278.008 184.56 264.49C184.864 264.174 185.336 264.088 185.732 264.274C188.126 265.395 190.655 266.311 193.303 266.933L197.318 267.895Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M75.4663 140.851C75.4663 152.603 78.3795 166.091 80.4253 174.114C80.713 175.242 82.458 175.01 82.5156 173.848C83.0875 162.287 85.7494 140.134 97.4904 130.033C108.545 120.523 117.526 131.201 132.13 131.201C145.353 131.201 157.695 120.704 168.836 130.033C181.053 140.264 183.463 159.992 183.739 171.736C183.767 172.936 185.717 173.218 186.003 172.053C187.986 163.959 190.429 151.77 190.429 140.851C190.429 100.426 174.665 81.3704 132.13 81.3704C93.3928 81.3704 75.4663 100.225 75.4663 140.851Z\"\n fill=\"#525252\"\n />\n </g>\n <rect\n x=\"30.7754\"\n y=\"360.29\"\n width=\"640.93\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"134.29\"\n width=\"402.636\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"209.623\"\n width=\"180.775\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"481.069\"\n y=\"209.623\"\n width=\"188.992\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"267.427\"\n y=\"284.956\"\n width=\"180.775\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"481.069\"\n y=\"284.956\"\n width=\"188.992\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"266.829\"\n y=\"58.3618\"\n width=\"402.636\"\n height=\"40.942\"\n rx=\"3\"\n fill=\"#C1C1C1\"\n />\n\n <g\n fillOpacity={frame === 3 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect\n x=\"672\"\n y=\"55\"\n width=\"47\"\n height=\"410\"\n transform=\"rotate(90 672 55)\"\n fill={accentColor}\n />\n <rect\n x=\"670\"\n y=\"206\"\n width=\"47\"\n height=\"194\"\n transform=\"rotate(90 670 206)\"\n fill={accentColor}\n />\n <rect\n x=\"242\"\n y=\"61\"\n width=\"271\"\n height=\"218\"\n transform=\"rotate(90 242 61)\"\n fill={accentColor}\n />\n <rect\n x=\"677\"\n y=\"357\"\n width=\"47\"\n height=\"653\"\n transform=\"rotate(90 677 357)\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame === 4 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect\n x=\"455\"\n y=\"281\"\n width=\"47\"\n height=\"194\"\n transform=\"rotate(90 455 281)\"\n fill={accentColor}\n />\n <rect\n x=\"672\"\n y=\"131\"\n width=\"47\"\n height=\"411\"\n transform=\"rotate(90 672 131)\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame >= 5 ? 1 : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <circle cx=\"360\" cy=\"215\" r=\"41\" fill={accentColor} />\n <path\n d=\"M339.937 218.076L350.044 229.83L381.809 201.915\"\n stroke=\"white\"\n strokeWidth=\"10\"\n strokeOpacity={frame >= 5 ? 1 : 0}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ transition: 'stroke-opacity 0.2s linear' }}\n />\n </g>\n </g>\n\n <filter\n id=\"filter0_f_91_884\"\n x=\"0\"\n y=\"0\"\n width=\"848\"\n height=\"556\"\n filterUnits=\"userSpaceOnUse\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feFlood floodOpacity=\"0\" result=\"BackgroundImageFix\" />\n <feBlend\n mode=\"normal\"\n in=\"SourceGraphic\"\n in2=\"BackgroundImageFix\"\n result=\"shape\"\n />\n <feGaussianBlur\n stdDeviation=\"5\"\n result=\"effect1_foregroundBlur_91_884\"\n />\n </filter>\n </svg>\n </div>\n )\n}\n\nexport function IdCaptureLoadingGraphicMobile({\n width = 428,\n height = 747,\n className,\n}: IdCaptureLoadingGraphicProps) {\n const [frame, setFrame] = useState(0)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 7)\n }, 1000)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n const accentOpacity =\n theme.idCapture?.loadingOverlay?.loadingGraphicAccentOpacity ?? 0.2\n\n return (\n <svg\n className={className}\n width={width}\n height={height}\n viewBox=\"0 0 428 747\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g\n id=\"card\"\n style={{\n transform: `translate(${frame < 1 ? '-500px' : '0'}, 0)`,\n transition: 'transform 0.3s linear',\n }}\n >\n <path\n d=\"M76.5001 181.274C76.5001 176.027 80.7534 171.774 86.0001 171.774L342 171.774C347.247 171.774 351.5 176.027 351.5 181.274L351.5 586C351.5 591.247 347.247 595.5 342 595.5L86.0001 595.5C80.7534 595.5 76.5001 591.247 76.5001 586L76.5001 181.274Z\"\n fill=\"#F3F3F3\"\n stroke=\"#DCDCDC\"\n />\n <mask\n id=\"mask0_29_1815\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"113\"\n y=\"452\"\n width=\"163\"\n height=\"126\"\n >\n <rect\n x=\"113\"\n y=\"577.273\"\n width=\"125\"\n height=\"162\"\n rx=\"3\"\n transform=\"rotate(-90 113 577.273)\"\n fill=\"#D9D9D9\"\n />\n </mask>\n <g mask=\"url(#mask0_29_1815)\">\n <path\n d=\"M214.008 497.796C214.165 497.754 214.33 497.751 214.489 497.788C225.426 500.352 233.24 507.14 233.24 515.098C233.24 523.058 225.395 529.861 214.455 532.423C214.3 532.46 214.138 532.458 213.983 532.418L206.704 530.546L205.204 530.154C204.764 530.039 204.457 529.641 204.457 529.186L204.457 501.028C204.457 500.571 204.766 500.173 205.208 500.059L213.044 498.048L213.817 497.847L214.008 497.796Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M172.144 483.183C172.092 483.102 172.027 483.031 171.955 482.966C155.547 468.233 196.225 478.134 191.447 486.357C183.444 500.161 173.096 484.665 172.144 483.183Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M274.192 433.287C274.528 433.202 274.882 433.292 275.124 433.541C282.444 441.074 286.849 458.59 287.283 460.373C287.308 460.479 287.314 460.558 287.305 460.667C287.111 462.898 284.971 490.135 294.285 506.502C295.735 509.05 293.703 521.155 293.593 521.803C293.589 521.823 293.587 521.84 293.585 521.861L291.51 541.224C291.502 541.299 291.502 541.364 291.509 541.439C291.65 542.782 292.959 557.13 285.925 568.508C280.203 577.763 281.504 589.995 275.126 596.677C274.887 596.927 274.528 597.02 274.193 596.935L267.003 595.111C255.396 592.147 246.379 582.999 243.588 571.332L243.287 570.043L239.866 555.741L238.936 551.833C238.535 550.186 237.977 548.611 237.262 547.123C236.66 545.877 235.959 544.689 235.158 543.572C234.299 542.37 233.326 541.239 232.252 540.222C229.375 537.488 225.826 535.469 221.832 534.438L215.936 532.921L214.347 532.52L214.218 532.491L206.704 530.544L205.21 530.164C204.767 530.051 204.457 529.652 204.457 529.194L204.457 501.04C204.457 500.584 204.765 500.186 205.207 500.071L213.044 498.046L213.817 497.846L214.198 497.744C214.23 497.736 214.263 497.731 214.297 497.731C214.33 497.731 214.363 497.727 214.395 497.718L215.95 497.302L221.832 495.784C227.3 494.367 231.98 491.088 235.158 486.636C236.918 484.202 238.22 481.411 238.936 478.39L239.795 474.782L243.588 458.891C246.379 447.223 255.396 438.075 267.003 435.112L274.192 433.287Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M214.008 497.796C214.165 497.754 214.33 497.751 214.489 497.788C225.426 500.352 233.24 507.14 233.24 515.098C233.24 523.058 225.395 529.861 214.455 532.423C214.3 532.46 214.138 532.458 213.983 532.418L206.704 530.546L205.204 530.154C204.764 530.039 204.457 529.641 204.457 529.186L204.457 501.028C204.457 500.571 204.766 500.173 205.208 500.059L213.044 498.048L213.817 497.847L214.008 497.796Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M172.144 547.035C172.092 547.117 172.027 547.188 171.955 547.252C155.547 561.986 196.225 552.085 191.447 543.861C183.444 530.057 173.096 545.553 172.144 547.035Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M160.188 480.675C160.188 480.679 160.191 480.682 160.195 480.682C161.452 480.682 162.681 480.754 163.91 480.897C165.026 481.011 169.792 481.512 175.861 482.4C179.224 482.885 182.971 483.511 186.733 484.252C186.765 484.258 186.795 484.26 186.827 484.262C186.893 484.266 186.958 484.296 187.022 484.309C196.192 486.126 205.299 488.682 208.623 492.02C212.401 495.8 215.836 498.835 218.312 502.3C220.803 505.764 222.348 509.644 222.348 515.084C222.348 520.524 220.803 524.404 218.312 527.869C215.836 531.319 212.401 534.368 208.623 538.148C205.277 541.494 196.118 544.055 186.939 545.887C186.92 545.891 186.906 545.893 186.886 545.893C186.867 545.893 186.844 545.895 186.825 545.898C185.646 546.125 184.468 546.338 183.303 546.551C182.817 546.637 182.33 546.723 181.843 546.809C179.782 547.167 177.764 547.482 175.875 547.768C168.946 548.793 163.714 549.294 163.652 549.3C163.651 549.3 163.651 549.3 163.649 549.3C162.519 549.415 161.361 549.472 160.188 549.472C159.888 549.472 159.587 549.472 159.287 549.472C156.581 549.4 153.948 549.028 151.429 548.355C151.314 548.327 151.2 548.298 151.085 548.269C137.116 544.447 126.682 532.035 125.852 517.06C125.809 516.401 125.795 515.757 125.795 515.084C125.795 505.578 129.645 496.974 135.871 490.746C141.238 485.363 148.395 481.756 156.367 480.882C157.624 480.739 158.895 480.668 160.181 480.668C160.185 480.668 160.188 480.671 160.188 480.675Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M191.119 509.673C193.495 509.673 195.413 512.092 195.413 515.084C195.413 518.077 193.495 520.482 191.119 520.482C190.877 520.482 190.861 520.186 191.077 520.077C192.647 519.282 193.753 517.343 193.753 515.084C193.753 512.826 192.647 510.876 191.077 510.079C190.866 509.971 190.883 509.673 191.119 509.673Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M274.264 433.275C274.6 433.189 274.954 433.278 275.199 433.524C296.217 454.568 295.682 514.893 295.68 515.097C295.68 515.103 295.68 515.092 295.68 515.098C295.682 515.302 296.217 575.643 275.184 596.673C274.939 596.917 274.586 597.007 274.251 596.921L267.076 595.097C255.454 592.134 246.437 582.986 243.646 571.318L239.925 555.699L238.994 551.819C238.638 550.318 238.133 548.86 237.499 547.48C237.314 547.078 237.398 546.602 237.715 546.294C245.845 538.394 250.903 527.342 250.903 515.098C250.903 502.851 245.844 491.798 237.711 483.897C237.396 483.591 237.311 483.119 237.493 482.719C238.122 481.341 238.638 479.89 238.994 478.376L239.81 474.983L243.646 458.877C246.437 447.21 255.454 438.061 267.076 435.112L274.264 433.275Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M239.436 476.54C239.609 475.821 240.466 475.529 241.015 476.024C246.147 480.64 257.535 493.254 258.403 515.098C259.367 539.068 245.359 551.601 241.088 554.862C240.535 555.285 239.753 554.982 239.59 554.305L238.994 551.82C238.638 550.319 238.133 548.86 237.499 547.48C237.314 547.079 237.398 546.603 237.715 546.295C245.845 538.394 250.903 527.343 250.903 515.098C250.903 502.852 245.844 491.799 237.711 483.898C237.396 483.592 237.311 483.119 237.493 482.72C238.122 481.342 238.638 479.891 238.994 478.377L239.436 476.54Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M162.007 550.079C167.945 550.079 174.609 548.865 179.507 547.741C180.642 547.481 180.435 545.695 179.275 545.595C171.872 544.959 160.808 542.941 155.401 536.678C149.594 529.951 156.114 524.486 156.114 515.6C156.114 507.554 149.704 500.044 155.401 493.265C160.661 487.005 170.034 484.976 177.145 484.392C178.342 484.293 178.605 482.241 177.431 481.993C172.848 481.025 167.193 480.126 162.007 480.126C137.322 480.126 125.686 489.718 125.686 515.6C125.686 539.171 137.2 550.079 162.007 550.079Z\"\n fill=\"#525252\"\n />\n </g>\n <rect\n x=\"296\"\n y=\"577.273\"\n width=\"390\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 296 577.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"158\"\n y=\"433.273\"\n width=\"245\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 158 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"204\"\n y=\"433.273\"\n width=\"110\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 204 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"204\"\n y=\"303.274\"\n width=\"115\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 204 303.274)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"250\"\n y=\"433.273\"\n width=\"110\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 250 433.273)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"250\"\n y=\"303.274\"\n width=\"115\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 250 303.274)\"\n fill=\"#C1C1C1\"\n />\n <rect\n x=\"111.637\"\n y=\"433.637\"\n width=\"245\"\n height=\"25\"\n rx=\"3\"\n transform=\"rotate(-90 111.637 433.637)\"\n fill=\"#C1C1C1\"\n />\n\n <g\n fillOpacity={frame === 2 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect x=\"200\" y=\"188\" width=\"33\" height=\"118\" fill={accentColor} />\n <rect x=\"108\" y=\"444\" width=\"171\" height=\"136\" fill={accentColor} />\n <rect x=\"108\" y=\"187\" width=\"33\" height=\"247\" fill={accentColor} />\n <rect x=\"293\" y=\"186\" width=\"31\" height=\"394\" fill={accentColor} />\n </g>\n\n <g\n fillOpacity={frame === 3 ? accentOpacity : 0}\n style={{ transition: 'fill-opacity 0.2s linear' }}\n >\n <rect x=\"154\" y=\"185\" width=\"33\" height=\"249\" fill={accentColor} />\n <rect\n x=\"247\"\n y=\"322\"\n width=\"31\"\n height=\"113\"\n rx=\"5\"\n fill={accentColor}\n />\n </g>\n\n <g\n fillOpacity={frame >= 4 ? 1 : 0}\n strokeOpacity={frame >= 4 ? 1 : 0}\n style={{\n transition: 'fill-opacity 0.2s linear, stroke-opacity 0.2s linear',\n }}\n >\n <rect\n x=\"78.5\"\n y=\"171.5\"\n width=\"271\"\n height=\"426\"\n rx=\"2.5\"\n stroke={accentColor}\n strokeWidth=\"5\"\n />\n <circle cx=\"214.5\" cy=\"383.5\" r=\"23.5\" fill={accentColor} />\n <path\n d=\"M203 385.263L208.793 392L227 376\"\n stroke=\"white\"\n strokeWidth=\"5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </g>\n </g>\n\n <g\n id=\"phone\"\n clipPath=\"url(#clip0_29_1778)\"\n style={{\n transform: `translate(${frame < 1 ? '40px' : '0'}, 0)`,\n transition: 'transform 0.3s linear',\n }}\n >\n <rect x=\"154\" y=\"693\" width=\"120\" height=\"5\" rx=\"2.5\" fill=\"#333343\" />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M372.869 156.244H373.495V156.241C376.342 156.241 378.647 158.551 378.647 161.396V234.788C378.647 237.637 376.339 239.944 373.495 239.944H372.869V677.09C372.869 698.895 355.203 716.571 333.411 716.571H94.2366C72.444 716.571 54.7781 698.895 54.7781 677.09V278.699H54.1523C51.3051 278.699 49 276.39 49 273.544V228.052C49 225.203 51.3082 222.897 54.1523 222.897H54.7781V212.047H54.1523C51.3051 212.047 49 209.737 49 206.892V161.399C49 158.551 51.3082 156.244 54.1523 156.244H54.7781V90.4813C54.7781 68.6761 72.444 51 94.2366 51H333.411C355.203 51 372.869 68.6761 372.869 90.4813V156.244ZM98.3077 60.7649H329.34C347.039 60.7649 361.387 75.1214 361.387 92.8311V674.734C361.387 692.444 347.039 706.8 329.34 706.8H98.3077C80.6082 706.8 66.26 692.444 66.26 674.734V92.8311C66.26 75.1214 80.6082 60.7649 98.3077 60.7649Z\"\n fill=\"#333343\"\n />\n <rect x=\"154\" y=\"71\" width=\"120\" height=\"20\" rx=\"10\" fill=\"#333343\" />\n </g>\n\n <defs>\n <clipPath id=\"clip0_29_1778\">\n <rect width=\"428\" height=\"747\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n )\n}\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { OverlayContainer, OverlayImageContainer } from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { IdCaptureModelsContext } from './IdCaptureModelsProvider'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureLoadingOverlayProps } from './IdCaptureLoadingOverlay'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport IdCaptureLoadingGraphic from './IdCaptureLoadingGraphic'\n\nconst legacyInstructionImageUrl = `${DEFAULT_CDN_URL}/WebSDK-Instruction-DL-Capture-3-Portrait.png`\n\nexport const IdCaptureLoadingOverlayDefault = ({\n onDismissed,\n onUserCancel,\n instructions,\n rotateImage = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureLoadingOverlayProps): ReactElement => {\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n IdCaptureModelsContext,\n )\n const {\n cameraReady,\n cameraAccessDenied,\n iphoneContinuityCameraAvailable,\n setIphoneContinuityCameraAllowed,\n } = useContext(CameraStateContext)\n const [dismissed, setDismissed] = useState(false)\n\n assets.instructionImageUrl ||= legacyInstructionImageUrl\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your ID',\n useContinuityCameraText: 'Use your iPhone as a webcam',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Loading guided capture experience...',\n modelsReadyText: 'Guided capture experience ready',\n cameraInitializingText: 'Camera initializing...',\n cameraInitializedText: 'Camera ready',\n continueText: \"Let's Go!\",\n })\n\n useEffect(() => {\n if (modelsReady && cameraReady) return () => null\n\n const t = setTimeout(() => {\n setDismissed(false)\n }, 500)\n\n return () => {\n clearTimeout(t)\n }\n }, [cameraReady, modelsReady])\n\n const imageRef = useRef<HTMLImageElement>(null)\n\n if (dismissed) return <></>\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n let imageStyle = {}\n if (rotateImage) {\n const naturalWidth = imageRef.current?.naturalWidth ?? 0\n const naturalHeight = imageRef.current?.naturalHeight ?? 0\n const scale =\n naturalWidth > naturalHeight ? naturalHeight / naturalWidth : 1\n imageStyle = { transform: `rotate(-90deg) scale(${scale})` }\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <OverlayHeader>\n <StyledGuidanceMessage className={classNames.heading}>\n {verbiage.headingText}\n </StyledGuidanceMessage>\n </OverlayHeader>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <StyledOverlayImageContainer\n className={classNames.imageContainer}\n style={{ pointerEvents: 'none' }}\n >\n {assets?.instructionImageUrl &&\n assets.instructionImageUrl !== legacyInstructionImageUrl ? (\n <CustomLoadingGraphic\n ref={imageRef}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n className={classNames.image}\n style={imageStyle}\n />\n ) : (\n <IdCaptureLoadingGraphic className={classNames.image} />\n )}\n </StyledOverlayImageContainer>\n\n {instructions}\n\n <ContinuityCameraCheckboxContainer\n className={classNames.continuityCameraCheckboxContainer}\n >\n {iphoneContinuityCameraAvailable && (\n <ContinuityCameraCheckboxInner\n className={classNames.continuityCameraCheckboxInner}\n >\n <ContinuityCameraCheckbox\n className={classNames.continuityCameraCheckbox}\n id=\"use-continuity-camera\"\n type=\"checkbox\"\n defaultChecked={true}\n onChange={(e) => {\n setIphoneContinuityCameraAllowed(e.target.checked)\n }}\n />\n <label\n htmlFor=\"use-continuity-camera\"\n className={classNames.continuityCameraCheckboxLabel}\n >\n {verbiage.useContinuityCameraText}\n </label>\n </ContinuityCameraCheckboxInner>\n )}\n </ContinuityCameraCheckboxContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <ProgressContainer className={classNames.progressContainer}>\n <ProgressBarBackground className={classNames.progressBackground} />\n <ProgressBar\n $progress={modelDownloadProgress}\n className={classNames.progressBar}\n >\n <ProgressIndicator className={classNames.progressIndicator} />\n </ProgressBar>\n </ProgressContainer>\n\n <LoadingListContainer className={classNames.loadingListContainer}>\n <LoadingList className={classNames.loadingList}>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n cameraReady ? 'done' : 'running'\n }`}\n >\n {cameraReady\n ? verbiage.cameraInitializedText\n : verbiage.cameraInitializingText}\n </LoadingListItem>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n modelsReady ? 'done' : 'running'\n }`}\n >\n {modelsReady\n ? verbiage.modelsReadyText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoadingListItem>\n </LoadingList>\n </LoadingListContainer>\n\n <ContinueButtonContainer className={classNames.continueBtnContainer}>\n {modelsReady && cameraReady && (\n <ContinueButton\n finished\n className={classNames.continueBtn}\n variant=\"positive\"\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {verbiage.continueText}\n </ContinueButton>\n )}\n </ContinueButtonContainer>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst OverlayInner = styled.div`\n height: 100dvh;\n display: flex;\n flex-direction: column;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.backgroundColor ?? '#ecedf3'};\n color: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.textColor ?? 'black'};\n`\n\nconst OverlayHeader = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n padding-bottom: 0;\n`\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 16px 24px;\n margin-top: 16px;\n font-size: 18px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst StyledOverlayImageContainer = styled(OverlayImageContainer)`\n padding: 0 0 100px;\n\n & > svg {\n height: 100%;\n }\n`\n\nconst ContinuityCameraCheckboxContainer = styled.div`\n position: fixed;\n bottom: 120px;\n width: 100dvw;\n display: flex;\n`\n\nconst ContinuityCameraCheckboxInner = styled(GuidanceMessage)`\n padding: 12px 18px;\n margin: 0 auto;\n font-size: 14px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst ContinuityCameraCheckbox = styled.input`\n margin-right: 8px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n display: flex;\n flex-direction: row;\n padding: 15px 25px;\n height: 100px;\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarTextColor ??\n 'white'};\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.idCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100dvw;\n box-sizing: border-box;\n`\n\nconst LoadingListContainer = styled.div`\n display: flex;\n position: relative;\n z-index: 2;\n`\n\nconst LoadingList = styled.ul`\n display: block;\n margin: auto;\n list-style: none;\n padding: 0;\n`\n\nconst LoadingListItem = styled.li`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n padding: 2px 1.25rem 2px 0;\n line-height: 1rem;\n\n &::before {\n content: '';\n display: inline-block;\n height: 1rem;\n min-width: 1rem;\n vertical-align: middle;\n background-size: cover;\n background-repeat: no-repeat;\n margin: auto 0.5rem auto 0;\n }\n\n &.done::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzg1KSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyNEMxOC42Mjc0IDI0IDI0IDE4LjYyNzQgMjQgMTJDMjQgNS4zNzI1OCAxOC42Mjc0IDAgMTIgMEM1LjM3MjU4IDAgMCA1LjM3MjU4IDAgMTJDMCAxOC42Mjc0IDUuMzcyNTggMjQgMTIgMjRaTTE5LjU2NDMgOC4yNzg1MkMxOS45NTQ5IDcuODg3OTkgMTkuOTU0OSA3LjI1NDgzIDE5LjU2NDMgNi44NjQzQzE5LjE3MzggNi40NzM3OCAxOC41NDA2IDYuNDczNzggMTguMTUwMSA2Ljg2NDNMOS40Mjg2NiAxNS41ODU4TDUuODUwMDUgMTIuMDA3MkM1LjQ1OTUzIDExLjYxNjYgNC44MjYzNiAxMS42MTY2IDQuNDM1ODQgMTIuMDA3MkM0LjA0NTMxIDEyLjM5NzcgNC4wNDUzMSAxMy4wMzA5IDQuNDM1ODQgMTMuNDIxNEw4LjcyMTU1IDE3LjcwNzFDOS4xMTIwOCAxOC4wOTc2IDkuNzQ1MjQgMTguMDk3NiAxMC4xMzU4IDE3LjcwNzFMMTkuNTY0MyA4LjI3ODUyWiIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF80OV8zODUiPjxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=');\n }\n\n &.running::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzcwKSI+PG1hc2sgaWQ9InBhdGgtMS1pbnNpZGUtMV80OV8zNzAiIGZpbGw9IndoaXRlIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMuNTE0NzIgMjAuNDg1NUM4LjIwMTAxIDI1LjE3MTggMTUuNzk5IDI1LjE3MTggMjAuNDg1MyAyMC40ODU1QzI1LjE3MTYgMTUuNzk5MiAyNS4xNzE2IDguMjAxMTkgMjAuNDg1MyAzLjUxNDlDMTUuNzk5IC0xLjE3MTM5IDguMjAxMDEgLTEuMTcxMzkgMy41MTQ3MiAzLjUxNDlDLTEuMTcxNTcgOC4yMDExOSAtMS4xNzE1NyAxNS43OTkyIDMuNTE0NzIgMjAuNDg1NVoiLz48L21hc2s+PHBhdGggZD0iTTYuMzk4MTQgMTEuNDU5QzUuODQ1ODYgMTEuNDU5IDUuMzk4MTQgMTEuOTA2NyA1LjM5ODE0IDEyLjQ1OUM1LjM5ODE0IDEzLjAxMTIgNS44NDU4NiAxMy40NTkgNi4zOTgxNCAxMy40NTlWMTEuNDU5Wk0xNy42MDE5IDEzLjQ1OUMxOC4xNTQxIDEzLjQ1OSAxOC42MDE5IDEzLjAxMTIgMTguNjAxOSAxMi40NTlDMTguNjAxOSAxMS45MDY3IDE4LjE1NDEgMTEuNDU5IDE3LjYwMTkgMTEuNDU5VjEzLjQ1OVpNNi4zOTgxNCAxMy40NTlIMTcuNjAxOVYxMS40NTlINi4zOTgxNFYxMy40NTlaTTMuNTE0NzIgMjAuNDg1NUw0LjkyODkzIDE5LjA3MTNMNC45Mjg5MyAxOS4wNzEzTDMuNTE0NzIgMjAuNDg1NVpNMjAuNDg1MyAzLjUxNDlMMTkuMDcxMSA0LjkyOTEyTDE5LjA3MTEgNC45MjkxMkwyMC40ODUzIDMuNTE0OVpNMy41MTQ3MiAzLjUxNDlMNC45Mjg5MyA0LjkyOTEyTDQuOTI4OTMgNC45MjkxMkwzLjUxNDcyIDMuNTE0OVpNMTkuMDcxMSAxOS4wNzEzQzE1LjE2NTggMjIuOTc2NSA4LjgzNDE3IDIyLjk3NjUgNC45Mjg5MyAxOS4wNzEzTDIuMTAwNTEgMjEuODk5N0M3LjU2Nzg0IDI3LjM2NyAxNi40MzIyIDI3LjM2NyAyMS44OTk1IDIxLjg5OTdMMTkuMDcxMSAxOS4wNzEzWk0xOS4wNzExIDQuOTI5MTJDMjIuOTc2MyA4LjgzNDM2IDIyLjk3NjMgMTUuMTY2IDE5LjA3MTEgMTkuMDcxM0wyMS44OTk1IDIxLjg5OTdDMjcuMzY2OCAxNi40MzIzIDI3LjM2NjggNy41NjgwMyAyMS44OTk1IDIuMTAwNjlMMTkuMDcxMSA0LjkyOTEyWk00LjkyODkzIDQuOTI5MTJDOC44MzQxNyAxLjAyMzg3IDE1LjE2NTggMS4wMjM4NyAxOS4wNzExIDQuOTI5MTJMMjEuODk5NSAyLjEwMDY5QzE2LjQzMjIgLTMuMzY2NjUgNy41Njc4NCAtMy4zNjY2NSAyLjEwMDUxIDIuMTAwNjlMNC45Mjg5MyA0LjkyOTEyWk00LjkyODkzIDE5LjA3MTNDMS4wMjM2OSAxNS4xNjYgMS4wMjM2OSA4LjgzNDM2IDQuOTI4OTMgNC45MjkxMkwyLjEwMDUxIDIuMTAwNjlDLTMuMzY2ODMgNy41NjgwMyAtMy4zNjY4MyAxNi40MzIzIDIuMTAwNTEgMjEuODk5N0w0LjkyODkzIDE5LjA3MTNaIiBmaWxsPSJ3aGl0ZSIgbWFzaz0idXJsKCNwYXRoLTEtaW5zaWRlLTFfNDlfMzcwKSIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImNsaXAwXzQ5XzM3MCI+PHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==');\n }\n`\n\nconst ProgressContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n`\n\nconst ProgressBarBackground = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarBackgroundColor ??\n 'var(--idm-color-positive-600)'};\n opacity: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarBackgroundOpacity ??\n 0.75};\n`\n\nconst ProgressBar = styled.span<{ $progress: number }>`\n display: block;\n width: ${(props) => props.$progress}%;\n height: 100%;\n`\n\nconst ProgressIndicator = styled.span`\n display: block;\n height: 100%;\n background: ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarIndicatorColor ??\n 'var(--idm-color-positive-600)'};\n animation: progressBar 3s ease-in-out;\n animation-fill-mode: both;\n\n @keyframes progressBar {\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n }\n`\n\nconst CustomLoadingGraphic = styled.img``\n\nconst ContinueButtonContainer = styled.div`\n display: flex;\n`\n\nconst ContinueButton = styled(LoaderButton)`\n margin: auto;\n white-space: nowrap;\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.idCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n ${(props) =>\n props.theme?.idCapture?.loadingOverlay?.continueBtnBorder\n ? `border: ${props.theme?.idCapture?.loadingOverlay?.continueBtnBorder};`\n : ''}\n`\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { IdCaptureModelsContext } from './IdCaptureModelsProvider'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureLoadingOverlayProps } from './IdCaptureLoadingOverlay'\n\nconst ContinuityCameraCheckboxContainer = styled.div`\n margin-top: 15px;\n margin-bottom: 15px;\n`\n\nconst ContinuityCameraCheckbox = styled.input`\n margin-right: 8px;\n`\n\nexport const IdCaptureLoadingOverlayLegacy = ({\n onDismissed,\n onUserCancel,\n instructions,\n rotateImage = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureLoadingOverlayProps): ReactElement => {\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n IdCaptureModelsContext,\n )\n const {\n cameraReady,\n cameraAccessDenied,\n iphoneContinuityCameraAvailable,\n setIphoneContinuityCameraAllowed,\n } = useContext(CameraStateContext)\n const [dismissed, setDismissed] = useState(false)\n\n assets.instructionImageUrl ||= `${DEFAULT_CDN_URL}/WebSDK-Instruction-DL-Capture-3-Portrait.png`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your ID',\n useContinuityCameraText: 'Use your iPhone as a webcam',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Models warming up...',\n cameraInitializingText: 'Camera initializing...',\n continueText: 'Continue',\n })\n\n useEffect(() => {\n if (modelsReady && cameraReady) return () => null\n\n const t = setTimeout(() => {\n setDismissed(false)\n }, 500)\n\n return () => {\n clearTimeout(t)\n }\n }, [cameraReady, modelsReady])\n\n const imageRef = useRef<HTMLImageElement>(null)\n\n if (dismissed) return <></>\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n let imageStyle = {}\n if (rotateImage) {\n const naturalWidth = imageRef.current?.naturalWidth ?? 0\n const naturalHeight = imageRef.current?.naturalHeight ?? 0\n const scale =\n naturalWidth > naturalHeight ? naturalHeight / naturalWidth : 1\n imageStyle = { transform: `rotate(-90deg) scale(${scale})` }\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <h3 className={classNames.heading}>{verbiage.headingText}</h3>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <OverlayImageContainer\n className={classNames.imageContainer}\n style={{ pointerEvents: 'none' }}\n >\n <img\n ref={imageRef}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n className={classNames.image}\n style={imageStyle}\n />\n </OverlayImageContainer>\n\n {instructions}\n\n <ContinuityCameraCheckboxContainer\n className={classNames.continuityCameraCheckboxContainer}\n >\n {iphoneContinuityCameraAvailable && (\n <>\n <ContinuityCameraCheckbox\n className={classNames.continuityCameraCheckbox}\n id=\"use-continuity-camera\"\n type=\"checkbox\"\n defaultChecked={true}\n onChange={(e) => {\n setIphoneContinuityCameraAllowed(e.target.checked)\n }}\n />\n <label\n htmlFor=\"use-continuity-camera\"\n className={classNames.continuityCameraCheckboxLabel}\n >\n {verbiage.useContinuityCameraText}\n </label>\n </>\n )}\n </ContinuityCameraCheckboxContainer>\n\n <LoaderButton\n className={classNames.continueBtn}\n variant=\"positive\"\n disabled={!cameraReady || !modelsReady}\n finished={modelsReady && cameraReady}\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {cameraReady && modelsReady\n ? verbiage.continueText\n : modelsReady\n ? verbiage.cameraInitializingText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoaderButton>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n","import { CapturedDocument } from '../id_capture/CapturedDocuments'\nimport React, { useRef, useState } from 'react'\nimport { cropToDetectedObjectBox } from '../../lib/utils/cropping'\n\nexport const CapturedDocumentImg = ({\n alt,\n className,\n image,\n}: {\n alt?: string\n className?: string\n image: CapturedDocument\n}) => {\n const [url, setUrl] = useState(image.imageData)\n const [cropped, setCropped] = useState(false)\n const bbox = image.boundingBox\n const imgRef = useRef<HTMLImageElement>(null)\n\n function onLoaded() {\n if (!bbox || cropped) return\n setCropped(true)\n setTimeout(() => {\n setUrl(\n cropToDetectedObjectBox(imgRef.current!, bbox).toDataURL(\n 'image/jpeg',\n 0.95,\n ),\n )\n }, 100)\n }\n\n return (\n <div style={{ position: 'relative' }}>\n <img\n ref={imgRef}\n alt={alt}\n className={className}\n src={url}\n onLoad={onLoaded}\n onClick={() => {\n fetch(image.imageData)\n .then((resp) => resp.blob())\n .then((blob) => {\n const url = URL.createObjectURL(new Blob([blob]))\n const link = document.createElement('a')\n link.href = url\n link.setAttribute('download', `${image.documentType}.jpg`)\n document.body.appendChild(link)\n link.click()\n link.parentNode?.removeChild(link)\n })\n }}\n />\n </div>\n )\n}\n","import React, { ReactElement, useContext } from 'react'\nimport { SubmissionStatus } from '../../contexts/SubmissionContext'\nimport { CapturedDocuments } from './CapturedDocuments'\nimport { PDF417DetectionResult } from '../../lib/barcode/Native'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayImageRow,\n OverlayInner,\n} from '../common/overlay'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { CapturedDocumentImg } from '../common/CapturedDocumentImg'\n\nexport const OverlayInstruction = styled.p`\n font-size: 18px;\n margin: 30px 0;\n`\n\nexport type IdCaptureSuccessClassNames = {\n container?: string\n inner?: string\n heading?: string\n imageContainer?: string\n imageRow?: string\n imageCol?: string\n imageHeading?: string\n imageWrapper?: string\n image?: string\n instruction?: string\n buttonsRow?: string\n retryBtn?: string\n submitBtn?: string\n}\n\nexport type IdCaptureSuccessVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n idCardFrontText?: CustomerSuppliedVerbiage\n idCardBackText?: CustomerSuppliedVerbiage\n passportText?: CustomerSuppliedVerbiage\n instructionText?: CustomerSuppliedVerbiage\n retryText?: CustomerSuppliedVerbiage\n submittingText?: CustomerSuppliedVerbiage\n submitText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureSuccessColors = {\n doneBtn?: LoaderButtonColors\n retryBtn?: LoaderButtonColors\n}\n\nexport type IdCaptureSuccessProps = {\n capturedDocuments: CapturedDocuments\n barcodeResult?: PDF417DetectionResult | null\n onSubmitClick?: () => void\n onRetryClick?: () => void\n\n classNames?: IdCaptureSuccessClassNames\n colors?: IdCaptureSuccessColors\n verbiage?: IdCaptureSuccessVerbiage\n}\n\nexport const IdCaptureSuccess = ({\n capturedDocuments,\n // barcodeResult,\n onSubmitClick,\n onRetryClick,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: IdCaptureSuccessProps): ReactElement => {\n const { submissionStatus } = useContext(SubmissionContext)\n const { idCardFront, idCardBack, passport } = capturedDocuments\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'ID Capture Successful',\n idCardFrontText: 'ID Card Front',\n idCardBackText: 'ID Card Back',\n passportText: 'Passport',\n instructionText: 'Verify the entire ID was captured clearly with no glare.',\n retryText: 'Retry',\n submittingText: 'Submitting...',\n submitText: 'Done',\n })\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <ImagesContainer className={classNames.imageContainer}>\n <ImageRow className={classNames.imageRow}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n {idCardFront && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.idCardFrontText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={idCardFront}\n className={classNames.image}\n alt={verbiage.idCardFrontText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n {idCardBack && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.idCardBackText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={idCardBack}\n className={classNames.image}\n alt={verbiage.idCardBackText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n {passport && (\n <ImageCol className={classNames.imageCol}>\n <ImageHeading className={classNames.imageHeading}>\n {verbiage.passportText}\n </ImageHeading>\n <CapturedImageWrapper className={classNames.imageWrapper}>\n <StyledImage\n image={passport}\n className={classNames.image}\n alt={verbiage.passportText}\n />\n </CapturedImageWrapper>\n </ImageCol>\n )}\n </ImageRow>\n </ImagesContainer>\n\n {/*{barcodeResult && (*/}\n {/* <>*/}\n {/* <h3>Barcode Result</h3>*/}\n {/* <pre>{JSON.stringify(barcodeResult, null, 2)}</pre>*/}\n {/* </>*/}\n {/*)}*/}\n\n <OverlayInstruction className={classNames.instruction}>\n {verbiage.instructionText}\n </OverlayInstruction>\n\n <ButtonsRow className={classNames.buttonsRow}>\n <LoaderButton\n className={classNames.retryBtn}\n variant=\"warning\"\n onClick={onRetryClick}\n colors={colors.retryBtn}\n finished\n >\n {verbiage.retryText}\n </LoaderButton>\n\n <LoaderButton\n className={classNames.submitBtn}\n variant=\"positive\"\n onClick={onSubmitClick}\n disabled={submissionStatus === SubmissionStatus.SUBMITTING}\n colors={colors.doneBtn}\n finished\n >\n {submissionStatus === SubmissionStatus.SUBMITTING\n ? verbiage.submittingText\n : verbiage.submitText}\n </LoaderButton>\n </ButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst Heading = styled.h1`\n margin-bottom: 12px;\n`\n\nconst ImagesContainer = styled(OverlayImageContainer)`\n overflow-y: auto;\n`\n\nconst ImageRow = styled(OverlayImageRow)`\n flex-direction: column;\n`\n\nconst ImageCol = styled.div`\n max-height: none !important;\n`\n\nconst ImageHeading = styled.h3`\n text-align: left;\n margin-top: 24px;\n margin-bottom: 8px;\n font-size: 16px;\n font-weight: normal;\n`\n\nconst CapturedImageWrapper = styled.div`\n border: 1px solid\n ${(props) =>\n props.theme.idCapture?.success?.imageBorderColor ??\n 'var(--idm-color-primary-400)'};\n border-radius: 6px;\n padding: 4px;\n background: white;\n display: flex;\n`\n\nconst StyledImage = styled(CapturedDocumentImg)`\n width: 100%;\n border-radius: 4px;\n`\n","import React, { ReactElement, useCallback, useContext, useEffect } from 'react'\nimport styled from 'styled-components'\nimport { CameraStateContext } from './CameraProvider'\n\nexport const CameraVideoTag = ({\n className,\n}: {\n className?: string\n}): ReactElement => {\n const { videoRef, setVideoLoaded, onVideoUnmounted, cameraRef } =\n useContext(CameraStateContext)\n\n useEffect(\n function notifyCameraProviderOfUnmount() {\n const videoElement = videoRef.current\n if (!videoElement) return\n return () => {\n onVideoUnmounted(videoElement)\n }\n },\n [onVideoUnmounted, videoRef],\n )\n\n useEffect(\n function setVideoLoadedToFalseOnMount() {\n setVideoLoaded(false)\n },\n [setVideoLoaded],\n )\n\n useEffect(\n function attachCameraStreamToVideoTagWhenReady() {\n if (videoRef.current && cameraRef.current?.stream) {\n videoRef.current.srcObject = cameraRef.current.stream\n }\n },\n [cameraRef, videoRef],\n )\n\n const onLoadedData = useCallback(() => {\n setVideoLoaded(true)\n }, [setVideoLoaded])\n\n return (\n <FullscreenVideoTag\n className={className}\n autoPlay\n playsInline\n muted\n ref={videoRef}\n onLoadedData={onLoadedData}\n $isRearFacing={cameraRef.current?.isRearFacing}\n />\n )\n}\n\nexport const FullscreenVideoTag = styled.video<{ $isRearFacing?: boolean }>`\n transform: ${(props) => (props.$isRearFacing ? '' : 'scaleX(-1)')};\n min-width: 100%;\n min-height: 100%;\n width: auto;\n height: auto;\n max-width: 100%;\n max-height: 100%;\n object-fit: cover;\n background: black;\n z-index: -2;\n`\n","import { useEffect, useState } from 'react'\n\nexport function useShowSuccessScreen(\n skipSuccessScreen: boolean | (() => Promise<boolean>),\n successScreenReady: boolean,\n onDoneCallback?: () => void,\n): boolean {\n const [skipSuccessScreenResolvedFalse, setSkipSuccessScreenResolvedFalse] =\n useState(false)\n\n useEffect(() => {\n if (successScreenReady && skipSuccessScreen) {\n if (typeof skipSuccessScreen === 'function') {\n ;(async () => {\n if (await skipSuccessScreen()) {\n onDoneCallback?.()\n } else {\n setSkipSuccessScreenResolvedFalse(true)\n }\n })()\n } else {\n onDoneCallback?.()\n }\n }\n }, [successScreenReady, onDoneCallback, skipSuccessScreen])\n\n return !skipSuccessScreen || skipSuccessScreenResolvedFalse\n}\n","export function setCanvasDimensions(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n) {\n let devicePixelRatio = 1\n if (typeof window !== 'undefined') devicePixelRatio = window.devicePixelRatio\n canvas.width = width * devicePixelRatio\n canvas.height = height * devicePixelRatio\n canvas.style.width = width + 'px'\n canvas.style.height = height + 'px'\n\n canvas.getContext('2d')?.scale(devicePixelRatio, devicePixelRatio)\n}\n\nexport function resetCanvasDimensions(canvas: HTMLCanvasElement) {\n canvas.width = 0\n canvas.height = 0\n canvas.style.width = '0'\n canvas.style.height = '0'\n}\n","import React, {\n ReactElement,\n SyntheticEvent,\n useContext,\n useEffect,\n} from 'react'\nimport { GuideOrientationContext } from '../../contexts/GuideOrientationContext'\nimport { PageContainerDiv } from '../common/Page'\nimport styled, { useTheme } from 'styled-components'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nconst StyledPageContainer = styled(PageContainerDiv)`\n z-index: 1000;\n`\n\nexport const GuidesContainer = styled.div`\n display: flex;\n flex-flow: column nowrap;\n width: 100dvw;\n height: 100dvh;\n`\n\nexport const GuideCenterRow = styled.div`\n position: relative;\n display: flex;\n flex-flow: row nowrap;\n align-items: center;\n justify-items: center;\n box-sizing: border-box;\n max-width: 100%;\n max-height: 100%;\n min-height: 0;\n flex: 1;\n`\n\nexport const GuideRegion = styled.div<{\n $minWidth?: number\n $minHeight?: number\n $maskColor?: string\n}>`\n display: flex;\n flex-direction: column;\n justify-content: end;\n width: 100%;\n position: relative;\n z-index: 1000;\n background: ${(props) =>\n props.$maskColor ??\n props.theme?.idCapture?.guideOverlay?.backgroundColor ??\n 'rgba(0, 0, 0, 0.5)'};\n color: ${(props) =>\n props.theme?.idCapture?.guideOverlay?.textColor ?? 'white'};\n text-align: center;\n ${(props) => (props.$minWidth ? `min-width: ${props.$minWidth}px;` : ``)}\n ${(props) => (props.$minHeight ? `min-height: ${props.$minHeight}px;` : ``)}\n`\n\nexport const Spacer = styled(GuideRegion)`\n display: block;\n width: auto;\n`\n\nexport const GuideCenterRegion = styled.div<{\n $minWidth?: number\n $isMirrored?: boolean\n}>`\n ${(props) => (props.$minWidth ? `min-width: ${props.$minWidth}px;` : ``)}\n ${(props) => (props.$isMirrored ? 'transform: scaleX(-1);' : '')}\n box-sizing: border-box;\n display: flex;\n flex: 1;\n max-height: 100%;\n height: 100%;\n`\n\nexport const GuideCenterBorder = styled.div<{\n $borderWidth: number\n $borderColor?: string\n}>`\n box-sizing: border-box;\n border: ${(props) =>\n `${props.$borderWidth ?? 4}px solid ${props.$borderColor ?? 'white'}`};\n display: flex;\n flex: 1;\n justify-content: center;\n max-height: 100%;\n min-height: 0;\n position: relative;\n`\n\nexport const GuideText = styled.span`\n align-content: center;\n margin-top: 12px;\n margin-bottom: 12px;\n`\n\nexport const GuideImage = styled.img<{\n $width?: number\n $height?: number\n $padding: number\n $visible?: boolean\n}>`\n position: relative;\n z-index: 1;\n padding: ${(props) => props.$padding}px;\n box-sizing: border-box;\n opacity: ${(props) => (props.$visible ? 1 : 0)};\n transition: opacity 0.5s;\n max-height: 100%;\n max-width: 100%;\n`\n\nexport type IdCaptureGuideOverlayClassNames = {\n container?: string\n inner?: string\n dimmingRegion?: string\n dimmingRegionTop?: string\n dimmingRegionLeft?: string\n dimmingRegionRight?: string\n dimmingRegionBottom?: string\n centerRow?: string\n centerRegion?: string\n centerRegionInner?: string\n image?: string\n guideText?: string\n}\n\nexport type IdCaptureGuideOverlayProps = {\n classNames?: IdCaptureGuideOverlayClassNames\n width?: number\n height?: number\n padding?: number\n imagePadding?: number\n imageVisible?: boolean\n borderWidth?: number\n borderColor?: string\n maskColor?: string\n isMirrored?: boolean\n instruction?: string\n portraitGuidesImageUrl?: string\n landscapeGuidesImageUrl?: string\n onClick?: () => void\n}\n\nexport const IdCaptureGuideOverlay = ({\n classNames = {},\n width = 0,\n height = 0,\n padding: userSuppliedPadding,\n imagePadding: userSuppliedImagePadding,\n imageVisible = true,\n borderWidth,\n borderColor,\n maskColor,\n isMirrored = false,\n instruction = '',\n portraitGuidesImageUrl,\n landscapeGuidesImageUrl,\n onClick,\n}: IdCaptureGuideOverlayProps): ReactElement => {\n const {\n orientation,\n wrapperRef,\n wrapperWidth,\n wrapperHeight,\n imageAspectRatio,\n wrapperAspectRatio,\n onImageLoaded: guideOrientationOnImageLoaded,\n setDimensions,\n } = useContext(GuideOrientationContext)\n\n const dispatch = useIdCaptureState()[1]\n\n function onImageLoaded(e: SyntheticEvent) {\n guideOrientationOnImageLoaded(e)\n\n const img = e.target as HTMLImageElement\n dispatch({\n type: 'guideImageLoaded',\n payload: { width: img.naturalWidth, height: img.naturalHeight },\n })\n }\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n\n if (width == 0) width = wrapperWidth\n if (height == 0) height = wrapperHeight\n\n useEffect(() => {\n setDimensions({ width, height })\n }, [height, setDimensions, width])\n\n const padding =\n userSuppliedPadding ??\n (isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 50)\n const paddingAndBorderPx = padding * 2 + borderWidth * 2\n const imgSrc =\n orientation === 'portrait'\n ? portraitGuidesImageUrl\n : landscapeGuidesImageUrl\n\n const imagePadding =\n userSuppliedImagePadding ?? theme.idCapture?.guideBox?.imagePadding ?? 0\n let imageWidth: number | undefined = undefined,\n imageHeight: number | undefined = undefined\n if (imageAspectRatio >= wrapperAspectRatio) {\n imageWidth = wrapperWidth - paddingAndBorderPx\n } else {\n imageHeight = wrapperHeight - paddingAndBorderPx\n }\n\n return (\n <StyledPageContainer\n ref={wrapperRef}\n onClick={onClick}\n className={classNames.container}\n >\n <GuidesContainer className={classNames.inner}>\n <GuideRegion\n $maskColor={maskColor}\n $minHeight={padding}\n className={regionClsx(classNames, 'Top')}\n >\n {instruction !== '' && (\n <GuideText className={classNames.guideText}>\n {instruction}\n </GuideText>\n )}\n </GuideRegion>\n\n <GuideCenterRow className={classNames.centerRow}>\n <Spacer\n $maskColor={maskColor}\n $minWidth={padding}\n className={regionClsx(classNames, 'Left')}\n />\n\n <GuideCenterRegion\n $minWidth={imageWidth}\n $isMirrored={isMirrored}\n className={classNames.centerRegion}\n >\n <GuideCenterBorder\n $borderWidth={borderWidth}\n $borderColor={borderColor}\n className={classNames.centerRegionInner}\n >\n <GuideImage\n src={imgSrc}\n alt=\"\"\n onLoad={onImageLoaded}\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $visible={imageVisible}\n />\n </GuideCenterBorder>\n </GuideCenterRegion>\n\n <Spacer\n $maskColor={maskColor}\n $minWidth={padding}\n className={regionClsx(classNames, 'Right')}\n />\n </GuideCenterRow>\n\n <GuideRegion\n $maskColor={maskColor}\n $minHeight={padding}\n className={regionClsx(classNames, 'Bottom')}\n >\n {instruction !== '' && (\n <GuideText style={{ opacity: 0 }}>{instruction}</GuideText>\n )}\n </GuideRegion>\n </GuidesContainer>\n </StyledPageContainer>\n )\n}\n\nconst regionClsx = (\n classNames: IdCaptureGuideOverlayClassNames,\n which: 'Top' | 'Left' | 'Right' | 'Bottom',\n): string =>\n [classNames.dimmingRegion, classNames[`dimmingRegion${which}`]]\n .filter((v) => v)\n .join(' ')\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport useResizeObserver from 'use-resize-observer'\nimport { GuideOrientationContext } from '../../contexts/GuideOrientationContext'\nimport { PageContainer } from '../common/Page'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport {\n GuideCenterBorder,\n GuideCenterRegion,\n GuideCenterRow,\n GuideImage,\n GuideRegion,\n GuidesContainer,\n GuideText,\n Spacer,\n} from './IdCaptureGuideOverlay'\nimport styled, { useTheme } from 'styled-components'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nconst FlippingImage = styled(GuideImage)<{\n $transitionTime?: number\n $transforms?: string\n}>`\n backface-visibility: hidden;\n transform-style: preserve-3d;\n position: absolute;\n height: 100%;\n top: 0;\n left: 50%;\n transition: transform ${(props) => props.$transitionTime}s;\n transform: translateX(-50%) ${(props) => props.$transforms};\n`\n\nexport type FlipIdPromptAssets = {\n frontPortraitGuidesImageUrl?: string\n frontLandscapeGuidesImageUrl?: string\n backPortraitGuidesImageUrl?: string\n backLandscapeGuidesImageUrl?: string\n}\n\nexport type FlipIdPromptClassNames = {\n container?: string\n inner?: string\n dimmingRegion?: string\n dimmingRegionTop?: string\n dimmingRegionLeft?: string\n dimmingRegionRight?: string\n dimmingRegionBottom?: string\n centerRow?: string\n centerRegion?: string\n image?: string\n guideText?: string\n}\n\nexport type FlipIdPromptVerbiage = {\n instructionText?: CustomerSuppliedVerbiage\n}\n\nexport type FlipIdPromptProps = {\n padding?: number\n imagePadding?: number\n borderWidth?: number\n borderColor?: string\n maskColor?: string\n assets?: FlipIdPromptAssets\n classNames?: FlipIdPromptClassNames\n verbiage?: FlipIdPromptVerbiage\n}\n\nexport const FlipIdPrompt = ({\n padding: userSuppliedPadding,\n imagePadding: userSuppliedImagePadding,\n borderWidth,\n borderColor,\n maskColor,\n assets = {},\n classNames = {},\n verbiage = {},\n}: FlipIdPromptProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const { cameraRef } = useContext(CameraStateContext)\n const theme = useTheme()\n\n assets.frontPortraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.frontLandscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backPortraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Portrait-2.svg`\n assets.backLandscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const instruction = useVerbiage(\n verbiage.instructionText,\n 'Please flip your ID card...',\n )\n\n const padding =\n userSuppliedPadding ?? isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 50\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n const isMirrored = !cameraRef.current?.isRearFacing\n\n const {\n orientation,\n wrapperRef,\n wrapperWidth,\n wrapperHeight,\n imageAspectRatio,\n wrapperAspectRatio,\n onImageLoaded,\n setDimensions,\n } = useContext(GuideOrientationContext)\n\n useEffect(() => {\n setDimensions({ width, height })\n }, [height, setDimensions, width])\n\n const paddingAndBorderPx = padding * 2 + borderWidth * 2\n\n const imagePadding =\n userSuppliedImagePadding ?? theme.idCapture?.guideBox?.imagePadding ?? 0\n let imageWidth: number | undefined = undefined,\n imageHeight: number | undefined = undefined\n if (imageAspectRatio >= wrapperAspectRatio) {\n imageWidth = wrapperWidth - paddingAndBorderPx\n } else {\n imageHeight = wrapperHeight - paddingAndBorderPx\n }\n\n const [transitionTime, setTransitionTime] = useState(1)\n const [rotationAngle, setRotationAngle] = useState(0)\n const frontTransforms = [`rotateY(${rotationAngle}deg)`]\n if (isMirrored) frontTransforms.push('scaleX(-1)')\n const backTransforms = [`rotateY(${180 - rotationAngle}deg)`]\n if (isMirrored) backTransforms.push('scaleX(-1)')\n\n useEffect(() => {\n const doFlip = () => {\n setTransitionTime(1)\n setRotationAngle(180)\n\n setTimeout(() => {\n setTransitionTime(0)\n setRotationAngle(0)\n }, 1500)\n }\n\n setTimeout(doFlip, 250)\n const interval = setInterval(doFlip, 2500)\n\n return () => {\n clearInterval(interval)\n }\n }, [])\n\n return (\n <PageContainer ref={ref} className={classNames.container}>\n <GuidesContainer ref={wrapperRef} className={classNames.inner}>\n <GuideRegion\n $minHeight={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Top')}\n >\n {instruction !== '' && (\n <GuideText className={classNames.guideText}>\n {instruction}\n </GuideText>\n )}\n </GuideRegion>\n\n <GuideCenterRow className={classNames.centerRow}>\n <Spacer\n $minWidth={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Left')}\n />\n\n <GuideCenterRegion>\n <GuideCenterBorder\n $borderWidth={borderWidth}\n $borderColor={borderColor}\n className={classNames.centerRegion}\n >\n <FlippingImage\n src={\n orientation === 'portrait'\n ? assets.frontPortraitGuidesImageUrl\n : assets.frontLandscapeGuidesImageUrl\n }\n alt=\"\"\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $transitionTime={transitionTime}\n $transforms={frontTransforms.join(' ')}\n $visible\n onLoad={onImageLoaded}\n />\n\n <FlippingImage\n src={\n orientation === 'portrait'\n ? assets.backPortraitGuidesImageUrl\n : assets.backLandscapeGuidesImageUrl\n }\n alt=\"\"\n className={classNames.image}\n $width={imageWidth}\n $height={imageHeight}\n $padding={imagePadding}\n $transitionTime={transitionTime}\n $transforms={backTransforms.join(' ')}\n $visible\n />\n </GuideCenterBorder>\n </GuideCenterRegion>\n\n <Spacer\n $minWidth={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Right')}\n />\n </GuideCenterRow>\n\n <GuideRegion\n $minHeight={padding}\n $maskColor={maskColor}\n className={regionClsx(classNames, 'Bottom')}\n >\n {instruction !== '' && (\n <GuideText style={{ opacity: 0 }}>{instruction}</GuideText>\n )}\n </GuideRegion>\n </GuidesContainer>\n </PageContainer>\n )\n}\n\nconst regionClsx = (\n classNames: FlipIdPromptClassNames,\n which: 'Top' | 'Left' | 'Right' | 'Bottom',\n): string =>\n [classNames.dimmingRegion, classNames[`dimmingRegion${which}`]]\n .filter((v) => v)\n .join(' ')\n","import React, { useEffect, useRef } from 'react'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport styled, { useTheme } from 'styled-components'\nimport {\n resetCanvasDimensions,\n setCanvasDimensions,\n} from '../../lib/utils/canvas'\nimport useResizeObserver from 'use-resize-observer'\nimport {\n IdCaptureGuideOverlay,\n IdCaptureGuideOverlayClassNames,\n} from './IdCaptureGuideOverlay'\nimport { FlipIdPrompt } from './FlipIdPrompt'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type IdCaptureFitGuideClassNames = IdCaptureGuideOverlayClassNames & {\n canvasWrapper?: string\n canvas?: string\n}\n\nexport type IdCaptureFitGuideProps = {\n aspectRatio?: number\n maskColor?: string\n borderRadius?: number\n borderColor?: string\n borderWidth?: number\n padding?: number\n imageUrl?: string\n imageVisible?: boolean\n frontImageUrl?: string\n backImageUrl?: string\n isMirrored?: boolean\n instruction?: string\n requestingFlip?: boolean\n classNames?: IdCaptureFitGuideClassNames\n}\n\nexport const IdCaptureFitGuide = ({\n aspectRatio,\n maskColor,\n borderRadius = 33,\n borderColor,\n borderWidth,\n padding,\n imageUrl,\n imageVisible,\n frontImageUrl,\n backImageUrl,\n isMirrored,\n instruction,\n requestingFlip = false,\n classNames = {},\n}: IdCaptureFitGuideProps) => {\n const [{ redrawing, guideImageWidth, guideImageHeight }, dispatch] =\n useIdCaptureState()\n const canvasRef = useRef<HTMLCanvasElement>(null)\n\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.idCapture?.guideBox?.borderWidth ?? 4\n\n if (padding === undefined) {\n padding = isMobile()\n ? theme.idCapture?.guideBox?.mobilePadding ?? 0\n : theme.idCapture?.guideBox?.desktopPadding ?? 0\n }\n\n if (aspectRatio === undefined && guideImageWidth !== 0) {\n aspectRatio = guideImageWidth / guideImageHeight\n }\n\n if (maskColor === undefined) {\n maskColor = theme.idCapture?.guideOverlay?.backgroundColor ?? '#708090'\n }\n\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n\n if (redrawing) {\n resetCanvasDimensions(canvas)\n setTimeout(() => {\n dispatch({ type: 'redrawInProgress' })\n }, 10)\n return\n }\n\n const boundingWidth = wrapperWidth - padding! * 2 - borderWidth! * 2\n const boundingHeight = wrapperHeight - padding! * 2 - borderWidth! * 2\n\n let [rectX, rectY, rectWidth, rectHeight] = [\n padding! + borderWidth!,\n padding! + borderWidth!,\n boundingWidth,\n boundingHeight,\n ]\n\n if (aspectRatio !== undefined) {\n const scaledWidth = boundingHeight * aspectRatio\n const scaledHeight = boundingWidth / aspectRatio\n\n if (scaledWidth < boundingWidth) {\n rectWidth = scaledWidth\n rectX += (boundingWidth - rectWidth) / 2\n } else {\n rectHeight = scaledHeight\n rectY += (boundingHeight - rectHeight) / 2\n }\n }\n\n setCanvasDimensions(canvas, wrapperWidth, wrapperHeight)\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.fillStyle = maskColor!\n ctx.clearRect(0, 0, wrapperWidth, wrapperHeight)\n ctx.fillRect(0, 0, wrapperWidth, wrapperHeight)\n\n // const radius = Math.min(wrapperWidth, wrapperHeight) / 2 - padding!\n ctx.beginPath()\n // ctx.arc(wrapperWidth / 2, wrapperHeight / 2, radius, 0, Math.PI * 2, true) // Hole anticlockwise\n ctx.roundRect(rectX, rectY, rectWidth, rectHeight, borderRadius!)\n\n ctx.lineWidth = borderWidth!\n ctx.strokeStyle = borderColor ?? 'white'\n if (borderColor?.startsWith('var(')) {\n ctx.strokeStyle = getComputedStyle(\n document.documentElement,\n ).getPropertyValue(borderColor.slice(4, -1))\n }\n ctx.stroke()\n\n // make alpha solid (the color doesn't matter)\n ctx.fillStyle = 'rgba(0,0,0,1)'\n\n // change composite mode and fill\n ctx.globalCompositeOperation = 'destination-out'\n ctx.fill()\n\n // reset composite mode to default\n ctx.globalCompositeOperation = 'source-over'\n\n const rectOffsetTop = canvas.offsetTop\n\n dispatch({\n type: 'redrawCompleted',\n payload: {\n guideRectX: rectX,\n guideRectY: rectY,\n guideRectWidth: rectWidth,\n guideRectHeight: rectHeight,\n guideRectOffsetTop: rectOffsetTop,\n },\n })\n }, [\n aspectRatio,\n borderColor,\n borderRadius,\n borderWidth,\n dispatch,\n maskColor,\n padding,\n redrawing,\n wrapperHeight,\n wrapperWidth,\n ])\n\n return (\n <>\n <CanvasWrapper\n ref={wrapperRef}\n $maskColor={maskColor}\n className={classNames.canvasWrapper}\n >\n <Canvas ref={canvasRef} className={classNames.canvas} />\n </CanvasWrapper>\n\n {requestingFlip ? (\n <FlipIdPrompt\n maskColor=\"transparent\"\n borderWidth={0}\n // instruction={instruction}\n classNames={classNames}\n assets={{\n frontLandscapeGuidesImageUrl: frontImageUrl,\n backLandscapeGuidesImageUrl: backImageUrl,\n }}\n />\n ) : (\n <IdCaptureGuideOverlay\n landscapeGuidesImageUrl={imageUrl}\n maskColor=\"transparent\"\n borderWidth={0}\n isMirrored={isMirrored}\n instruction={instruction}\n classNames={classNames}\n imageVisible={imageVisible}\n />\n )}\n </>\n )\n}\n\nconst CanvasWrapper = styled.div<{ $maskColor: string }>`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n flex-grow: 1;\n background-clip: padding-box;\n box-shadow: inset 0 0 0 2px ${(props) => props.$maskColor};\n z-index: -1;\n`\n\nconst Canvas = styled.canvas`\n display: block;\n`\n","import {\n IdCaptureFitGuide,\n IdCaptureFitGuideClassNames,\n} from './IdCaptureFitGuide'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport React, { useContext } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useTranslations } from '../../lib/locales'\nimport { IdCaptureGuideOverlay } from './IdCaptureGuideOverlay'\nimport {\n IdCaptureAssets,\n IdCaptureColors,\n IdCaptureVerbiage,\n} from './IdCapture'\nimport { FlipIdPromptAssets } from './FlipIdPrompt'\n\nexport type IdCaptureGuideType = 'fit' | 'overlay'\n\nexport function IdCaptureGuides({\n guideType = 'fit',\n portraitGuidesOnMobile = false,\n requestingFlip = false,\n flipIdPromptAssets = {},\n classNames = {},\n assets = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: {\n guideType?: IdCaptureGuideType\n portraitGuidesOnMobile?: boolean\n requestingFlip?: boolean\n flipIdPromptAssets?: FlipIdPromptAssets\n classNames?: IdCaptureFitGuideClassNames\n assets?: IdCaptureAssets\n colors?: IdCaptureColors\n verbiage?: IdCaptureVerbiage\n}) {\n const [state] = useIdCaptureState()\n\n const { cameraRef } = useContext(CameraStateContext)\n\n const verbiage = useTranslations(rawVerbiage, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n capturingText: 'Capturing...',\n captureFailedText: 'Capture failed!',\n guidanceSatisfiedText: 'Document detected, hold still...',\n guidanceTooBlurryText: 'Document out of focus – try improving the lighting',\n guidanceNotCenteredText: 'Document is not centered',\n guidanceNotDetectedText: 'Document not detected',\n })\n\n const isMobile = window.innerWidth < window.innerHeight\n const frontImageUrl =\n portraitGuidesOnMobile && isMobile\n ? flipIdPromptAssets?.frontPortraitGuidesImageUrl\n : flipIdPromptAssets?.frontLandscapeGuidesImageUrl\n\n const backImageUrl =\n portraitGuidesOnMobile && isMobile\n ? flipIdPromptAssets?.backPortraitGuidesImageUrl\n : flipIdPromptAssets?.backLandscapeGuidesImageUrl\n\n return (\n <>\n {/* TODO: ternary for flip requests */}\n {guideType === 'overlay' && (\n <IdCaptureGuideOverlay\n classNames={classNames}\n width={state.pageWidth}\n height={state.pageHeight}\n instruction={\n state.captureFailed\n ? verbiage.captureFailedText\n : state.capturing\n ? verbiage?.capturingText\n : verbiage.instructionText\n }\n portraitGuidesImageUrl={assets.portraitGuidesImageUrl}\n landscapeGuidesImageUrl={assets.landscapeGuidesImageUrl}\n isMirrored={!cameraRef.current?.isRearFacing}\n borderColor={\n state.isGoodFrame\n ? colors.guideBoxSatisfiedColor\n : colors.guideBoxUnsatisfiedColor\n }\n imageVisible={\n requestingFlip ||\n !state.documentDetectionThresholdMet ||\n !state.documentInBounds ||\n state.documentTooClose\n }\n />\n )}\n\n {guideType === 'fit' && (\n <IdCaptureFitGuide\n classNames={classNames}\n requestingFlip={requestingFlip}\n instruction={\n state.captureFailed\n ? verbiage.captureFailedText\n : state.capturing\n ? verbiage?.capturingText\n : verbiage.instructionText\n }\n imageUrl={\n portraitGuidesOnMobile && isMobile\n ? assets?.portraitGuidesImageUrl\n : assets?.landscapeGuidesImageUrl\n }\n frontImageUrl={frontImageUrl}\n backImageUrl={backImageUrl}\n isMirrored={!cameraRef.current?.isRearFacing}\n borderColor={\n state.isGoodFrame\n ? colors.guideBoxSatisfiedColor\n : colors.guideBoxUnsatisfiedColor\n }\n imageVisible={\n requestingFlip ||\n !state.documentDetectionThresholdMet ||\n !state.documentInBounds ||\n state.documentTooClose\n }\n />\n )}\n </>\n )\n}\n","import { Spinner } from './spinner'\nimport styled from 'styled-components'\nimport React, { useRef, useState } from 'react'\nimport { error } from '../../lib/utils/logger'\n\nexport type IdCaptureImagePreviewClassNames = {\n container?: string\n text?: string\n imageContainer?: string\n image?: string\n}\n\nexport type IdCaptureImagePreviewProps = {\n classNames?: IdCaptureImagePreviewClassNames\n text?: string\n imageUrl: string\n}\n\nexport const IdCaptureImagePreview = ({\n classNames = {},\n text,\n imageUrl,\n}: IdCaptureImagePreviewProps) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [loaded, setLoaded] = useState(false)\n const [aspectRatio, setAspectRatio] = useState(0)\n\n function onLoad() {\n const aspectRatio =\n imageRef.current!.naturalWidth / imageRef.current!.naturalHeight\n setAspectRatio(aspectRatio)\n setLoaded(true)\n }\n\n function onError() {\n error('failed to load image from url', imageUrl)\n }\n\n return (\n <ImagePreviewWrapper\n className={classNames.container}\n style={{ opacity: loaded ? 1 : 0 }}\n >\n {text && (\n <ImagePreviewText className={classNames.text}>{text}</ImagePreviewText>\n )}\n\n <ImagePreviewImageWrapper\n className={classNames.imageContainer}\n style={{ aspectRatio }}\n >\n <img\n ref={imageRef}\n src={imageUrl}\n alt=\"\"\n className={classNames.image}\n onLoad={onLoad}\n onError={onError}\n />\n </ImagePreviewImageWrapper>\n </ImagePreviewWrapper>\n )\n}\n\nexport type SelfieProgressPreviewClassNames = {\n container?: string\n text?: string\n spinner?: string\n imageContainer?: string\n image?: string\n}\n\nexport type SelfieProgressPreviewProps = {\n classNames?: SelfieProgressPreviewClassNames\n text: string\n imageUrl: string\n}\n\nexport const SelfieProgressPreview = ({\n classNames = {},\n text,\n imageUrl,\n}: SelfieProgressPreviewProps) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [loaded, setLoaded] = useState(false)\n const [aspectRatio, setAspectRatio] = useState(0)\n\n function onLoad() {\n const aspectRatio =\n imageRef.current!.naturalWidth / imageRef.current!.naturalHeight\n setAspectRatio(aspectRatio)\n setLoaded(true)\n }\n\n function onError() {\n error('failed to load image from url', imageUrl)\n }\n\n return (\n <ImagePreviewWrapper\n className={classNames.container}\n style={{ aspectRatio, opacity: loaded ? 1 : 0 }}\n >\n <ImagePreviewText className={classNames.text}>\n <StyledSpinner\n className={classNames.spinner}\n $size={24}\n $color=\"white\"\n $thickness={3}\n />\n {text}\n </ImagePreviewText>\n\n <ImagePreviewImageWrapper className={classNames.imageContainer}>\n <img\n ref={imageRef}\n src={imageUrl}\n alt=\"\"\n className={classNames.image}\n onLoad={onLoad}\n onError={onError}\n />\n </ImagePreviewImageWrapper>\n </ImagePreviewWrapper>\n )\n}\n\nconst StyledSpinner = styled(Spinner)`\n position: relative;\n top: 4px;\n left: -3px;\n margin: 0 3px 0 -12px;\n`\n\nconst ImagePreviewWrapper = styled.div`\n position: absolute;\n display: flex;\n flex-direction: column;\n height: 33%;\n bottom: 12px;\n right: 12px;\n`\n\nconst ImagePreviewText = styled.div`\n display: block;\n position: absolute;\n top: -32px;\n font:\n 14px -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n Helvetica,\n Arial,\n sans-serif,\n 'Apple Color Emoji',\n 'Segoe UI Emoji',\n 'Segoe UI Symbol';\n color: white;\n text-align: center;\n margin: 0 auto;\n width: 100%;\n`\n\nconst ImagePreviewImageWrapper = styled.div`\n position: relative;\n height: calc(100% - 8px);\n padding: 4px;\n border-radius: 4px;\n background: white;\n\n & > img {\n border-radius: 4px;\n width: auto;\n max-height: 100%;\n }\n`\n","import React, {\n createContext,\n Dispatch,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useDebouncedCallback } from 'use-debounce'\nimport { drawToCanvas } from '../common/InvisibleCanvas'\nimport { CameraFeedMode } from '../../lib/camera/CameraFeedWrapper'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\n\nexport type OnDocumentCaptured = (document: CapturedDocument) => void\nexport type OnDocumentUploaded = (document: CapturedDocument) => void\nexport type OnAllDocumentsUploaded = (\n documents: CapturedDocument[],\n) => Promise<void>\n\nexport type CapturedDocument = {\n title?: string\n aspectRatio?: number\n cameraFeedMode?: CameraFeedMode\n instructions?: ReactNode\n documentId?: string\n content?: Blob\n contentUrl?: string\n uploadState?: DocumentCaptureUploadState\n onCaptured?: OnDocumentCaptured\n onUploaded?: OnDocumentUploaded\n}\n\ntype DocumentCaptureUploadState =\n | 'not_started'\n | 'in_progress'\n | 'succeeded'\n | 'failed'\n\nexport type DocumentCaptureState = {\n documents: CapturedDocument[]\n currentDocumentIndex: number\n initialDrawComplete: boolean\n redrawing: boolean\n rectX: number\n rectY: number\n rectWidth: number\n rectHeight: number\n rectOffsetTop: number\n capturing: boolean\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n}\n\nexport type DocumentCaptureStateWithActions = DocumentCaptureState & {\n uploadCapturedDocument: (content: Blob, filetype?: string) => Promise<void>\n}\n\nexport const documentCaptureInitialState = {\n documents: [],\n currentDocumentIndex: 0,\n initialDrawComplete: false,\n redrawing: false,\n capturing: false,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n uploadCapturedDocument: () => Promise.resolve(),\n} satisfies DocumentCaptureStateWithActions\n\nexport const DocumentCaptureStateContext =\n createContext<DocumentCaptureStateWithActions>(documentCaptureInitialState)\n\nexport type DocumentCaptureAction =\n | { type: 'setDocuments'; payload: CapturedDocument[] }\n | {\n type: 'setHooks'\n payload: {\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n }\n }\n | { type: 'redrawRequested' }\n | { type: 'redrawInProgress' }\n | {\n type: 'redrawCompleted'\n payload: {\n rectX: number\n rectY: number\n rectWidth: number\n rectHeight: number\n rectOffsetTop: number\n }\n }\n | { type: 'captureRequested' }\n | { type: 'captureCompleted'; payload: { content: Blob; contentUrl: string } }\n | { type: 'retryCapture' }\n | { type: 'uploadStarted' }\n | { type: 'uploadCompleted'; payload: { documentId: string } }\n | { type: 'uploadFailed' }\n\nexport type DocumentCaptureDispatch = Dispatch<DocumentCaptureAction>\n\nexport const DocumentCaptureDispatchContext =\n createContext<DocumentCaptureDispatch>(() => {})\n\nexport const documentCaptureStateReducer = (\n state: DocumentCaptureState,\n action: DocumentCaptureAction,\n): DocumentCaptureState => {\n switch (action.type) {\n case 'setDocuments':\n return { ...state, documents: action.payload, currentDocumentIndex: 0 }\n\n case 'setHooks':\n return { ...state, ...action.payload }\n\n case 'redrawRequested':\n return {\n ...state,\n redrawing: true,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n }\n\n case 'redrawInProgress':\n return {\n ...state,\n redrawing: false,\n rectX: 0,\n rectY: 0,\n rectWidth: 0,\n rectHeight: 0,\n rectOffsetTop: 0,\n }\n\n case 'redrawCompleted':\n return { ...state, ...action.payload, initialDrawComplete: true }\n\n case 'captureRequested':\n return { ...state, capturing: true }\n\n case 'captureCompleted': {\n const newState = { ...state, capturing: false }\n const index = state.currentDocumentIndex\n newState.documents[index].content = action.payload.content\n newState.documents[index].contentUrl = action.payload.contentUrl\n state.onDocumentCaptured?.(newState.documents[index])\n return newState\n }\n\n case 'retryCapture': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].content = undefined\n newState.documents[index].contentUrl = undefined\n return newState\n }\n\n case 'uploadStarted': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].uploadState = 'in_progress'\n return newState\n }\n\n case 'uploadCompleted': {\n const newState = { ...state }\n\n const index = state.currentDocumentIndex\n newState.documents[index].documentId = action.payload.documentId\n newState.documents[index].uploadState = 'succeeded'\n newState.documents[index].onUploaded?.(newState.documents[index])\n state.onDocumentUploaded?.(newState.documents[index])\n\n if (state.documents.length - 1 > index) {\n newState.currentDocumentIndex += 1\n } else {\n state.onAllDocumentsUploaded?.(newState.documents)\n }\n\n return newState\n }\n\n case 'uploadFailed': {\n const newState = { ...state }\n const index = state.currentDocumentIndex\n newState.documents[index].uploadState = 'failed'\n return newState\n }\n\n default:\n return state\n }\n}\n\nexport const DocumentCaptureStateProvider = ({\n documents = [],\n aspectRatio,\n cameraFeedMode,\n instructions,\n onDocumentCaptured,\n onDocumentUploaded,\n onAllDocumentsUploaded,\n children,\n}: {\n documents?: CapturedDocument[]\n aspectRatio?: number\n cameraFeedMode?: CameraFeedMode\n instructions?: ReactNode\n onDocumentCaptured?: OnDocumentCaptured\n onDocumentUploaded?: OnDocumentUploaded\n onAllDocumentsUploaded?: OnAllDocumentsUploaded\n children: ReactNode\n}) => {\n const [state, dispatch] = useReducer(\n documentCaptureStateReducer,\n documentCaptureInitialState,\n )\n\n const { cameraRef, videoRef } = useContext(CameraStateContext)\n const { uploadDocument } = useContext(SubmissionContext)\n\n const uploadCapturedDocument = useCallback(\n async (content: Blob, filetype?: string) => {\n try {\n dispatch({ type: 'uploadStarted' })\n const documentId = await uploadDocument(content!, { filetype })\n setTimeout(() => {\n dispatch({ type: 'uploadCompleted', payload: { documentId } })\n }, 0)\n } catch (e) {\n dispatch({ type: 'uploadFailed' })\n }\n },\n [uploadDocument],\n )\n\n useEffect(() => {\n const resolvedDocuments: CapturedDocument[] = documents?.length\n ? documents.map((d) => ({\n title: 'Document Capture',\n aspectRatio,\n cameraFeedMode: 'snapToGuides',\n instructions,\n ...d,\n uploadState: 'not_started',\n }))\n : [\n {\n title: 'Document Capture',\n aspectRatio,\n cameraFeedMode: cameraFeedMode ?? 'snapToGuides',\n instructions,\n uploadState: 'not_started',\n },\n ]\n\n dispatch({ type: 'setDocuments', payload: resolvedDocuments })\n\n resolvedDocuments.forEach((d) => {\n if (d.content) {\n d.contentUrl ||= URL.createObjectURL(d.content)\n uploadCapturedDocument(d.content, d.content.type)\n }\n })\n }, [\n aspectRatio,\n cameraFeedMode,\n documents,\n instructions,\n uploadCapturedDocument,\n ])\n\n useEffect(() => {\n dispatch({\n type: 'setHooks',\n payload: {\n onDocumentCaptured,\n onDocumentUploaded,\n onAllDocumentsUploaded,\n },\n })\n }, [onDocumentCaptured, onAllDocumentsUploaded, onDocumentUploaded])\n\n const onResize = useDebouncedCallback(() => {\n dispatch({ type: 'redrawRequested' })\n }, 500)\n\n useLayoutEffect(() => {\n if (typeof window === 'undefined') return\n window.addEventListener('resize', onResize)\n return () => {\n window.removeEventListener('resize', onResize)\n }\n }, [onResize])\n\n const videoTag = videoRef.current\n useEffect(() => {\n if (!state.capturing) return\n if (!cameraRef.current) return\n\n function onComplete(content: Blob | null) {\n if (!content) return\n const contentUrl = URL.createObjectURL(content)\n dispatch({\n type: 'captureCompleted',\n payload: { content, contentUrl },\n })\n }\n\n if (typeof ImageCapture !== 'undefined') {\n const tracks = cameraRef.current.stream.getTracks()\n const videoCameraTrack = tracks.find((track) => {\n return track.kind === 'video'\n })\n\n if (videoCameraTrack) {\n const imageCapture = new ImageCapture(videoCameraTrack)\n imageCapture\n .takePhoto()\n .then(onComplete)\n .catch(() => {})\n } else {\n throw new Error('Failed to find a video feed for taking a photo')\n }\n } else if (videoTag) {\n const canvas = document.createElement('canvas')\n drawToCanvas(canvas, videoTag)\n canvas.toBlob(onComplete)\n }\n }, [cameraRef, state.capturing, videoTag])\n\n const stateWithActions = useMemo<DocumentCaptureStateWithActions>(\n () => ({ ...state, uploadCapturedDocument }),\n [state, uploadCapturedDocument],\n )\n\n return (\n <DocumentCaptureStateContext.Provider value={stateWithActions}>\n <DocumentCaptureDispatchContext.Provider value={dispatch}>\n {children}\n </DocumentCaptureDispatchContext.Provider>\n </DocumentCaptureStateContext.Provider>\n )\n}\n\nexport const useDocumentCaptureState = (): [\n DocumentCaptureStateWithActions,\n DocumentCaptureDispatch,\n] => {\n const state = useContext(DocumentCaptureStateContext)\n const dispatch = useContext(DocumentCaptureDispatchContext)\n if (!state || !dispatch)\n throw new Error(\n 'useDocumentCaptureState cannot be used without DocumentCaptureStateProvider',\n )\n\n return [state, dispatch]\n}\n","import React, { useEffect, useRef } from 'react'\nimport styled, { useTheme } from 'styled-components'\nimport useResizeObserver from 'use-resize-observer'\nimport { useDocumentCaptureState } from './DocumentCaptureStateProvider'\nimport {\n resetCanvasDimensions,\n setCanvasDimensions,\n} from '../../lib/utils/canvas'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type DocumentCaptureGuideOverlayClassNames = {\n container?: string\n}\n\nexport type DocumentCaptureGuideOverlayProps = {\n aspectRatio?: number\n borderRadius?: number\n borderColor?: string\n borderWidth?: number\n maskColor: string\n padding?: number\n classNames?: DocumentCaptureGuideOverlayClassNames\n}\n\nexport const DocumentCaptureGuideOverlay = ({\n aspectRatio,\n borderRadius = 25,\n borderColor,\n borderWidth,\n maskColor,\n padding,\n classNames = {},\n}: DocumentCaptureGuideOverlayProps) => {\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const [{ redrawing }, dispatch] = useDocumentCaptureState()\n\n const canvasRef = useRef<HTMLCanvasElement>(null)\n\n const theme = useTheme()\n if (borderWidth === undefined)\n borderWidth = theme.documentCapture?.guideBox?.borderWidth ?? 4\n\n if (padding === undefined) {\n padding = isMobile()\n ? theme.documentCapture?.guideBox?.mobilePadding ?? 0\n : theme.documentCapture?.guideBox?.desktopPadding ?? 0\n }\n\n useEffect(() => {\n const canvas = canvasRef.current\n if (!canvas) return\n\n if (redrawing) {\n resetCanvasDimensions(canvas)\n setTimeout(() => {\n dispatch({ type: 'redrawInProgress' })\n }, 10)\n return\n }\n\n const boundingWidth = wrapperWidth - padding! * 2 - borderWidth! * 2\n const boundingHeight = wrapperHeight - padding! * 2 - borderWidth! * 2\n\n let [rectX, rectY, rectWidth, rectHeight] = [\n padding! + borderWidth!,\n padding! + borderWidth!,\n boundingWidth,\n boundingHeight,\n ]\n\n if (aspectRatio !== undefined) {\n const scaledWidth = boundingHeight * aspectRatio\n const scaledHeight = boundingWidth / aspectRatio\n\n if (scaledWidth < boundingWidth) {\n rectWidth = scaledWidth\n rectX += (boundingWidth - rectWidth) / 2\n } else {\n rectHeight = scaledHeight\n rectY += (boundingHeight - rectHeight) / 2\n }\n }\n\n setCanvasDimensions(canvas, wrapperWidth, wrapperHeight)\n\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n ctx.fillStyle = maskColor\n ctx.clearRect(0, 0, wrapperWidth, wrapperHeight)\n ctx.fillRect(0, 0, wrapperWidth, wrapperHeight)\n\n // const radius = Math.min(wrapperWidth, wrapperHeight) / 2 - padding!\n ctx.beginPath()\n // ctx.arc(wrapperWidth / 2, wrapperHeight / 2, radius, 0, Math.PI * 2, true) // Hole anticlockwise\n ctx.roundRect(rectX, rectY, rectWidth, rectHeight, borderRadius!)\n\n ctx.lineWidth = borderWidth!\n ctx.strokeStyle = borderColor ?? 'white'\n ctx.stroke()\n\n // make alpha solid (the color doesn't matter)\n ctx.fillStyle = 'rgba(0,0,0,1)'\n\n // change composite mode and fill\n ctx.globalCompositeOperation = 'destination-out'\n ctx.fill()\n\n // reset composite mode to default\n ctx.globalCompositeOperation = 'source-over'\n\n const rectOffsetTop = canvas.offsetTop\n\n dispatch({\n type: 'redrawCompleted',\n payload: { rectX, rectY, rectWidth, rectHeight, rectOffsetTop },\n })\n }, [\n aspectRatio,\n borderColor,\n borderRadius,\n borderWidth,\n dispatch,\n maskColor,\n padding,\n redrawing,\n wrapperHeight,\n wrapperWidth,\n ])\n\n return (\n <CanvasWrapper\n ref={wrapperRef}\n className={classNames.container}\n $maskColor={maskColor}\n >\n <Canvas ref={canvasRef} />\n </CanvasWrapper>\n )\n}\n\nconst CanvasWrapper = styled.div<{ $maskColor: string }>`\n flex-grow: 1;\n background-clip: padding-box;\n box-shadow: inset 0 0 0 2px ${(props) => props.$maskColor};\n`\n\nconst Canvas = styled.canvas`\n display: block;\n`\n","import React, { useContext, useEffect, useState } from 'react'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { DocumentCaptureGuideOverlay } from './DocumentCaptureGuideOverlay'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { PageContainer } from '../common/Page'\nimport { useDocumentCaptureState } from './DocumentCaptureStateProvider'\nimport styled, { useTheme } from 'styled-components'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { CameraFeedWrapper } from '../../lib/camera/CameraFeedWrapper'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\n\nexport type DocumentCaptureScreenClassNames = {\n container?: string\n cameraFeedWrapper?: string\n cameraFeed?: string\n previewImage?: string\n captureContainer?: string\n headingRow?: string\n heading?: string\n footerRow?: string\n instructions?: string\n buttonsRow?: string\n retryCameraAccessBtn?: string\n retryCaptureBtn?: string\n uploadBtn?: string\n uploadProgressBtn?: string\n captureBtn?: string\n}\n\nexport type DocumentCaptureScreenVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n loadingBtnText?: CustomerSuppliedVerbiage\n retryCameraAccessBtnText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n capturingBtnText?: CustomerSuppliedVerbiage\n retryCaptureBtnText?: CustomerSuppliedVerbiage\n uploadBtnText?: CustomerSuppliedVerbiage\n uploadingBtnText?: CustomerSuppliedVerbiage\n retryUploadBtnText?: CustomerSuppliedVerbiage\n successBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type DocumentCaptureScreenProps = {\n onCaptureClicked?: () => void\n classNames?: DocumentCaptureScreenClassNames\n verbiage?: DocumentCaptureScreenVerbiage\n}\n\nexport const DocumentCaptureScreen = ({\n onCaptureClicked,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: DocumentCaptureScreenProps) => {\n const [\n {\n documents,\n currentDocumentIndex,\n rectX,\n rectY,\n rectWidth,\n rectHeight,\n rectOffsetTop,\n capturing,\n uploadCapturedDocument,\n },\n dispatch,\n ] = useDocumentCaptureState()\n\n const {\n title,\n aspectRatio,\n cameraFeedMode,\n instructions,\n contentUrl,\n content,\n uploadState,\n } = documents[currentDocumentIndex] ?? {}\n\n const { cameraRef, cameraReady, cameraAccessDenied, requestCameraAccess } =\n useContext(CameraStateContext)\n\n const [cameraAccessRequested, setCameraAccessRequested] = useState(false)\n const cameraAccessNeeded = // we should force the browser to ask for camera access if...\n uploadState === 'not_started' && // we aren't in the middle of uploading a document...\n !content && // and the user hasn't passed a media blob for the current document...\n !cameraAccessRequested && // and we haven't already tried to force a camera request...\n !cameraRef.current?.stream?.active // and we don't already have camera access.\n\n useEffect(\n function requestCameraAccessIfNeeded() {\n if (!cameraAccessNeeded) return\n setCameraAccessRequested(true)\n requestCameraAccess()\n },\n [cameraAccessNeeded, requestCameraAccess],\n )\n\n const theme = useTheme()\n\n const maskColor =\n theme.documentCapture?.guideBox?.maskColor ??\n (cameraFeedMode === 'snapToGuides' ? '#708090' : `rgba(0, 0, 0, 0.5)`)\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: title,\n loadingBtnText: 'Camera initializing...',\n retryCameraAccessBtnText: 'Retry',\n captureBtnText: 'Capture',\n capturingBtnText: 'Capturing...',\n retryCaptureBtnText: 'Retry capture',\n uploadBtnText: 'Upload',\n uploadingBtnText: 'Uploading...',\n retryUploadBtnText: 'Retry',\n successBtnText: 'Upload succeeded!',\n })\n\n function onCaptureClick() {\n dispatch({ type: 'captureRequested' })\n onCaptureClicked?.()\n }\n\n async function onSubmitClick() {\n await uploadCapturedDocument(content!, 'image/jpeg')\n }\n\n return (\n <PageContainer className={`flex ${classNames.container ?? ''}`}>\n <CameraFeedWrapper\n className={classNames.cameraFeedWrapper}\n $mode={cameraFeedMode ?? 'snapToGuides'}\n $x={rectX}\n $y={rectY + rectOffsetTop}\n $w={rectWidth}\n $h={rectHeight}\n >\n {contentUrl ? (\n <PreviewImage\n alt=\"\"\n src={contentUrl}\n className={classNames.previewImage}\n />\n ) : (\n <CameraVideoTag className={classNames.cameraFeed} />\n )}\n </CameraFeedWrapper>\n\n <CaptureContainer className={classNames.captureContainer}>\n <HeadingRow $maskColor={maskColor} className={classNames.headingRow}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n </HeadingRow>\n\n <DocumentCaptureGuideOverlay\n aspectRatio={aspectRatio}\n classNames={classNames}\n maskColor={maskColor}\n />\n\n <FooterRow $maskColor={maskColor} className={classNames.footerRow}>\n {instructions && (\n <Instructions className={classNames.instructions}>\n {instructions}\n </Instructions>\n )}\n <StyledButtonsRow className={classNames.buttonsRow}>\n {cameraAccessDenied ? (\n <LoaderButton\n className={classNames.retryCameraAccessBtn}\n variant=\"negative\"\n finished\n onClick={requestCameraAccess}\n >\n {verbiage.retryCameraAccessBtnText}\n </LoaderButton>\n ) : contentUrl ? (\n <>\n {uploadState === 'not_started' ? (\n <>\n <LoaderButton\n className={classNames.retryCaptureBtn}\n finished\n variant=\"warning\"\n onClick={() => {\n dispatch({ type: 'retryCapture' })\n }}\n >\n {verbiage.retryCaptureBtnText}\n </LoaderButton>\n\n <LoaderButton\n className={classNames.uploadBtn}\n finished\n variant=\"positive\"\n onClick={onSubmitClick}\n >\n {verbiage.uploadBtnText}\n </LoaderButton>\n </>\n ) : (\n <LoaderButton\n className={classNames.uploadProgressBtn}\n finished={uploadState !== 'in_progress'}\n variant={uploadState === 'failed' ? 'negative' : 'positive'}\n onClick={onSubmitClick}\n disabled={['in_progress', 'succeeded'].includes(\n uploadState ?? '',\n )}\n >\n {uploadState === 'succeeded'\n ? verbiage.successBtnText\n : uploadState === 'failed'\n ? verbiage.retryUploadBtnText\n : verbiage.uploadingBtnText}\n </LoaderButton>\n )}\n </>\n ) : (\n <LoaderButton\n className={classNames.captureBtn}\n finished={cameraReady}\n variant=\"primary\"\n onClick={onCaptureClick}\n disabled={!cameraReady || capturing}\n >\n {!cameraReady\n ? verbiage.loadingBtnText\n : capturing\n ? verbiage.capturingBtnText\n : verbiage.captureBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </FooterRow>\n </CaptureContainer>\n </PageContainer>\n )\n}\n\nconst CaptureContainer = styled.div`\n display: flex;\n flex-direction: column;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: var(--app-height);\n`\n\nconst HeadingRow = styled.div<{ $maskColor: string }>`\n background: ${(props) => props.$maskColor};\n text-align: center;\n color: white;\n`\n\nconst Heading = styled.h1`\n font-size: 22px;\n`\n\nconst FooterRow = styled.div<{ $maskColor: string }>`\n background: ${(props) => props.$maskColor};\n display: flex;\n flex-direction: column;\n justify-content: center;\n padding: 0 20px 20px;\n height: auto;\n color: white;\n`\n\nconst Instructions = styled.div`\n max-height: ${(props) =>\n props.theme.documentCapture?.instructions?.maxHeight ?? '8rem'};\n overflow-y: auto;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n padding-top: 20px;\n`\n\nconst PreviewImage = styled.img`\n width: 100%;\n height: 100%;\n object-fit: cover;\n`\n","import React, { useCallback, useEffect, useState } from 'react'\n\nexport function useFileState() {\n const [file, setFile] = useState<File>()\n\n const fileInputOnChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setFile(e.currentTarget?.files?.[0])\n },\n [setFile],\n )\n\n return {\n rawFile: file,\n fileInputOnChange,\n }\n}\n\nexport function useFileDataUrl(file?: File) {\n const [url, setUrl] = useState<string>()\n\n useEffect(() => {\n if (!file) return\n let aborted = false\n const reader = new FileReader()\n reader.onload = () => !aborted && setUrl(reader.result as string)\n reader.readAsDataURL(file)\n return () => {\n aborted = true\n }\n }, [file])\n\n return {\n url,\n }\n}\n\nexport function useResizeMaxEdge({\n rawFile,\n maxEdgePx = 2048, //This is based on \"2K of 2048 x 1080\n}: {\n rawFile?: File\n maxEdgePx?: number\n}) {\n const { url } = useFileDataUrl(rawFile)\n const [resizedImageFile, setResizedImageFile] = useState<string>()\n\n useEffect(() => {\n if (!url) return\n // A flag to prevent out-or-order errors\n let aborted = false\n\n const image = new Image()\n image.onload = async () => {\n if (aborted) return\n\n const { width, height } =\n image.width > image.height\n ? {\n width: maxEdgePx,\n height: (maxEdgePx / image.width) * image.height,\n }\n : {\n width: (maxEdgePx / image.height) * image.width,\n height: maxEdgePx,\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = width\n canvas.height = height\n\n const context = canvas.getContext('2d')\n if (context == null) throw new Error(\"Can't obtain canvas context\")\n context.imageSmoothingQuality = 'high'\n\n context.drawImage(\n image, // source image\n 0, // source x, y, width, height\n 0,\n image.width,\n image.height,\n 0, // destination x, y, width height\n 0,\n width,\n height,\n )\n\n const dataUrl = canvas.toDataURL('image/jpeg', 0.95)\n if (aborted) return\n setResizedImageFile(dataUrl)\n }\n\n image.src = url\n\n // If one of the props changes before the resize completes then\n // abort in case this run completes after a subsequent one and\n // overwrites the result.\n return () => {\n aborted = true\n }\n }, [maxEdgePx, url])\n\n return {\n resizedImageFile,\n }\n}\n","import React, { ReactElement, useEffect, useRef, useState } from 'react'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n OverlayContainer,\n OverlayImageRow,\n OverlayInner,\n} from '../common/overlay'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport {\n allowedImageCountForOption,\n IdCaptureRequirementOption,\n requiredImageCountForOption,\n} from '../id_capture/IdCaptureRequirementOption'\nimport { DocumentCaptureWizard } from '../document_capture/DocumentCaptureWizard'\nimport { CapturedDocument } from '../document_capture/DocumentCaptureStateProvider'\nimport { useFileState, useResizeMaxEdge } from '../../lib/utils/resizeFile'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type IdCaptureFallbackClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n imageContainer?: string\n imageCol?: string\n image?: string\n instruction?: string\n buttonsRow?: string\n captureBtn?: string\n captureMoreBtn?: string\n doneBtn?: string\n}\n\nexport type IdCaptureFallbackColors = {\n captureBtn?: LoaderButtonColors\n captureMoreBtn?: LoaderButtonColors\n doneBtn?: LoaderButtonColors\n}\n\nexport type IdCaptureFallbackVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n descriptionText?: CustomerSuppliedVerbiage\n firstInstructionText?: CustomerSuppliedVerbiage\n secondInstructionText?: CustomerSuppliedVerbiage\n thirdInstructionText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n captureMoreBtnText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type IdCaptureFallbackProps = {\n idCaptureRequirement?: IdCaptureRequirementOption\n onCapture?: (imageData: string) => void\n onFinished?: (images: string[]) => void\n classNames?: IdCaptureFallbackClassNames\n colors?: IdCaptureFallbackColors\n verbiage?: IdCaptureFallbackVerbiage\n silentFallback?: boolean\n}\n\nexport const IdCaptureFallback = ({\n idCaptureRequirement = 'idCardOrPassport',\n onCapture,\n onFinished,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n silentFallback = false,\n}: IdCaptureFallbackProps): ReactElement => {\n const lastResizedFileRef = useRef<string | null>(null)\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [images, setImages] = useState<string[]>([])\n const [documentToCapture, setDocumentToCapture] = useState<\n string | undefined\n >()\n const [useFallback, setUseFallback] = useState<boolean>(silentFallback)\n const allowedImageCount = allowedImageCountForOption(idCaptureRequirement)\n const requiredImageCount = requiredImageCountForOption(idCaptureRequirement)\n const { rawFile, fileInputOnChange } = useFileState()\n const { resizedImageFile } = useResizeMaxEdge({\n rawFile,\n })\n const [isProcessing, setIsProcessing] = useState(false) // helps eliminate some of the flicker as the image processes\n\n const whatToCapture =\n idCaptureRequirement === 'idCard'\n ? 'ID card'\n : idCaptureRequirement === 'passport'\n ? 'passport'\n : idCaptureRequirement === 'idCardOrPassport'\n ? 'ID card or passport'\n : 'ID card and passport'\n\n const firstInstructionText =\n idCaptureRequirement === 'idCard' ||\n idCaptureRequirement === 'idCardAndPassport'\n ? 'Please capture the front of your ID card.'\n : idCaptureRequirement === 'passport'\n ? 'Please capture the ID page of your passport.'\n : 'Please capture the front of your ID card, or the ID page of your passport.'\n\n const secondInstructionText =\n idCaptureRequirement === 'idCardOrPassport'\n ? 'Please capture the back of your ID card, or click Done if submitting a passport.'\n : 'Please capture the back of your ID card.'\n\n const descriptionText = `On-device capture guidance failed, please capture ${\n requiredImageCount > 1 ? 'photos' : ' a photo'\n } of your ${whatToCapture} manually.`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: `We're having some trouble.`,\n descriptionText,\n firstInstructionText,\n secondInstructionText,\n thirdInstructionText: 'Please capture the ID page of your passport.',\n captureBtnText: 'Capture',\n captureMoreBtnText: `Capture ${\n images.length === 2 ? 'ID page of passport' : 'back of ID card'\n }`,\n doneBtnText: 'Done',\n })\n\n useEffect(\n function resetAfterCapturingImage() {\n // we only want to run this IF the file has changed\n // there IS risk in this if we ever capture multiple documents that are the same (from files)\n if (resizedImageFile && resizedImageFile !== lastResizedFileRef.current) {\n lastResizedFileRef.current = resizedImageFile\n setImages((images) => [...images, resizedImageFile])\n onCapture?.(resizedImageFile)\n setDocumentToCapture(undefined)\n setUseFallback(false)\n setIsProcessing(false)\n }\n },\n [onCapture, resizedImageFile],\n )\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n if (!e.target.files?.[0]) return\n\n setDocumentToCapture(undefined)\n setIsProcessing(true)\n fileInputOnChange(e)\n }\n\n const instructionText =\n images.length === 0\n ? verbiage.firstInstructionText\n : images.length === 1\n ? verbiage.secondInstructionText\n : verbiage.thirdInstructionText\n\n if (useFallback) {\n setUseFallback(false)\n setDocumentToCapture(instructionText)\n }\n\n if ((!isMobile() && documentToCapture) || useFallback) {\n return (\n <DocumentCaptureWizard\n documents={[{ title: documentToCapture }]}\n onDocumentCaptured={(document: CapturedDocument) => {\n const imageData = document.contentUrl!\n onCapture?.(imageData)\n // todo: this a hack to address what is probably some sub-optimal coupling - fix\n setTimeout(() => {\n setImages((images) => [...images, imageData])\n setDocumentToCapture(undefined)\n }, 0)\n }}\n />\n )\n }\n\n return (\n <>\n <OverlayContainer className={classNames.container}>\n <StyledOverlayInner className={classNames.inner}>\n {!silentFallback && (\n <>\n <Heading className={classNames.heading}>\n {verbiage.headingText}\n </Heading>\n <Description className={classNames.description}>\n {verbiage.descriptionText}\n </Description>\n </>\n )}\n\n {(images.length > 0 || isProcessing) && (\n <OverlayImageRow className={classNames.imageContainer}>\n {images.map((image, i) => (\n <ImageCol key={i} className={classNames.imageCol}>\n <img src={image} alt=\"\" className={classNames.image} />\n </ImageCol>\n ))}\n </OverlayImageRow>\n )}\n\n {images.length < requiredImageCount && (\n <Instruction className={classNames.instruction}>\n {instructionText}\n </Instruction>\n )}\n\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*\"\n capture=\"environment\"\n onChange={onFileSelected}\n hidden\n />\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n {images.length < allowedImageCount && (\n <LoaderButton\n variant={images.length > 0 ? 'secondary' : 'positive'}\n className={\n images.length > 0\n ? classNames.captureMoreBtn\n : classNames.captureBtn\n }\n colors={\n images.length > 0 ? colors.captureMoreBtn : colors.captureBtn\n }\n finished\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setDocumentToCapture(instructionText)\n }\n }}\n >\n {images.length > 0\n ? verbiage.captureMoreBtnText\n : verbiage.captureBtnText}\n </LoaderButton>\n )}\n\n {images.length >= requiredImageCount && (\n <LoaderButton\n variant=\"positive\"\n className={classNames.doneBtn}\n colors={colors.doneBtn}\n finished\n onClick={() => {\n onFinished?.(images)\n }}\n >\n {verbiage.doneBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </StyledOverlayInner>\n </OverlayContainer>\n </>\n )\n}\n\nconst StyledOverlayInner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst Instruction = styled.p`\n font-weight: bold;\n`\n\nconst ImageCol = styled.div`\n display: flex;\n justify-content: center;\n flex-grow: 1;\n flex-basis: 0;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, {\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react'\nimport {\n IdCapture,\n IdCaptureAssets,\n IdCaptureClassNames,\n IdCaptureColors,\n IdCaptureVerbiage,\n} from './IdCapture'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n IdCaptureLoadingOverlay,\n IdCaptureLoadingOverlayAssets,\n IdCaptureLoadingOverlayClassNames,\n IdCaptureLoadingOverlayColors,\n IdCaptureLoadingOverlayMode,\n IdCaptureLoadingOverlayVerbiage,\n} from './IdCaptureLoadingOverlay'\nimport {\n FlipIdPromptAssets,\n FlipIdPromptClassNames,\n FlipIdPromptVerbiage,\n} from './FlipIdPrompt'\nimport {\n dataUrlToBase64,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport {\n CaptureAttemptMetadata,\n SubmissionStatus,\n} from '../../contexts/SubmissionContext'\nimport { CapturedDocuments, CapturedDocumentType } from './CapturedDocuments'\nimport {\n IdCaptureSuccess,\n IdCaptureSuccessClassNames,\n IdCaptureSuccessColors,\n IdCaptureSuccessVerbiage,\n} from './IdCaptureSuccess'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { PageContainer } from '../common/Page'\nimport {\n IdCaptureModelsContext,\n IdCapturePrediction,\n} from './IdCaptureModelsProvider'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { useTranslations } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { IdCaptureRequirementOption } from './IdCaptureRequirementOption'\nimport { CameraFeedWrapper } from '../../lib/camera/CameraFeedWrapper'\nimport { useIdCaptureState } from './IdCaptureStateProvider'\nimport { IdCaptureGuides, IdCaptureGuideType } from './IdCaptureGuides'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { IdCaptureImagePreview } from '../common/SelfieProgressPreview'\nimport { useTheme } from 'styled-components'\nimport {\n IdCaptureFallback,\n IdCaptureFallbackClassNames,\n IdCaptureFallbackColors,\n IdCaptureFallbackVerbiage,\n} from '../fallback_flows/IdCapture'\nimport { defaultDocumentDetectionThresholds } from '../../lib/models/DocumentDetection'\nimport { defaultFocusThresholds } from '../../lib/models/Focus'\n\nexport type IdCaptureWizardAssets = {\n documentDetectionModelUrl?: string\n focusModelUrl?: string\n loadingOverlay?: IdCaptureLoadingOverlayAssets\n idCardFront?: IdCaptureAssets\n idCardBack?: IdCaptureAssets\n passport?: IdCaptureAssets\n flipIdPrompt?: FlipIdPromptAssets\n}\n\nexport type IdCaptureWizardClassNames = {\n container?: string\n cameraFeed?: string\n loadingOverlay?: IdCaptureLoadingOverlayClassNames\n capture?: IdCaptureClassNames\n flipIdPrompt?: FlipIdPromptClassNames\n success?: IdCaptureSuccessClassNames\n fallback?: IdCaptureFallbackClassNames\n}\n\nexport type IdCaptureWizardColors = IdCaptureColors & {\n loadingOverlay?: IdCaptureLoadingOverlayColors\n success?: IdCaptureSuccessColors\n fallback?: IdCaptureFallbackColors\n}\n\nexport type IdCaptureWizardVerbiage = {\n loadingOverlay?: IdCaptureLoadingOverlayVerbiage\n idCardFront?: IdCaptureVerbiage\n idCardBack?: IdCaptureVerbiage\n passport?: IdCaptureVerbiage\n flipIdPrompt?: FlipIdPromptVerbiage\n success?: IdCaptureSuccessVerbiage\n fallback?: IdCaptureFallbackVerbiage\n}\n\nexport type IdCaptureSubmission = {\n idFrontImage?: string\n idBackImage?: string\n passportImage?: string\n}\n\nexport type IdCaptureWizardProps = {\n onSuccess?: (submission: IdCaptureSubmission) => void\n onExitCapture?: () => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: IdCaptureLoadingOverlayMode\n modelLoadTimeoutMs?: number\n precapturedDocuments?: CapturedDocuments\n captureRequirement?: IdCaptureRequirementOption\n separateIdCardCaptureSequence?: boolean\n autoCaptureEnabled?: boolean\n autoCaptureBarcodeRequired?: 'mobile' | boolean\n barcodeScanningEnabled?: boolean\n idCardAutoCaptureScoreThreshold?: number\n passportAutoCaptureScoreThreshold?: number\n mrzDetectionScoreThreshold?: number\n idCardFocusScoreThreshold?: number\n passportFocusScoreThreshold?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n instructions?: ReactNode\n releaseCameraAccessOnExit?: boolean\n guideType?: IdCaptureGuideType\n portraitGuidesOnMobile?: boolean\n rotateLoadingOverlayImageWhenPortrait?: boolean\n silentFallback?: boolean\n\n assets?: IdCaptureWizardAssets\n classNames?: IdCaptureWizardClassNames\n colors?: IdCaptureWizardColors\n verbiage?: IdCaptureWizardVerbiage\n debugMode?: boolean\n}\n\nexport const IdCaptureWizard = ({\n onSuccess,\n onExitCapture,\n onUserCancel,\n\n loadingOverlayMode = 'default',\n precapturedDocuments,\n captureRequirement = 'idCardOrPassport',\n separateIdCardCaptureSequence = false,\n autoCaptureEnabled = true,\n autoCaptureBarcodeRequired = 'mobile',\n barcodeScanningEnabled = false,\n idCardAutoCaptureScoreThreshold = defaultDocumentDetectionThresholds.idCard,\n passportAutoCaptureScoreThreshold = defaultDocumentDetectionThresholds.passport,\n mrzDetectionScoreThreshold = defaultDocumentDetectionThresholds.mrz,\n idCardFocusScoreThreshold = defaultFocusThresholds.idCard?.mobile,\n passportFocusScoreThreshold = defaultFocusThresholds.passport?.mobile,\n skipSuccessScreen = false,\n instructions,\n releaseCameraAccessOnExit = true,\n guideType = 'fit',\n portraitGuidesOnMobile = false,\n rotateLoadingOverlayImageWhenPortrait = true,\n silentFallback = false,\n\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: IdCaptureWizardProps): ReactElement => {\n const [state, dispatch] = useIdCaptureState()\n const { cameraAccessDenied, releaseCameraAccess } =\n useContext(CameraStateContext)\n const [overlayDismissed, setOverlayDismissed] = useState(false)\n const {\n submissionStatus,\n setIdFrontImage,\n setIdBackImage,\n setPassportImage,\n logIdFrontCaptureAttempt,\n logIdBackCaptureAttempt,\n } = useContext(SubmissionContext)\n const { start, stop, modelError, resetBestFrame } = useContext(\n IdCaptureModelsContext,\n )\n\n useEffect(() => {\n dispatch({\n type: 'configureWizard',\n payload: { captureRequirement, precapturedDocuments },\n })\n }, [captureRequirement, dispatch, precapturedDocuments])\n\n const documentCount = Object.keys(state.capturedDocuments).length\n\n useEffect(() => {\n documentCount && resetBestFrame()\n }, [documentCount, resetBestFrame])\n\n const logCaptureMetadata = useCallback(\n (metadata: CaptureAttemptMetadata) => {\n metadata.operationTime =\n new Date().getTime() -\n (state.operationStartedAt ?? new Date()).getTime()\n\n state.requestedDocumentType === 'idCardBack'\n ? logIdBackCaptureAttempt(metadata)\n : logIdFrontCaptureAttempt(metadata)\n },\n [\n logIdBackCaptureAttempt,\n logIdFrontCaptureAttempt,\n state.operationStartedAt,\n state.requestedDocumentType,\n ],\n )\n\n useEffect(\n function startModelsWhenCapturing() {\n if (!overlayDismissed || state.captureState !== 'capturing') return\n dispatch({ type: 'captureStarted' })\n start()\n return () => {\n stop()\n }\n },\n [dispatch, overlayDismissed, start, state.captureState, stop],\n )\n\n const onPrediction = useCallback(\n (prediction: IdCapturePrediction) => {\n dispatch({ type: 'predictionMade', payload: prediction })\n },\n [dispatch],\n )\n\n const onCapture = useCallback(\n (\n imageData: string,\n width: number,\n height: number,\n documentType: CapturedDocumentType,\n metadata: CaptureAttemptMetadata,\n ) => {\n logCaptureMetadata(metadata)\n dispatch({\n type: 'documentCaptured',\n payload: {\n imageData,\n width,\n height,\n documentType,\n boundingBox: metadata.boundingBox,\n },\n })\n },\n [dispatch, logCaptureMetadata],\n )\n\n const onSubmitClick = useCallback(() => {\n const { idCardFront, idCardBack, passport } = state.capturedDocuments\n\n const idFrontImage =\n idCardFront && dataUrlToBase64Sync(idCardFront.imageData)\n const idBackImage = idCardBack && dataUrlToBase64Sync(idCardBack.imageData)\n const passportImage = passport && dataUrlToBase64Sync(passport.imageData)\n\n idFrontImage && setIdFrontImage(idFrontImage)\n idBackImage && setIdBackImage(idBackImage)\n passportImage && setPassportImage(passportImage)\n\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onSuccess?.({ idFrontImage, idBackImage, passportImage })\n }, 0)\n }, [\n onSuccess,\n releaseCameraAccess,\n releaseCameraAccessOnExit,\n setIdBackImage,\n setIdFrontImage,\n setPassportImage,\n state.capturedDocuments,\n ])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n state.captureState === 'complete',\n onSubmitClick,\n )\n\n const onRetryClick = useCallback(() => {\n dispatch({ type: 'resetWizard' })\n }, [dispatch])\n\n const [attempt, setAttempt] = useState(0)\n const onExit = useCallback(() => {\n setOverlayDismissed(false)\n setAttempt((n) => n + 1)\n dispatch({ type: 'resetWizard' })\n onExitCapture?.()\n }, [dispatch, onExitCapture])\n\n useEffect(() => {\n if (submissionStatus !== SubmissionStatus.READY) {\n releaseCameraAccessOnExit && releaseCameraAccess()\n }\n }, [releaseCameraAccess, releaseCameraAccessOnExit, submissionStatus])\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setOverlayDismissed(false)\n setAttempt((n) => n + 1)\n }\n }, [cameraAccessDenied])\n\n assets.idCardFront ||= {}\n assets.idCardFront.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Portrait-2.svg`\n assets.idCardFront.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.idCardBack ||= {}\n assets.idCardBack.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Portrait-2.svg`\n assets.idCardBack.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n assets.passport ||= {}\n assets.passport.portraitGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-Passport-Front-SVG-Portrait-2.svg`\n assets.passport.landscapeGuidesImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-Passport-Front-SVG-Landscape-2.svg`\n assets.flipIdPrompt ||= {}\n assets.flipIdPrompt.frontPortraitGuidesImageUrl ||=\n assets.idCardFront.portraitGuidesImageUrl\n assets.flipIdPrompt.frontLandscapeGuidesImageUrl ||=\n assets.idCardFront.landscapeGuidesImageUrl\n assets.flipIdPrompt.backPortraitGuidesImageUrl ||=\n assets.idCardBack.portraitGuidesImageUrl\n assets.flipIdPrompt.backLandscapeGuidesImageUrl ||=\n assets.idCardBack.landscapeGuidesImageUrl\n\n const idCaptureVerbiages = {\n idCardFront: useTranslations(verbiage.idCardFront, {\n instructionText: 'Scan the front of ID',\n processingIdCardText: 'ID card front captured.',\n }),\n idCardBack: useTranslations(verbiage.idCardBack, {\n instructionText: 'Scan the back of ID',\n }),\n passport: useTranslations(verbiage.passport, {\n instructionText: 'Scan the ID page of passport',\n }),\n }\n\n const theme = useTheme()\n const [\n { guideRectX, guideRectY, guideRectWidth, guideRectHeight, imageUrl },\n ] = useIdCaptureState()\n\n const idCaptureAssets = assets[\n state.requestedDocumentType as keyof typeof assets\n ] as IdCaptureAssets\n\n const idCaptureVerbiage = idCaptureVerbiages[\n state.requestedDocumentType as keyof typeof idCaptureVerbiages\n ] as IdCaptureVerbiage\n\n useEffect(() => {\n if (separateIdCardCaptureSequence) return\n if (state.captureState === 'requestingFlip') {\n setTimeout(() => {\n dispatch({ type: 'flipRequestCompleted' })\n }, 6000)\n }\n }, [dispatch, separateIdCardCaptureSequence, state.captureState])\n\n const handleCapture = useCallback(\n async (imageData: string) => {\n const base64ImageData = await dataUrlToBase64(imageData)\n dispatch({\n type: 'documentCapturedManually',\n payload: { imageData: base64ImageData },\n })\n },\n [dispatch],\n )\n\n useEffect(() => {}, [])\n\n if (modelError) {\n return (\n <IdCaptureFallback\n idCaptureRequirement={captureRequirement}\n onFinished={onSubmitClick}\n onCapture={handleCapture}\n classNames={classNames.fallback}\n colors={colors.fallback}\n verbiage={verbiage.fallback}\n silentFallback={silentFallback}\n />\n )\n }\n\n return (\n <PageContainer className={`flex ${classNames?.container ?? ''}`}>\n {state.captureState !== 'complete' && (\n <CameraFeedWrapper\n $x={guideRectX}\n $y={guideRectY}\n $w={guideRectWidth}\n $h={guideRectHeight}\n $mode={guideType === 'fit' ? 'snapToGuides' : 'fullscreen'}\n >\n <CameraVideoTag className={classNames?.cameraFeed} />\n </CameraFeedWrapper>\n )}\n\n {overlayDismissed && state.captureState === 'capturing' && (\n <IdCapture\n requiredDocumentType={state.requestedDocumentType}\n autoCaptureEnabled={autoCaptureEnabled}\n idCardDetectionThreshold={idCardAutoCaptureScoreThreshold}\n passportDetectionThreshold={passportAutoCaptureScoreThreshold}\n idCardFocusScoreThreshold={idCardFocusScoreThreshold}\n passportFocusScoreThreshold={passportFocusScoreThreshold}\n mrzDetectionScoreThreshold={mrzDetectionScoreThreshold}\n autoCaptureBarcodeRequired={autoCaptureBarcodeRequired}\n barcodeScanningEnabled={\n barcodeScanningEnabled &&\n state.requestedDocumentType === 'idCardBack'\n }\n onPrediction={onPrediction}\n onCapture={onCapture}\n assets={idCaptureAssets}\n classNames={classNames?.capture}\n colors={colors}\n verbiage={idCaptureVerbiage}\n debugMode={debugMode}\n />\n )}\n\n <IdCaptureGuides\n guideType={guideType}\n portraitGuidesOnMobile={portraitGuidesOnMobile}\n requestingFlip={state.captureState === 'requestingFlip'}\n flipIdPromptAssets={assets?.flipIdPrompt}\n classNames={classNames}\n assets={idCaptureAssets}\n colors={colors}\n verbiage={idCaptureVerbiage}\n />\n\n {!theme.idCapture?.capturePreview?.disabled &&\n state.captureState === 'requestingFlip' &&\n !separateIdCardCaptureSequence &&\n imageUrl && (\n <IdCaptureImagePreview\n classNames={classNames.capture?.imagePreview}\n text={idCaptureVerbiages?.idCardFront?.processingIdCardText}\n imageUrl={imageUrl}\n />\n )}\n\n {state.captureState !== 'complete' && (\n <div id=\"idmission-above-guides-content\" />\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.capture?.exitCaptureBtn}\n />\n\n {!overlayDismissed && (\n <IdCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n instructions={instructions}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onUserCancel={onUserCancel}\n onDismissed={() => {\n setOverlayDismissed(true)\n }}\n rotateImage={\n rotateLoadingOverlayImageWhenPortrait &&\n portraitGuidesOnMobile &&\n window.innerWidth < window.innerHeight\n }\n />\n )}\n\n {state.captureState === 'requestingFlip' &&\n separateIdCardCaptureSequence && (\n <IdCaptureSuccess\n capturedDocuments={state.capturedDocuments}\n classNames={classNames.success}\n onSubmitClick={() => {\n dispatch({ type: 'flipRequestCompleted' })\n }}\n onRetryClick={onRetryClick}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )}\n\n {state.captureState === 'complete' && showSuccessScreen && (\n <IdCaptureSuccess\n capturedDocuments={state.capturedDocuments}\n barcodeResult={state.barcodeResult}\n classNames={classNames.success}\n onSubmitClick={onSubmitClick}\n onRetryClick={onRetryClick}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )}\n </PageContainer>\n )\n}\n","import * as React from 'react'\nimport {\n createContext,\n MutableRefObject,\n ReactElement,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n} from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { error } from '../../lib/utils/logger'\nimport {\n defaultSelfieCaptureModelLoadTimeoutMs,\n Face,\n makeFaceDetectorPrediction,\n useLoadFaceDetector,\n} from '../../lib/models/FaceDetection'\nimport { useFrameLoop } from '../../lib/models/FrameLoop'\n\ntype PredictionHandler = (prediction: Face[]) => void\n\ntype SelfieGuidanceModelsState = {\n start: () => void\n stop: () => void\n onPredictionMade: (handler: PredictionHandler) => void\n canvasRef: MutableRefObject<HTMLCanvasElement | null>\n ready: boolean\n error: Error | null\n modelDownloadProgress: number\n}\n\nexport const SelfieGuidanceModelsContext =\n createContext<SelfieGuidanceModelsState>({\n start: () => null,\n stop: () => null,\n onPredictionMade: () => null,\n canvasRef: { current: null },\n ready: false,\n error: null,\n modelDownloadProgress: 0,\n })\n\nexport type SelfieGuidanceModelsProviderProps = {\n autoStart?: boolean\n children: ReactNode\n throttleMs?: number\n onModelError?: (error: Error) => void\n modelLoadTimeoutMs?: number\n}\n\nexport function SelfieGuidanceModelsProvider({\n autoStart = true,\n children,\n throttleMs,\n onModelError,\n modelLoadTimeoutMs = defaultSelfieCaptureModelLoadTimeoutMs,\n}: SelfieGuidanceModelsProviderProps): ReactElement {\n const { videoRef, videoLoaded, cameraReady } = useContext(CameraStateContext)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const onPredictionHandler = useRef<PredictionHandler>()\n\n const { detector, ready, modelDownloadProgress, modelError } =\n useLoadFaceDetector({ onModelError, modelLoadTimeoutMs })\n\n const { start, stop } = useFrameLoop(\n useCallback(async () => {\n if (\n !videoLoaded ||\n !cameraReady ||\n !ready ||\n modelError ||\n !videoRef.current ||\n !detector.current ||\n !canvasRef.current\n )\n return\n\n const vw = videoRef.current.videoWidth\n const vh = videoRef.current.videoHeight\n const ctx = canvasRef.current.getContext('2d')\n canvasRef.current.width = vw\n canvasRef.current.height = vh\n\n if (ctx && videoRef.current.readyState === 4) {\n ctx.translate(vw, 0)\n ctx.scale(-1, 1)\n ctx.drawImage(videoRef.current, 0, 0, vw, vh)\n\n // Detectors can throw errors, for example when using custom URLs that\n // contain a model that doesn't provide the expected output.\n try {\n const { faces } = makeFaceDetectorPrediction(\n detector.current,\n canvasRef.current,\n )\n onPredictionHandler.current?.(faces)\n } catch (e) {\n error('caught face detection error', e)\n }\n }\n }, [cameraReady, detector, modelError, ready, videoLoaded, videoRef]),\n { throttleMs, autoStart },\n )\n\n const onPredictionMade = useCallback((handler: PredictionHandler) => {\n onPredictionHandler.current = handler\n }, [])\n\n const value = useMemo<SelfieGuidanceModelsState>(\n () => ({\n start,\n stop,\n ready,\n canvasRef,\n onPredictionMade,\n error: modelError,\n modelDownloadProgress,\n }),\n [modelError, modelDownloadProgress, onPredictionMade, ready, start, stop],\n )\n\n return (\n <SelfieGuidanceModelsContext.Provider value={value}>\n <InvisibleCanvas ref={canvasRef} />\n {children}\n </SelfieGuidanceModelsContext.Provider>\n )\n}\n","import { useEffect, useState } from 'react'\n\nexport const useTimeout = (\n durationMs?: number,\n onTimeout?: () => void,\n timeoutAverted?: boolean,\n shouldWaitLonger?: boolean,\n shouldStart: boolean = true,\n) => {\n const [timedOut, setTimedOut] = useState(false)\n const [timeoutStartedAt, setTimeoutStartedAt] = useState<Date | null>()\n\n useEffect(() => {\n if (!durationMs || !shouldStart) return\n\n setTimeoutStartedAt(new Date())\n const timer = setTimeout(() => {\n setTimedOut(true)\n }, durationMs)\n\n return () => {\n if (timer) clearTimeout(timer)\n }\n }, [durationMs, shouldStart])\n\n useEffect(() => {\n if (!timedOut || timeoutAverted) return\n if (!shouldWaitLonger) {\n onTimeout?.()\n return\n }\n\n const t = setTimeout(() => {\n onTimeout?.()\n }, 120000)\n\n return () => {\n clearTimeout(t)\n }\n }, [onTimeout, shouldWaitLonger, timedOut, timeoutAverted])\n\n return { timedOut, timeoutStartedAt }\n}\n","import React, { ReactElement, useEffect, useRef, useState } from 'react'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { DocumentCaptureWizard } from '../document_capture/DocumentCaptureWizard'\nimport { CapturedDocument } from '../document_capture/DocumentCaptureStateProvider'\nimport { useFileState, useResizeMaxEdge } from '../../lib/utils/resizeFile'\nimport { isMobile } from '../../lib/utils/isMobile'\n\nexport type SelfieCaptureFallbackClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n imageContainer?: string\n image?: string\n buttonsRow?: string\n captureBtn?: string\n doneBtn?: string\n retryCaptureBtn?: string\n}\n\nexport type SelfieCaptureFallbackColors = {\n captureBtn?: LoaderButtonColors\n doneBtn?: LoaderButtonColors\n}\n\nexport type SelfieCaptureFallbackVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n descriptionText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n doneBtnLoadingText?: CustomerSuppliedVerbiage\n livenessFailedText?: CustomerSuppliedVerbiage\n livenessFailedReasonText?: CustomerSuppliedVerbiage\n retryButtonText?: CustomerSuppliedVerbiage\n retryCaptureButtonText?: CustomerSuppliedVerbiage\n}\n\nexport type SelfieCaptureFallbackProps = {\n onFinished?: (imageData: string) => void\n onCapture?: (imageData: string) => void\n classNames?: SelfieCaptureFallbackClassNames\n colors?: SelfieCaptureFallbackColors\n verbiage?: SelfieCaptureFallbackVerbiage\n silentFallback?: boolean\n invalidSelfie?: boolean\n guidanceMessage?: string\n}\n\nexport const SelfieCaptureFallback = ({\n onFinished,\n onCapture,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n silentFallback = false,\n invalidSelfie = false,\n guidanceMessage = undefined,\n}: SelfieCaptureFallbackProps): ReactElement => {\n const [image, setImage] = useState<string | null>(null)\n const lastResizedFileRef = useRef<string | null>(null)\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [loading, setLoading] = useState(false)\n const [usingDocumentCapture, setUsingDocumentCapture] = useState(false)\n const { rawFile, fileInputOnChange } = useFileState()\n const { resizedImageFile } = useResizeMaxEdge({\n rawFile: rawFile,\n })\n\n useEffect(\n function resetAfterCapturingImage() {\n // we only want to run this IF the file has changed\n if (resizedImageFile && resizedImageFile !== lastResizedFileRef.current) {\n lastResizedFileRef.current = resizedImageFile\n setImage(resizedImageFile)\n setLoading(true)\n onCapture?.(resizedImageFile)\n onFinished?.(resizedImageFile)\n }\n },\n [resizedImageFile, onCapture, onFinished, loading],\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: `We're having some trouble.`,\n descriptionText: silentFallback\n ? 'Use your device camera to capture your face'\n : 'On-device capture guidance failed, please capture a selfie manually.',\n captureBtnText: 'Capture',\n doneBtnText: 'Done',\n doneBtnLoadingText: 'Verifying...',\n livenessFailedText: 'Live face not detected, please try again',\n livenessFailedReasonText: guidanceMessage,\n retryButtonText: 'Retry',\n retryCaptureButtonText: 'Retry capture',\n })\n\n useEffect(\n function triggerInputWhenInSilentFallbackMode() {\n let fallbackTimeout: NodeJS.Timeout\n if (silentFallback) {\n fallbackTimeout = setTimeout(() => {\n // using the input element, we want to click on it \"immediately\" which is 250ms to allow for even old browsers to finish connecting the input\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setUsingDocumentCapture(true)\n }\n }, 250)\n }\n\n return () => {\n clearTimeout(fallbackTimeout)\n }\n },\n [silentFallback],\n )\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n if (!e.target.files?.[0]) return\n setImage('LOADING') // this is to reduce some of the flicker - it isn't perfect since .readAsDataURL() is slow\n fileInputOnChange(e)\n }\n\n if (\n usingDocumentCapture ||\n (silentFallback && !!invalidSelfie && !image && !isMobile()) // desktop silent fallback - not a very realistic situation\n ) {\n return (\n <DocumentCaptureWizard\n documents={[\n {\n title: invalidSelfie\n ? verbiage.livenessFailedText\n : verbiage.descriptionText,\n },\n ]}\n onDocumentCaptured={(document: CapturedDocument) => {\n const imageData = document.contentUrl!\n onCapture?.(imageData)\n // todo: this a hack to address what is probably some sub-optimal coupling - fix\n setTimeout(() => {\n setImage(imageData)\n setUsingDocumentCapture(false)\n }, 0)\n }}\n />\n )\n }\n\n // todo: JN - we might be able to use the media stream instead if we clone it - as it stands today, we hae to use the camera to support iOS 16 devices\n return (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*\"\n capture=\"user\"\n onChange={onFileSelected}\n hidden\n />\n\n <OverlayContainer className={classNames.container}>\n <StyledOverlayInner className={classNames.inner}>\n {silentFallback ? (\n invalidSelfie && (\n <>\n <Heading className={classNames.heading}>\n {verbiage.livenessFailedText}\n </Heading>\n\n <Description className={classNames.description}>\n {verbiage.livenessFailedReasonText ||\n verbiage.descriptionText}\n </Description>\n </>\n )\n ) : (\n <>\n <Heading className={classNames.heading}>\n {invalidSelfie\n ? verbiage.livenessFailedText\n : verbiage.headingText}\n </Heading>\n\n <Description className={classNames.description}>\n {verbiage.livenessFailedReasonText || verbiage.descriptionText}\n </Description>\n </>\n )}\n\n {image && image !== 'LOADING' && (\n <ImageContainer className={classNames.imageContainer}>\n <img src={image} alt=\"\" className={classNames.image} />\n </ImageContainer>\n )}\n\n {/* todo: JN - this is arguably super gross - should break into two components - 1 for fallback and one for silentFallback*/}\n <StyledButtonsRow className={classNames.buttonsRow}>\n {image && !loading && !isMobile() && (\n <LoaderButton\n className={classNames.retryCaptureBtn}\n finished\n variant=\"warning\"\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n setUsingDocumentCapture(true)\n }\n }}\n >\n {verbiage.retryCaptureButtonText}\n </LoaderButton>\n )}\n <LoaderButton\n variant=\"positive\"\n key={loading ? 'loading-btn' : 'ready-btn'}\n className={!image ? classNames.captureBtn : classNames?.doneBtn}\n colors={!image ? colors.captureBtn : colors?.doneBtn}\n finished={!image ? true : !loading}\n onClick={() => {\n if (isMobile()) {\n fileInput.current?.click()\n } else {\n if (!image) {\n setUsingDocumentCapture(true)\n } else {\n setLoading(true)\n onFinished?.(image)\n }\n }\n }}\n >\n {!image\n ? invalidSelfie\n ? verbiage.retryButtonText\n : verbiage.captureBtnText\n : loading\n ? verbiage.doneBtnLoadingText\n : verbiage.doneBtnText}\n </LoaderButton>\n </StyledButtonsRow>\n </StyledOverlayInner>\n </OverlayContainer>\n </>\n )\n}\n\nconst StyledOverlayInner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst ImageContainer = styled(OverlayImageContainer)`\n margin-top: 32px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, {\n ReactElement,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport useResizeObserver from 'use-resize-observer'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n FaceCaptureGuideOverlay,\n FaceCaptureGuideOverlayClassNames,\n} from '../face_liveness/FaceCaptureGuideOverlay'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { PageContainer } from '../common/Page'\nimport {\n DebugStatsPane,\n ObjectDetectionDebugOverlayDiv,\n SelfieCaptureFaceDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport {\n clearCanvas,\n drawToCanvas,\n InvisibleCanvas,\n} from '../common/InvisibleCanvas'\nimport {\n SelfieCaptureFallback,\n SelfieCaptureFallbackClassNames,\n} from '../fallback_flows/SelfieCapture'\nimport { Face } from '../../lib/models/FaceDetection'\n\ntype State = {\n videoWidth: number\n videoHeight: number\n\n capturing: boolean\n captured: boolean\n captureFailed: boolean\n\n frame: ImageBitmap | null\n faces: Face[]\n faceNotCentered: boolean\n faceLookingAway: boolean\n faceTooClose: boolean\n faceTooFar: boolean\n faceReady: boolean\n faceReadyAt: Date | null\n\n // TODO: remove good frames threshold\n goodFramesCount: number\n goodFramesThreshold: number\n goodFramesThresholdMet: boolean\n}\n\nconst initialState: State = {\n videoWidth: 0,\n videoHeight: 0,\n\n capturing: false,\n captured: false,\n captureFailed: false,\n\n frame: null,\n faces: [],\n faceNotCentered: false,\n faceLookingAway: false,\n faceTooClose: false,\n faceTooFar: false,\n faceReady: false,\n faceReadyAt: null,\n\n goodFramesCount: 0,\n goodFramesThreshold: 1,\n goodFramesThresholdMet: false,\n}\n\ntype Action =\n | { type: 'configure'; payload: { videoWidth: number; videoHeight: number } }\n | { type: 'capturing' }\n | { type: 'captured' }\n | { type: 'captureFailed' }\n | { type: 'facesDetected'; payload: { frame?: ImageBitmap; faces: Face[] } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'configure':\n return {\n ...state,\n videoWidth: action.payload.videoWidth,\n videoHeight: action.payload.videoHeight,\n }\n\n case 'capturing':\n return {\n ...state,\n capturing: true,\n captured: false,\n captureFailed: false,\n }\n\n case 'captured':\n return {\n ...state,\n capturing: false,\n captured: true,\n captureFailed: false,\n }\n\n case 'captureFailed':\n return {\n ...state,\n capturing: false,\n captured: false,\n captureFailed: true,\n }\n\n case 'facesDetected': {\n const { faces } = action.payload\n const face = faces[0]\n\n let faceNotCentered = true,\n faceLookingAway = false,\n faceTooClose = false,\n faceTooFar = false,\n faceReadyAt = state.faceReadyAt,\n goodFramesCount = state.goodFramesCount\n\n if (face) {\n // calculate centroids\n const vCX = state.videoWidth / 2\n const vCY = state.videoHeight / 2\n const fCX = (face.box.xMin + face.box.xMax) / 2\n const fCY = (face.box.yMin + face.box.yMax) / 2\n\n // calculate thresholds\n const vTX = state.videoWidth * 0.125\n const vTY = state.videoHeight * 0.125\n const fTW = face.box.width * 0.2\n const fTH = face.box.height * 0.2\n\n const nose = face.keypoints[2] //.find((k) => k.name === 'noseTip')\n if (nose) {\n faceNotCentered =\n Math.abs(vCX - fCX) > vTX || Math.abs(vCY + 50 - fCY) > vTY\n faceLookingAway =\n Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH\n }\n\n const isMobile = state.videoWidth < state.videoHeight\n\n const tooCloseMultiple = isMobile ? 2 : 4.5\n const tooFarMultiple = isMobile ? 6 : 7\n faceTooClose = face.box.width > state.videoWidth / tooCloseMultiple\n faceTooFar = face.box.width < state.videoWidth / tooFarMultiple\n }\n\n const faceReady =\n !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar\n\n if (!faceReady) {\n faceReadyAt = null\n goodFramesCount = 0\n } else if (!state.faceReady) {\n faceReadyAt = new Date()\n }\n\n return {\n ...state,\n faces,\n faceNotCentered,\n faceLookingAway,\n faceTooClose,\n faceTooFar,\n faceReady,\n faceReadyAt,\n goodFramesCount,\n }\n }\n }\n}\n\nexport type SelfieCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guides?: FaceCaptureGuideOverlayClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n exitCaptureBtn?: string\n fallback?: SelfieCaptureFallbackClassNames\n}\n\nexport type SelfieCaptureColors = {\n guidesUnsatisfiedColor?: string\n guidesSatisfiedColor?: string\n guidanceMessagesSatisfiedBackgroundColor?: string\n guidanceMessagesUnsatisfiedBackgroundColor?: string\n guidanceMessagesSatisfiedTextColor?: string\n guidanceMessagesUnsatisfiedTextColor?: string\n}\n\nexport type SelfieCaptureVerbiage = {\n guidanceHoldStillText?: CustomerSuppliedVerbiage\n guidanceLookStraightText?: CustomerSuppliedVerbiage\n guidanceMoveBackText?: CustomerSuppliedVerbiage\n guidanceMoveForwardText?: CustomerSuppliedVerbiage\n guidanceMoveToCenterText?: CustomerSuppliedVerbiage\n}\n\nexport type SelfieCaptureProps = {\n onGuidanceSatisfied?: () => void\n onGuidanceNotSatisfied?: () => void\n onSelfieCaptured?: (frame: ImageData, face: Face) => void\n onTimeout?: () => void\n onExit?: () => void\n timeoutDurationMs?: number\n guidanceMessage?: string\n guidanceSatisfied?: boolean\n classNames?: SelfieCaptureClassNames\n colors?: SelfieCaptureColors\n verbiage?: SelfieCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const SelfieCapture = ({\n onGuidanceSatisfied,\n onGuidanceNotSatisfied,\n onSelfieCaptured,\n onTimeout,\n onExit,\n timeoutDurationMs = 15000,\n guidanceMessage,\n guidanceSatisfied,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: SelfieCaptureProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const [state, dispatch] = useReducer(reducer, initialState)\n const lastPredictionCanvas = useRef<HTMLCanvasElement | null>(null)\n const { cameraRef, cameraReady, videoRef } = useContext(CameraStateContext)\n const { onPredictionMade, error: guidanceError } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n useEffect(() => {\n if (cameraReady && videoRef.current && videoRef.current.videoWidth !== 0) {\n dispatch({\n type: 'configure',\n payload: {\n videoWidth: videoRef.current.videoWidth,\n videoHeight: videoRef.current.videoHeight,\n },\n })\n }\n }, [cameraReady, videoRef])\n\n useEffect(() => {\n onPredictionMade((prediction) => {\n dispatch({\n type: 'facesDetected',\n payload: { faces: prediction },\n })\n })\n }, [onPredictionMade])\n\n const [captureReady, setCaptureReady] = useState(false)\n useEffect(() => {\n let timer: NodeJS.Timer\n\n if (state.faceReady) {\n onGuidanceSatisfied?.()\n timer = setTimeout(() => {\n setCaptureReady(true)\n }, 1000)\n } else {\n onGuidanceNotSatisfied?.()\n }\n\n return () => {\n if (timer) clearTimeout(timer)\n }\n }, [onGuidanceNotSatisfied, onGuidanceSatisfied, state.faceReady])\n\n useEffect(() => {\n ;(async () => {\n if (\n captureReady &&\n videoRef.current &&\n lastPredictionCanvas.current &&\n state.faces.length > 0\n ) {\n drawToCanvas(lastPredictionCanvas.current, videoRef.current)\n const ctx = lastPredictionCanvas.current.getContext('2d')\n if (!ctx) return\n const imageData = ctx.getImageData(\n 0,\n 0,\n videoRef.current.videoWidth,\n videoRef.current.videoHeight,\n )\n\n onSelfieCaptured?.(imageData, state.faces[0])\n clearCanvas(lastPredictionCanvas.current)\n }\n })()\n }, [captureReady, onSelfieCaptured, state.faces, videoRef])\n\n const { timedOut, timeoutStartedAt } = useTimeout(\n timeoutDurationMs,\n onTimeout,\n )\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: width,\n pageHeight: height,\n videoWidth: state.videoWidth,\n videoHeight: state.videoHeight,\n })\n\n colors.guidesUnsatisfiedColor ||= 'white'\n colors.guidesSatisfiedColor ||= 'green'\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceHoldStillText: 'Hold still for a few seconds...',\n guidanceLookStraightText: 'Look straight into the camera...',\n guidanceMoveBackText: 'Move back...',\n guidanceMoveForwardText: 'Move forward...',\n guidanceMoveToCenterText: 'Move to the center...',\n })\n\n let satisfied = state.faceReady\n if (typeof guidanceSatisfied === 'boolean') satisfied = guidanceSatisfied\n\n guidanceMessage ||= satisfied\n ? verbiage.guidanceHoldStillText\n : state.faceLookingAway\n ? verbiage.guidanceLookStraightText\n : state.faceTooClose\n ? verbiage.guidanceMoveBackText\n : state.faceTooFar\n ? verbiage.guidanceMoveForwardText\n : state.faceNotCentered\n ? verbiage.guidanceMoveToCenterText\n : ''\n\n if (guidanceError) {\n return <SelfieCaptureFallback classNames={classNames.fallback} />\n }\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n <InvisibleCanvas ref={lastPredictionCanvas} />\n\n <FaceCaptureGuideOverlay\n classNames={classNames.guides}\n variant={satisfied ? 'satisfied' : 'unsatisfied'}\n />\n\n {guidanceMessage !== '' && (\n <GuidanceMessageContainer\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n $variant={satisfied ? 'positive' : 'negative'}\n className={classNames.guidanceMessage}\n >\n {guidanceMessage}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && state.faces.length > 0 && (\n <ObjectDetectionDebugOverlayDiv>\n {state.faces.map((face, i) => (\n <SelfieCaptureFaceDebugBox\n key={i}\n face={face}\n scaling={debugScalingDetails}\n color={satisfied ? 'green' : 'red'}\n />\n ))}\n </ObjectDetectionDebugOverlayDiv>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {!state.faceNotCentered ? '✅' : '❌'} Face Centered\n <br />\n {!state.faceTooClose && !state.faceTooFar ? '✅' : '❌'} Face{' '}\n {state.faceTooClose\n ? 'Too Close'\n : state.faceTooFar\n ? 'Too Far'\n : 'Distance Correct'}\n <br />\n {!state.faceLookingAway ? '✅' : '❌'} Face Looking Forward\n <br />\n {state.goodFramesThresholdMet ? '✅' : '❌'} {state.goodFramesCount}{' '}\n Good Frames\n <br />\n {!timedOut ? '✅' : '❌'} Time Remaining:{' '}\n {Math.max(\n 0,\n timeoutDurationMs -\n (new Date().getTime() -\n (timeoutStartedAt ?? new Date()).getTime()),\n )}\n ms\n </DebugStatsPane>\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.exitCaptureBtn}\n />\n </PageContainer>\n )\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { LiveCheckResponse } from '../../contexts/SubmissionContext'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { SelfieCaptureFallback } from '../fallback_flows/SelfieCapture'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\ntype LivenessCheckState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'IN_PROGRESS'\n | 'PASSED'\n | 'FAILED'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n requestState: LivenessCheckState\n requestError: Error | null\n imageUrl: string | null\n faceLive: boolean\n eyeCoveringDetected: boolean\n maskDetected: boolean\n headCoveringDetected: boolean\n phoneDetected: boolean\n timesLivenessCheckFailed: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n requestState: 'CAPTURING',\n requestError: null,\n imageUrl: null,\n faceLive: false,\n eyeCoveringDetected: false,\n maskDetected: false,\n headCoveringDetected: false,\n phoneDetected: false,\n timesLivenessCheckFailed: 0,\n}\n\ntype Action =\n | { type: 'livenessReady'; payload: { frame: ImageData; face: Face } }\n | { type: 'livenessChecking' }\n | {\n type: 'livenessChecked'\n payload: {\n frame?: ImageData\n face?: Face\n imageUrl: string\n response: LiveCheckResponse\n }\n }\n | { type: 'livenessCheckFailed'; payload: { error: Error } }\n\n/** todo: JN - this feels like it should be hoisted up to the wizard because these states of failed and error dovetail into those in the wizard.\n * There may also be some crossing of wires in how error/failed are used.\n */\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'livenessReady': {\n const allowedStates = ['CAPTURING', 'FAILED', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'livenessChecking':\n return { ...state, requestState: 'IN_PROGRESS' }\n\n case 'livenessChecked': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n const faceLive = ['Live Face Detected', 'Approved'].includes(\n resultData.verificationResult,\n )\n const eyeCoveringDetected = resultData.eyeCovering === 'true'\n const maskDetected = resultData.faceMask === 'true'\n const headCoveringDetected = resultData.headCovering === 'true'\n const phoneDetected = resultData.cellPhone === 'true'\n\n const livenessCheckPassed =\n faceLive &&\n !eyeCoveringDetected &&\n !maskDetected &&\n !headCoveringDetected\n const requestState = livenessCheckPassed ? 'PASSED' : 'FAILED'\n\n let timesLivenessCheckFailed = state.timesLivenessCheckFailed\n if (livenessCheckPassed) {\n timesLivenessCheckFailed = 0\n } else {\n timesLivenessCheckFailed += 1\n }\n\n return {\n ...state,\n frame: action.payload.frame ?? null,\n face: action.payload.face ?? null,\n imageUrl: action.payload.imageUrl,\n requestState,\n faceLive,\n eyeCoveringDetected,\n maskDetected,\n headCoveringDetected,\n phoneDetected,\n timesLivenessCheckFailed,\n }\n }\n\n case 'livenessCheckFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type FaceLivenessCaptureClassNames = SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n}\n\nexport type FaceLivenessCaptureColors = SelfieCaptureColors\n\nexport type FaceLivenessCaptureVerbiage = SelfieCaptureVerbiage & {\n guidanceRemoveEyeCoveringsText?: CustomerSuppliedVerbiage\n guidanceRemoveHeadCoveringsText?: CustomerSuppliedVerbiage\n guidanceRemoveMaskText?: CustomerSuppliedVerbiage\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type FaceLivenessCaptureProps = {\n onCapture?: () => void\n onSuccess?: (faceCropImageUrl: string) => void\n onTimeout?: () => void\n onExit?: () => void\n timeoutDurationMs?: number\n silentFallback?: boolean\n classNames?: FaceLivenessCaptureClassNames\n colors?: FaceLivenessCaptureColors\n verbiage?: FaceLivenessCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const FaceLivenessCapture = ({\n onCapture,\n onSuccess,\n onTimeout,\n onExit,\n timeoutDurationMs = 15000,\n silentFallback = false,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode,\n}: FaceLivenessCaptureProps): ReactElement => {\n const { checkLiveness, submissionError } = useContext(SubmissionContext)\n const { error: modelError } = useContext(SelfieGuidanceModelsContext)\n const [state, dispatch] = useReducer(reducer, initialState)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n const theme = useTheme()\n\n const onSelfieCaptured = useCallback(\n (frame: ImageData, face: Face) => {\n onCapture?.()\n dispatch({ type: 'livenessReady', payload: { frame, face } })\n },\n [onCapture],\n )\n\n const { frame, face } = state\n const isReady = state.requestState === 'CAPTURED'\n const isPassed = state.requestState === 'PASSED'\n useEffect(\n function checkLivenessIfPossible() {\n if (!frame || !face || !isReady || submissionError) return\n dispatch({ type: 'livenessChecking' })\n ;(async () => {\n try {\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n const response = await checkLiveness(await dataUrlToBase64(imageUrl))\n\n dispatch({\n type: 'livenessChecked',\n payload: { frame, face, imageUrl, response },\n })\n } catch (e) {\n dispatch({\n type: 'livenessCheckFailed',\n payload: { error: e as Error },\n })\n }\n })()\n },\n [checkLiveness, face, frame, isReady, submissionError],\n )\n\n const onFallbackImageCaptured = useCallback(\n async (imageUrl: string) => {\n dispatch({ type: 'livenessChecking' })\n\n try {\n const imageData = await dataUrlToBase64(imageUrl)\n const response = await checkLiveness(imageData)\n // todo: JN - this feels dirty and is the reason for the todo around line 83 - but is necessary to handle fallback liveness validation\n if (response?.resultData?.verificationResult !== 'Live Face Detected') {\n onTimeout?.()\n }\n dispatch({\n type: 'livenessChecked',\n payload: { imageUrl, response },\n })\n } catch (e) {\n dispatch({\n type: 'livenessCheckFailed',\n payload: { error: e as Error },\n })\n }\n },\n [checkLiveness, onTimeout],\n )\n\n useEffect(\n function callSuccessIfAvailable() {\n if (isPassed && state.imageUrl) onSuccess?.(state.imageUrl)\n },\n [onSuccess, state.imageUrl, isPassed],\n )\n\n useEffect(\n function timeoutOnTooManyLivenessCheckFailures() {\n if (modelError) return\n\n const allowedFailures = 2\n if (state.timesLivenessCheckFailed >= allowedFailures) {\n onTimeout?.()\n }\n },\n [modelError, onTimeout, state.timesLivenessCheckFailed],\n )\n\n useTimeout(\n timeoutDurationMs,\n onTimeout,\n state.requestState === 'PASSED' || !!modelError,\n state.requestState === 'IN_PROGRESS',\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceRemoveEyeCoveringsText:\n 'Please remove your eye coverings (sunglasses, eye patch, etc.)...',\n guidanceRemoveHeadCoveringsText:\n 'Please remove your head coverings (hat, scarf, etc.)...',\n guidanceRemoveMaskText: 'Please remove your mask...',\n progressPreviewText: 'Processing...',\n })\n\n const guidanceMessage = state.eyeCoveringDetected\n ? verbiage.guidanceRemoveEyeCoveringsText\n : state.headCoveringDetected\n ? verbiage.guidanceRemoveHeadCoveringsText\n : state.maskDetected\n ? verbiage.guidanceRemoveMaskText\n : undefined\n\n if (modelError) {\n return (\n <SelfieCaptureFallback\n key={state.timesLivenessCheckFailed}\n onFinished={onFallbackImageCaptured}\n silentFallback={silentFallback}\n invalidSelfie={!!state.timesLivenessCheckFailed}\n guidanceMessage={guidanceMessage}\n />\n )\n }\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={timeoutDurationMs}\n guidanceMessage={guidanceMessage}\n guidanceSatisfied={guidanceMessage ? false : undefined}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n classNames={classNames.imagePreview}\n imageUrl={imageUrl}\n text={verbiage.progressPreviewText ?? ''}\n />\n )}\n </>\n )\n}\n","import React, { ReactElement, useContext, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport {\n OverlayContainer,\n OverlayImageContainer,\n OverlayInner,\n} from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { SelfieCaptureLoadingOverlayProps } from './SelfieCaptureLoadingOverlay'\nimport { MicrophoneAccessDeniedOverlay } from '../camera/MicrophoneAccessDeniedOverlay'\n\nexport const SelfieCaptureLoadingOverlayLegacy = ({\n onDismissed,\n onUserCancel,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: SelfieCaptureLoadingOverlayProps): ReactElement => {\n const { cameraReady, cameraAccessDenied, microphoneAccessDenied } =\n useContext(CameraStateContext)\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n assets.instructionImageUrl ||= `${DEFAULT_CDN_URL}/Selfie-Image-1.png`\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your face',\n removeEyeCoveringsText: 'Remove Sunglasses & Hat',\n avoidExcessiveBacklightingText: 'Avoid Excessive Backlighting',\n continueText: 'Continue',\n cameraInitializingText: 'Camera initializing...',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Models warming up...',\n })\n\n const [dismissed, setDismissed] = useState(false)\n if (dismissed) return <></>\n\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n if (microphoneAccessDenied) {\n return (\n <MicrophoneAccessDeniedOverlay\n assets={assets.microphoneAccessDenied}\n classNames={classNames.microphoneAccessDenied}\n colors={colors.microphoneAccessDenied}\n verbiage={rawVerbiage.microphoneAccessDenied}\n />\n )\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n <h3 className={classNames.heading}>{verbiage.headingText}</h3>\n\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <StyledGuidanceMessage>\n {verbiage.removeEyeCoveringsText}\n <br />\n {verbiage.avoidExcessiveBacklightingText}\n </StyledGuidanceMessage>\n\n <OverlayImageContainer className={classNames.imageContainer}>\n <img\n className={classNames.image}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n />\n </OverlayImageContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <LoaderButton\n variant=\"positive\"\n disabled={!cameraReady || !modelsReady}\n finished={cameraReady && modelsReady}\n className={classNames.continueBtn}\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {cameraReady && modelsReady\n ? verbiage.continueText\n : modelsReady\n ? verbiage.cameraInitializingText\n : modelDownloadProgress >= 100\n ? `${verbiage.modelsWarmingUpText}`\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoaderButton>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 12px 24px;\n font-weight: normal;\n line-height: 1.5;\n margin-bottom: -30px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n flex-direction: column;\n padding-top: 25px;\n`\n","import React, { useEffect, useState } from 'react'\nimport { useTheme } from 'styled-components'\n\nexport function SelfieCaptureLoadingGraphic({\n width = 840,\n height = 740,\n className,\n}: {\n width?: number\n height?: number\n className?: string\n}) {\n const [frame, setFrame] = useState(1)\n\n useEffect(() => {\n const i = setInterval(() => {\n setFrame((n) => (n + 1) % 10)\n }, 750)\n\n return () => {\n clearInterval(i)\n }\n }, [])\n\n const theme = useTheme()\n const accentColor =\n theme.selfieCapture?.loadingOverlay?.loadingGraphicAccentColor ??\n 'var(--idm-color-positive-600)'\n\n return (\n <svg\n width={width}\n height={height}\n className={className}\n viewBox=\"0 0 840 740\"\n fill=\"none\"\n preserveAspectRatio=\"xMidYMax slice\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g clipPath=\"url(#clip0_428_1188)\">\n <mask\n id=\"mask0_428_1188\"\n style={{ maskType: 'alpha' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"840\"\n height=\"740\"\n >\n <rect width=\"840\" height=\"740\" fill=\"#D9D9D9\" />\n </mask>\n\n <g mask=\"url(#mask0_428_1188)\">\n <path\n d=\"M503.781 449.497C491.561 503.154 458.442 541.609 419.561 541.609C380.68 541.609 347.492 503.015 335.272 449.358L344.645 412.916L347.492 402.019H491.561L502.253 443.667L503.225 447.415L503.781 449.497Z\"\n fill=\"#D2D4DA\"\n />\n <path\n d=\"M574.88 244.97C647.073 163.885 598.921 362.155 558.945 338.928C488.709 298.211 574.88 244.97 574.88 244.97Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M816.983 742.838C779.698 781.432 736.86 814.612 689.786 841.127C617.161 882.012 534.399 906.862 446.153 911.027C437.335 911.513 428.448 911.721 419.491 911.721C374.986 911.721 331.731 906.446 290.281 896.519C232.514 882.706 178.358 859.8 129.271 829.397C89.9033 805.033 53.9382 775.948 22 742.838L31.512 705.355C45.8842 649.061 90.2505 605.33 146.837 591.795L153.085 590.337L222.447 573.747L241.401 569.235C249.386 567.292 257.023 564.585 264.244 561.114C270.285 558.199 276.047 554.797 281.463 550.91C287.295 546.745 292.78 542.025 297.71 536.819C310.971 522.867 320.761 505.653 325.76 486.286L333.119 457.688L335.064 449.983L335.202 449.358L344.645 412.916L347.422 402.019H491.491L502.253 443.667L503.225 447.415L503.78 449.497V449.983L505.863 457.757L513.223 486.286C520.097 512.802 535.996 535.5 557.589 550.91C569.393 559.448 582.932 565.765 597.581 569.235L615.078 573.4L692.146 591.795C748.732 605.33 793.099 649.061 807.471 705.355L816.983 742.838Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M503.781 449.497C491.561 503.154 458.442 541.609 419.561 541.609C380.68 541.609 347.492 503.015 335.272 449.358L344.645 412.916L347.492 402.019H491.561L502.253 443.667L503.225 447.415L503.781 449.497Z\"\n fill=\"#DC968D\"\n />\n <path\n d=\"M264.123 244.97C191.93 163.885 240.082 362.155 280.058 338.928C350.294 298.211 264.123 244.97 264.123 244.97Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M586.473 187.324C586.473 193.432 586.126 199.402 585.432 205.371C584.876 210.785 582.446 233.9 578.141 263.331C575.781 279.713 572.726 297.969 569.115 316.294C569.115 316.502 569.115 316.78 568.976 316.988C560.159 361.621 547.731 406.045 531.484 422.219C513.154 440.544 498.435 457.203 481.632 469.211C464.83 481.289 446.014 488.786 419.631 488.786C393.247 488.786 374.431 481.289 357.629 469.211C340.896 457.203 326.107 440.544 307.778 422.219C291.531 405.976 279.103 361.482 270.216 316.918C270.216 316.918 270.216 316.71 270.216 316.641C269.105 310.879 268.063 305.118 267.022 299.426C266.605 297.066 266.189 294.706 265.772 292.346C264.036 282.351 262.509 272.563 261.12 263.401C256.121 229.596 253.691 204.122 253.691 204.122C253.136 198.638 252.858 193.016 252.858 187.324C252.858 185.866 252.858 184.408 252.858 182.951C253.205 169.832 255.01 157.06 258.274 144.843C258.412 144.287 258.551 143.732 258.69 143.177C277.228 75.4294 337.425 24.8271 410.049 20.8011C413.243 20.5928 416.368 20.5234 419.631 20.5234C465.733 20.5234 507.461 39.1956 537.663 69.3904C563.769 95.4205 581.266 130.127 585.501 168.79C586.195 174.899 586.542 181.077 586.542 187.324H586.473Z\"\n fill=\"#FEAEA5\"\n />\n <path\n d=\"M445.867 337.327C445.867 348.849 434.133 358.151 419.622 358.151C405.111 358.151 393.447 348.849 393.447 337.327C393.447 335.939 393.586 334.55 394.002 333.301C396.293 342.88 406.916 350.099 419.622 350.099C432.328 350.099 443.02 342.88 445.312 333.301C445.728 334.62 445.867 335.939 445.867 337.327Z\"\n fill=\"#F7A69C\"\n />\n <path\n d=\"M817.053 743.187C716.586 847.238 575.642 912 419.561 912C263.481 912 122.467 847.238 22.0698 743.118L31.5818 705.704C45.954 649.34 90.3203 605.61 146.906 592.074L222.655 574.027L241.471 569.515C249.942 567.502 258.135 564.517 265.772 560.699C304.237 601.653 358.879 627.267 419.561 627.267C480.244 627.267 534.886 601.653 573.351 560.699C580.988 564.448 589.111 567.502 597.651 569.515L614.106 573.471L692.216 592.074C748.802 605.61 793.168 649.34 807.471 705.704L817.053 743.187Z\"\n fill=\"#6E7174\"\n />\n <path\n d=\"M614.106 573.471C597.165 594.018 534.886 659.058 419.561 663.639C286.671 668.984 226.266 579.441 222.655 574.027L241.471 569.515C249.942 567.502 258.134 564.517 265.772 560.699C304.236 601.653 358.879 627.267 419.561 627.267C480.244 627.267 534.886 601.653 573.35 560.699C580.988 564.448 589.111 567.502 597.651 569.515L614.106 573.471Z\"\n fill=\"#555A5E\"\n />\n <path\n d=\"M249.898 196.144C249.898 249.777 270.317 315.623 270.317 315.623C270.317 315.623 266.862 205.572 314.892 164.108C347.514 135.946 374.019 167.565 417.115 167.565C456.137 167.565 492.558 136.481 525.436 164.108C578.852 208.994 568.738 315.623 568.738 315.623C568.738 315.623 589.157 250.557 589.157 196.144C589.157 76.4319 542.638 20 417.115 20C302.8 20 249.898 75.8365 249.898 196.144Z\"\n fill=\"#525252\"\n />\n </g>\n\n {frame >= 8 ? (\n <>\n <path\n d=\"M565.5 295C565.5 350.583 549.016 400.803 522.488 437.067C495.958 473.332 459.517 495.5 419.5 495.5C379.483 495.5 343.042 473.332 316.512 437.067C289.984 400.803 273.5 350.583 273.5 295C273.5 239.417 289.984 189.197 316.512 152.933C343.042 116.668 379.483 94.5 419.5 94.5C459.517 94.5 495.958 116.668 522.488 152.933C549.016 189.197 565.5 239.417 565.5 295Z\"\n stroke={accentColor}\n strokeWidth=\"5\"\n />\n <circle cx=\"518.5\" cy=\"438.5\" r=\"25.5\" fill={accentColor} />\n <path\n d=\"M504 440.5L512 448L531 427\"\n stroke=\"white\"\n strokeWidth=\"5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </>\n ) : (\n <>\n {frame > 2 && (\n <>\n {frame > 3 && (\n <>\n {frame > 4 && (\n <>\n {frame > 5 && (\n <>\n <path\n d=\"M298.5 182.5L419 164.5L540 182\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <circle cx=\"419\" cy=\"165\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M565.5 295C565.5 350.583 549.016 400.803 522.488 437.067C495.958 473.332 459.517 495.5 419.5 495.5C379.483 495.5 343.042 473.332 316.512 437.067C289.984 400.803 273.5 350.583 273.5 295C273.5 239.417 289.984 189.197 316.512 152.933C343.042 116.668 379.483 94.5 419.5 94.5C459.517 94.5 495.958 116.668 522.488 152.933C549.016 189.197 565.5 239.417 565.5 295Z\"\n stroke=\"white\"\n strokeOpacity={\n frame > 7 ? 0.8 : frame > 5 ? 0.3 : 0.1\n }\n strokeWidth=\"5\"\n />\n <path\n d=\"M299.939 262.805L419 478.5L538.5 261.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M298.5 182.5L418.871 230.054L540 182\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M298.5 182.5L299.939 262.805\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M540.001 182L538.501 261.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n\n <circle cx=\"299.914\" cy=\"182\" r=\"7\" fill=\"white\" />\n <circle cx=\"540\" cy=\"182\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M418.828 230L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M300 263.001L419 342.501\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M538.5 261.5L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M301.5 409L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M536.5 410L419 342.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M300 263L419 230\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M538.5 261.5L419 230\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 4 && frame < 7 ? 0.3 : 1}\n />\n\n <circle cx=\"419\" cy=\"229.971\" r=\"7\" fill=\"white\" />\n <circle cx=\"419\" cy=\"342.4\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n <path\n d=\"M538.5 261.5L536.5 410\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 3 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M419 478.5L536.5 410\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 3 && frame < 7 ? 0.3 : 1}\n />\n <circle cx=\"537\" cy=\"263\" r=\"7\" fill=\"white\" />\n <circle cx=\"537\" cy=\"409\" r=\"7\" fill=\"white\" />\n </>\n )}\n\n {frame > 1 && (\n <>\n <path\n d=\"M301.501 409L300.001 263\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 2 && frame < 7 ? 0.3 : 1}\n />\n <path\n d=\"M301.501 409L419.001 478.5\"\n stroke=\"white\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeOpacity={frame > 2 && frame < 7 ? 0.3 : 1}\n />\n <circle cx=\"419\" cy=\"477.576\" r=\"7\" fill=\"white\" />\n <circle cx=\"301.914\" cy=\"263\" r=\"7\" fill=\"white\" />\n <circle cx=\"301.444\" cy=\"409\" r=\"7\" fill=\"white\" />\n </>\n )}\n </>\n )}\n </g>\n <defs>\n <clipPath id=\"clip0_428_1188\">\n <rect width=\"840\" height=\"740\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n )\n}\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { OverlayContainer, OverlayImageContainer } from '../common/overlay'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { SelfieGuidanceModelsContext } from './SelfieGuidanceModelsProvider'\nimport { CameraAccessDeniedOverlay } from '../camera/CameraAccessDeniedOverlay'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { useTranslations } from '../../lib/locales'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { SelfieCaptureLoadingOverlayProps } from './SelfieCaptureLoadingOverlay'\nimport { SelfieCaptureLoadingGraphic } from './SelfieCaptureLoadingGraphic'\nimport { MicrophoneAccessDeniedOverlay } from '../camera/MicrophoneAccessDeniedOverlay'\n\nconst legacyInstructionImageUrl = `${DEFAULT_CDN_URL}/Selfie-Image-1.png`\n\nexport const SelfieCaptureLoadingOverlayDefault = ({\n onDismissed,\n onUserCancel,\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n}: SelfieCaptureLoadingOverlayProps): ReactElement => {\n const { cameraReady, cameraAccessDenied, microphoneAccessDenied } =\n useContext(CameraStateContext)\n const { ready: modelsReady, modelDownloadProgress } = useContext(\n SelfieGuidanceModelsContext,\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Use your device camera to capture your face',\n removeEyeCoveringsText: 'Remove Sunglasses & Hat',\n avoidExcessiveBacklightingText: 'Avoid Excessive Backlighting',\n continueText: \"Let's Go!\",\n cameraInitializingText: 'Accessing camera...',\n cameraInitializedText: 'Camera ready',\n downloadingText: 'Downloading...',\n modelsWarmingUpText: 'Loading guided capture experience...',\n modelsReadyText: 'Guided capture experience ready',\n })\n\n const [headingTextIndex, setHeadingTextIndex] = useState(0)\n const headingText = [\n verbiage.headingText,\n verbiage.removeEyeCoveringsText,\n verbiage.avoidExcessiveBacklightingText,\n ][headingTextIndex]\n\n useEffect(() => {\n setInterval(() => {\n setHeadingTextIndex((n) => (n + 1) % 3)\n }, 3000)\n }, [])\n\n const [dismissed, setDismissed] = useState(false)\n if (dismissed) return <></>\n\n if (cameraAccessDenied) {\n return (\n <CameraAccessDeniedOverlay\n assets={assets.cameraAccessDenied}\n classNames={classNames.cameraAccessDenied}\n colors={colors.cameraAccessDenied}\n verbiage={rawVerbiage.cameraAccessDenied}\n />\n )\n }\n\n if (microphoneAccessDenied) {\n return (\n <MicrophoneAccessDeniedOverlay\n assets={assets.microphoneAccessDenied}\n classNames={classNames.microphoneAccessDenied}\n colors={colors.microphoneAccessDenied}\n verbiage={rawVerbiage.microphoneAccessDenied}\n />\n )\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <OverlayInner className={classNames.inner}>\n {onUserCancel && (\n <ExitCaptureButton\n onClick={onUserCancel}\n className={classNames.cancelBtn}\n />\n )}\n\n <OverlayHeader className={classNames.headingContainer}>\n <StyledGuidanceMessage className={classNames.heading}>\n {headingText}\n </StyledGuidanceMessage>\n </OverlayHeader>\n\n <StyledOverlayImageContainer className={classNames.imageContainer}>\n {assets?.instructionImageUrl &&\n assets.instructionImageUrl !== legacyInstructionImageUrl ? (\n <CustomLoadingGraphic\n className={classNames.image}\n alt={verbiage.headingText}\n src={assets.instructionImageUrl}\n />\n ) : (\n <SelfieCaptureLoadingGraphic className={classNames.image} />\n )}\n </StyledOverlayImageContainer>\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n <ProgressContainer className={classNames.progressContainer}>\n <ProgressBarBackground className={classNames.progressBackground} />\n <ProgressBar\n $progress={modelDownloadProgress}\n className={classNames.progressBar}\n >\n <ProgressIndicator className={classNames.progressIndicator} />\n </ProgressBar>\n </ProgressContainer>\n\n <LoadingListContainer className={classNames.loadingListContainer}>\n <LoadingList className={classNames.loadingList}>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n cameraReady ? 'done' : 'running'\n }`}\n >\n {cameraReady\n ? verbiage.cameraInitializedText\n : verbiage.cameraInitializingText}\n </LoadingListItem>\n <LoadingListItem\n className={`${classNames.loadingListItem} ${\n modelsReady ? 'done' : 'running'\n }`}\n >\n {modelsReady\n ? verbiage.modelsReadyText\n : modelDownloadProgress >= 100\n ? verbiage.modelsWarmingUpText\n : `${verbiage.downloadingText} (${modelDownloadProgress}%)`}\n </LoadingListItem>\n </LoadingList>\n </LoadingListContainer>\n\n <ContinueButtonContainer className={classNames.continueBtnContainer}>\n {modelsReady && cameraReady && (\n <ContinueButton\n finished\n className={classNames.continueBtn}\n variant=\"positive\"\n colors={colors.continueBtn}\n onClick={() => {\n setDismissed(true)\n onDismissed?.()\n }}\n >\n {verbiage.continueText}\n </ContinueButton>\n )}\n </ContinueButtonContainer>\n </StyledButtonsRow>\n </OverlayInner>\n </OverlayContainer>\n )\n}\n\nconst OverlayInner = styled.div`\n height: 100dvh;\n display: flex;\n flex-direction: column;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.backgroundColor ?? '#ecedf3'};\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.textColor ?? 'black'};\n`\n\nconst OverlayHeader = styled.div`\n text-align: ${(props) => props.theme.textAlign ?? 'center'};\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n ${(props) =>\n props.theme.padding\n ? `box-sizing: border-box; padding: ${props.theme.padding};`\n : ``}\n padding-bottom: 0;\n`\n\nconst StyledGuidanceMessage = styled(GuidanceMessage)`\n padding: 16px 24px;\n margin-top: 16px;\n font-size: 18px;\n font-weight: bold;\n background: white;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n display: flex;\n flex-direction: row;\n padding: 15px 25px;\n height: 100px;\n color: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarTextColor ??\n 'white'};\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100dvw;\n box-sizing: border-box;\n`\n\nconst StyledOverlayImageContainer = styled(OverlayImageContainer)`\n padding: 0;\n\n & > svg {\n height: 100%;\n }\n`\n\nconst LoadingListContainer = styled.div`\n display: flex;\n position: relative;\n z-index: 2;\n`\n\nconst LoadingList = styled.ul`\n display: block;\n margin: auto;\n list-style: none;\n padding: 0;\n`\n\nconst LoadingListItem = styled.li`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n padding: 2px 1.25rem 2px 0;\n line-height: 1rem;\n\n &::before {\n content: '';\n display: inline-block;\n height: 1rem;\n min-width: 1rem;\n vertical-align: middle;\n background-size: cover;\n background-repeat: no-repeat;\n margin: auto 0.5rem auto 0;\n }\n\n &.done::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzg1KSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiAyNEMxOC42Mjc0IDI0IDI0IDE4LjYyNzQgMjQgMTJDMjQgNS4zNzI1OCAxOC42Mjc0IDAgMTIgMEM1LjM3MjU4IDAgMCA1LjM3MjU4IDAgMTJDMCAxOC42Mjc0IDUuMzcyNTggMjQgMTIgMjRaTTE5LjU2NDMgOC4yNzg1MkMxOS45NTQ5IDcuODg3OTkgMTkuOTU0OSA3LjI1NDgzIDE5LjU2NDMgNi44NjQzQzE5LjE3MzggNi40NzM3OCAxOC41NDA2IDYuNDczNzggMTguMTUwMSA2Ljg2NDNMOS40Mjg2NiAxNS41ODU4TDUuODUwMDUgMTIuMDA3MkM1LjQ1OTUzIDExLjYxNjYgNC44MjYzNiAxMS42MTY2IDQuNDM1ODQgMTIuMDA3MkM0LjA0NTMxIDEyLjM5NzcgNC4wNDUzMSAxMy4wMzA5IDQuNDM1ODQgMTMuNDIxNEw4LjcyMTU1IDE3LjcwNzFDOS4xMTIwOCAxOC4wOTc2IDkuNzQ1MjQgMTguMDk3NiAxMC4xMzU4IDE3LjcwNzFMMTkuNTY0MyA4LjI3ODUyWiIgZmlsbD0id2hpdGUiLz48L2c+PGRlZnM+PGNsaXBQYXRoIGlkPSJjbGlwMF80OV8zODUiPjxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiLz48L2NsaXBQYXRoPjwvZGVmcz48L3N2Zz4=');\n }\n\n &.running::before {\n background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBjbGlwLXBhdGg9InVybCgjY2xpcDBfNDlfMzcwKSI+PG1hc2sgaWQ9InBhdGgtMS1pbnNpZGUtMV80OV8zNzAiIGZpbGw9IndoaXRlIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMuNTE0NzIgMjAuNDg1NUM4LjIwMTAxIDI1LjE3MTggMTUuNzk5IDI1LjE3MTggMjAuNDg1MyAyMC40ODU1QzI1LjE3MTYgMTUuNzk5MiAyNS4xNzE2IDguMjAxMTkgMjAuNDg1MyAzLjUxNDlDMTUuNzk5IC0xLjE3MTM5IDguMjAxMDEgLTEuMTcxMzkgMy41MTQ3MiAzLjUxNDlDLTEuMTcxNTcgOC4yMDExOSAtMS4xNzE1NyAxNS43OTkyIDMuNTE0NzIgMjAuNDg1NVoiLz48L21hc2s+PHBhdGggZD0iTTYuMzk4MTQgMTEuNDU5QzUuODQ1ODYgMTEuNDU5IDUuMzk4MTQgMTEuOTA2NyA1LjM5ODE0IDEyLjQ1OUM1LjM5ODE0IDEzLjAxMTIgNS44NDU4NiAxMy40NTkgNi4zOTgxNCAxMy40NTlWMTEuNDU5Wk0xNy42MDE5IDEzLjQ1OUMxOC4xNTQxIDEzLjQ1OSAxOC42MDE5IDEzLjAxMTIgMTguNjAxOSAxMi40NTlDMTguNjAxOSAxMS45MDY3IDE4LjE1NDEgMTEuNDU5IDE3LjYwMTkgMTEuNDU5VjEzLjQ1OVpNNi4zOTgxNCAxMy40NTlIMTcuNjAxOVYxMS40NTlINi4zOTgxNFYxMy40NTlaTTMuNTE0NzIgMjAuNDg1NUw0LjkyODkzIDE5LjA3MTNMNC45Mjg5MyAxOS4wNzEzTDMuNTE0NzIgMjAuNDg1NVpNMjAuNDg1MyAzLjUxNDlMMTkuMDcxMSA0LjkyOTEyTDE5LjA3MTEgNC45MjkxMkwyMC40ODUzIDMuNTE0OVpNMy41MTQ3MiAzLjUxNDlMNC45Mjg5MyA0LjkyOTEyTDQuOTI4OTMgNC45MjkxMkwzLjUxNDcyIDMuNTE0OVpNMTkuMDcxMSAxOS4wNzEzQzE1LjE2NTggMjIuOTc2NSA4LjgzNDE3IDIyLjk3NjUgNC45Mjg5MyAxOS4wNzEzTDIuMTAwNTEgMjEuODk5N0M3LjU2Nzg0IDI3LjM2NyAxNi40MzIyIDI3LjM2NyAyMS44OTk1IDIxLjg5OTdMMTkuMDcxMSAxOS4wNzEzWk0xOS4wNzExIDQuOTI5MTJDMjIuOTc2MyA4LjgzNDM2IDIyLjk3NjMgMTUuMTY2IDE5LjA3MTEgMTkuMDcxM0wyMS44OTk1IDIxLjg5OTdDMjcuMzY2OCAxNi40MzIzIDI3LjM2NjggNy41NjgwMyAyMS44OTk1IDIuMTAwNjlMMTkuMDcxMSA0LjkyOTEyWk00LjkyODkzIDQuOTI5MTJDOC44MzQxNyAxLjAyMzg3IDE1LjE2NTggMS4wMjM4NyAxOS4wNzExIDQuOTI5MTJMMjEuODk5NSAyLjEwMDY5QzE2LjQzMjIgLTMuMzY2NjUgNy41Njc4NCAtMy4zNjY2NSAyLjEwMDUxIDIuMTAwNjlMNC45Mjg5MyA0LjkyOTEyWk00LjkyODkzIDE5LjA3MTNDMS4wMjM2OSAxNS4xNjYgMS4wMjM2OSA4LjgzNDM2IDQuOTI4OTMgNC45MjkxMkwyLjEwMDUxIDIuMTAwNjlDLTMuMzY2ODMgNy41NjgwMyAtMy4zNjY4MyAxNi40MzIzIDIuMTAwNTEgMjEuODk5N0w0LjkyODkzIDE5LjA3MTNaIiBmaWxsPSJ3aGl0ZSIgbWFzaz0idXJsKCNwYXRoLTEtaW5zaWRlLTFfNDlfMzcwKSIvPjwvZz48ZGVmcz48Y2xpcFBhdGggaWQ9ImNsaXAwXzQ5XzM3MCI+PHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSIvPjwvY2xpcFBhdGg+PC9kZWZzPjwvc3ZnPg==');\n }\n`\n\nconst ProgressContainer = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n`\n\nconst ProgressBarBackground = styled.div`\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarBackgroundColor ??\n 'var(--idm-color-positive-600)'};\n opacity: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarBackgroundOpacity ??\n 0.75};\n`\n\nconst ProgressBar = styled.span<{ $progress: number }>`\n display: block;\n width: ${(props) => props.$progress}%;\n height: 100%;\n`\n\nconst ProgressIndicator = styled.span`\n display: block;\n height: 100%;\n background: ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarIndicatorColor ??\n 'var(--idm-color-positive-600)'};\n animation: progressBar 3s ease-in-out;\n animation-fill-mode: both;\n\n @keyframes progressBar {\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n }\n`\n\nconst CustomLoadingGraphic = styled.img``\n\nconst ContinueButtonContainer = styled.div`\n display: flex;\n`\n\nconst ContinueButton = styled(LoaderButton)`\n margin: auto;\n white-space: nowrap;\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize\n ? `font-size: ${props.theme?.selfieCapture?.loadingOverlay?.progressBarFontSize};`\n : ''}\n ${(props) =>\n props.theme?.selfieCapture?.loadingOverlay?.continueBtnBorder\n ? `border: ${props.theme?.selfieCapture?.loadingOverlay?.continueBtnBorder};`\n : ''}\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {\n FaceLivenessCapture,\n FaceLivenessCaptureClassNames,\n FaceLivenessCaptureColors,\n FaceLivenessCaptureVerbiage,\n} from './FaceLivenessCapture'\nimport {\n FaceLivenessSuccess,\n FaceLivenessSuccessClassNames,\n FaceLivenessSuccessColors,\n FaceLivenessSuccessVerbiage,\n} from './FaceLivenessSuccess'\nimport {\n FaceLivenessFailure,\n FaceLivenessFailureAssets,\n FaceLivenessFailureClassNames,\n FaceLivenessFailureColors,\n FaceLivenessFailureVerbiage,\n} from './FaceLivenessFailure'\nimport {\n LivenessCheckRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport {\n SelfieCaptureLoadingOverlayMode,\n SelfieCaptureLoadingOverlay,\n SelfieCaptureLoadingOverlayAssets,\n SelfieCaptureLoadingOverlayClassNames,\n SelfieCaptureLoadingOverlayColors,\n SelfieCaptureLoadingOverlayVerbiage,\n} from '../selfie_capture/SelfieCaptureLoadingOverlay'\nimport { PageContainer } from '../common/Page'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\n\ntype CaptureState = 'LOADING' | 'CAPTURING' | 'SUCCESS' | 'FAILED'\n\nexport type FaceLivenessAssets = {\n loadingOverlay?: SelfieCaptureLoadingOverlayAssets\n failure?: FaceLivenessFailureAssets\n}\n\nexport type FaceLivenessClassNames = {\n loadingOverlay?: SelfieCaptureLoadingOverlayClassNames\n capture?: FaceLivenessCaptureClassNames\n success?: FaceLivenessSuccessClassNames\n failure?: FaceLivenessFailureClassNames\n}\n\nexport type FaceLivenessColors = FaceLivenessCaptureColors & {\n loadingOverlay?: SelfieCaptureLoadingOverlayColors\n success?: FaceLivenessSuccessColors\n failure?: FaceLivenessFailureColors\n}\n\nexport type FaceLivenessVerbiage = FaceLivenessCaptureVerbiage & {\n loadingOverlay?: SelfieCaptureLoadingOverlayVerbiage\n success?: FaceLivenessSuccessVerbiage\n failure?: FaceLivenessFailureVerbiage\n}\n\nexport type FaceLivenessWizardProps = {\n onSuccess?: (resp: SubmissionResponse, req: LivenessCheckRequest) => void\n onComplete?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onTimeout?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onExitCapture?: () => void\n onExitAfterFailure?: (\n resp: SubmissionResponse | null,\n req: LivenessCheckRequest | null,\n ) => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: SelfieCaptureLoadingOverlayMode\n timeoutDurationMs?: number\n modelLoadTimeoutMs?: number\n maxRetries?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n renderCameraFeed?: boolean\n releaseCameraAccessOnExit?: boolean\n silentFallback?: boolean\n\n assets?: FaceLivenessAssets\n classNames?: FaceLivenessClassNames\n colors?: FaceLivenessColors\n verbiage?: FaceLivenessVerbiage\n debugMode?: boolean\n}\n\nexport const FaceLivenessWizard = ({\n onComplete,\n onSuccess,\n onTimeout,\n onExitCapture,\n onExitAfterFailure,\n onUserCancel,\n loadingOverlayMode = 'default',\n timeoutDurationMs = 15000,\n maxRetries = 2,\n skipSuccessScreen = false,\n renderCameraFeed = true,\n releaseCameraAccessOnExit = true,\n silentFallback = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: FaceLivenessWizardProps): ReactElement => {\n const {\n submissionResponse,\n livenessCheckRequest,\n setSelfieImage,\n logSelfieCaptureAttempt,\n } = useContext(SubmissionContext)\n const { cameraAccessDenied, releaseCameraAccess } =\n useContext(CameraStateContext)\n const [faceCropImageUrl, setFaceCropImageUrl] = useState('')\n const [retryCount, setRetryCount] = useState(0)\n const [captureState, setCaptureState] = useState<CaptureState>('LOADING')\n const captureStartedAt = useRef<Date>()\n const captureEndedAt = useRef<Date>()\n const operationStartedAt = useRef<Date>()\n const { start, stop } = useContext(SelfieGuidanceModelsContext)\n\n useEffect(() => {\n operationStartedAt.current = new Date()\n }, [])\n\n useEffect(() => {\n if (captureState !== 'CAPTURING') return\n captureStartedAt.current = new Date()\n start()\n return () => {\n stop()\n }\n }, [captureState, start, stop])\n\n const onCapture = useCallback(() => {\n captureEndedAt.current = new Date()\n }, [])\n\n const logCaptureMetadata = useCallback(() => {\n logSelfieCaptureAttempt({\n autoCapture: 'Y',\n captureTime:\n (captureEndedAt.current ?? new Date()).getTime() -\n (captureStartedAt.current ?? new Date()).getTime(),\n operationTime:\n new Date().getTime() -\n (operationStartedAt.current ?? new Date()).getTime(),\n })\n\n operationStartedAt.current = new Date()\n }, [logSelfieCaptureAttempt])\n\n const onSuccessCallback = useCallback(\n async (faceCropImageUrl: string) => {\n if (!livenessCheckRequest || !submissionResponse) return\n setCaptureState('SUCCESS')\n setFaceCropImageUrl(faceCropImageUrl)\n setSelfieImage(await dataUrlToBase64(faceCropImageUrl))\n onSuccess?.(submissionResponse, livenessCheckRequest)\n },\n [onSuccess, setSelfieImage, livenessCheckRequest, submissionResponse],\n )\n\n // todo: JN - how this is being used, it would make sense to rename the prop as well, but that would be a breaking change - discuss\n const onFailureOrTimeout = useCallback(() => {\n setCaptureState('FAILED')\n onTimeout?.(submissionResponse, livenessCheckRequest)\n }, [onTimeout, livenessCheckRequest, submissionResponse])\n\n const [attempt, setAttempt] = useState(0)\n const onExitCallback = useCallback(() => {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n onExitCapture?.()\n }, [onExitCapture])\n\n const onDoneCallback = useCallback(() => {\n logCaptureMetadata()\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onComplete?.(submissionResponse, livenessCheckRequest)\n }, 0)\n }, [\n logCaptureMetadata,\n onComplete,\n releaseCameraAccess,\n releaseCameraAccessOnExit,\n livenessCheckRequest,\n submissionResponse,\n ])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n captureState === 'SUCCESS',\n onDoneCallback,\n )\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n }\n }, [cameraAccessDenied])\n\n return (\n <>\n <PageContainer className={`flex ${classNames.capture?.container ?? ''}`}>\n {renderCameraFeed && (\n <CameraVideoTag className={classNames.capture?.cameraFeed} />\n )}\n\n {captureState !== 'LOADING' &&\n (() => {\n switch (captureState) {\n case 'CAPTURING':\n return (\n <FaceLivenessCapture\n key={`capture${attempt}`}\n onCapture={onCapture}\n onSuccess={onSuccessCallback}\n onTimeout={onFailureOrTimeout}\n onExit={onExitCallback}\n timeoutDurationMs={timeoutDurationMs}\n silentFallback={silentFallback}\n classNames={classNames.capture}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n )\n\n case 'SUCCESS':\n if (!showSuccessScreen) return null\n return (\n <FaceLivenessSuccess\n key=\"success\"\n imageUrl={faceCropImageUrl}\n classNames={classNames.success}\n colors={colors.success}\n verbiage={verbiage.success}\n onDoneClick={onDoneCallback}\n onRetryClick={() => {\n logCaptureMetadata()\n setCaptureState('CAPTURING')\n }}\n />\n )\n\n case 'FAILED':\n return (\n <FaceLivenessFailure\n key=\"failure\"\n assets={assets.failure}\n classNames={classNames.failure}\n colors={colors.failure}\n verbiage={verbiage.failure}\n canRetry={maxRetries > -1 && retryCount < maxRetries}\n onRetryClick={() => {\n logCaptureMetadata()\n setRetryCount((c) => c + 1)\n setCaptureState('CAPTURING')\n }}\n onExitClick={() => {\n releaseCameraAccessOnExit && releaseCameraAccess()\n setTimeout(() => {\n onExitAfterFailure?.(\n submissionResponse,\n livenessCheckRequest,\n )\n }, 0)\n }}\n />\n )\n\n default:\n return null\n }\n })()}\n </PageContainer>\n\n <SelfieCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onUserCancel={onUserCancel}\n onDismissed={() => {\n setCaptureState('CAPTURING')\n }}\n />\n </>\n )\n}\n","import React, { ReactElement, ReactNode, useCallback, useState } from 'react'\nimport {\n GuideOrientationContext,\n GuideOrientationState,\n} from '../contexts/GuideOrientationContext'\nimport useResizeObserver from 'use-resize-observer'\n\nexport const GuideOrientationProvider = ({\n children,\n}: {\n children: ReactNode\n}): ReactElement => {\n const setDimensions = useState({ width: 1, height: 1 })[1]\n const [imageAspectRatio, setImageAspectRatio] = useState(1)\n const {\n ref: wrapperRef,\n width: wrapperWidth = 1,\n height: wrapperHeight = 1,\n } = useResizeObserver<HTMLDivElement>()\n\n const wrapperAspectRatio = wrapperWidth / wrapperHeight\n\n const onImageLoaded = useCallback((e: React.SyntheticEvent) => {\n const img = e.target as HTMLImageElement\n setImageAspectRatio(img.naturalWidth / img.naturalHeight)\n }, [])\n\n const orientation = 'landscape' //width > height ? 'landscape' : 'portrait'\n const value: GuideOrientationState = {\n orientation,\n wrapperWidth,\n wrapperHeight,\n wrapperAspectRatio,\n imageAspectRatio,\n setDimensions,\n wrapperRef,\n onImageLoaded,\n }\n\n return (\n <GuideOrientationContext.Provider value={value}>\n {children}\n </GuideOrientationContext.Provider>\n )\n}\n","import React, { ReactElement, useContext, useMemo, useState } from 'react'\nimport { SubmissionContext } from './SubmissionProvider'\n\nexport const SubmissionSuccess = (): ReactElement => {\n const { submissionRequest, submissionResponse } =\n useContext(SubmissionContext)\n const [showRequestBody, setShowRequestBody] = useState(false)\n const [truncateImages, setTruncateImages] = useState(true)\n\n const requestBodyDisplay = useMemo(() => {\n const body = JSON.parse(JSON.stringify(submissionRequest))\n if (truncateImages) {\n if (body?.customerData?.idData?.idImageFront)\n body.customerData.idData.idImageFront = truncate(\n body.customerData.idData.idImageFront,\n 200,\n )\n if (body?.customerData?.idData?.idImageBack)\n body.customerData.idData.idImageBack = truncate(\n body.customerData.idData.idImageBack,\n 200,\n )\n if (body?.customerData?.biometricData?.selfie)\n body.customerData.biometricData.selfie = truncate(\n body.customerData.biometricData.selfie,\n 200,\n )\n }\n return JSON.stringify(body, null, 2)\n }, [submissionRequest, truncateImages])\n\n return (\n <>\n <h3>Submission completed!</h3>\n\n <button\n onClick={() => {\n setShowRequestBody(!showRequestBody)\n }}\n >\n {showRequestBody ? 'Hide' : 'Show'} request body\n </button>\n\n {showRequestBody && (\n <>\n <button\n style={{ marginLeft: 8 }}\n onClick={() => {\n setTruncateImages(!truncateImages)\n }}\n >\n {truncateImages ? 'Display full images' : 'Truncate images'}\n </button>\n\n <h5>Request Body</h5>\n <pre>{requestBodyDisplay}</pre>\n </>\n )}\n\n <h5>Response Body</h5>\n <pre>{JSON.stringify(submissionResponse, null, 2)}</pre>\n </>\n )\n}\n\nfunction truncate(str: string, max_chars: number): string {\n let truncated = str.split('').splice(0, max_chars).join('')\n if (truncated.length < str.length) truncated += '...'\n return truncated\n}\n","import React, { ReactElement, useRef, useState } from 'react'\nimport {\n contentDispositionFromDataUrl,\n dataUrlToBase64Sync,\n} from '../../lib/utils/dataUrlToBase64'\nimport { OverlayContainer, OverlayInner } from '../common/overlay'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport styled from 'styled-components'\nimport { LoaderButton } from '../common/LoaderButton'\nimport { ButtonsRow } from '../common/ButtonsRow'\n\nexport type AdditionalDocument = {\n name: string\n description?: string\n skip?: () => Promise<boolean>\n}\n\nexport type UploadedDocument = {\n documentName: string\n additionalDocument: string | Record<string, string>\n}\n\nexport type AdditionalDocumentCaptureClassNames = {\n container?: string\n inner?: string\n heading?: string\n description?: string\n buttonsRow?: string\n captureBtn?: string\n nextBtn?: string\n}\n\nexport type AdditionalDocumentCaptureVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n nextBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type AdditionalDocumentCaptureProps = {\n document: AdditionalDocument\n onComplete?: (uploadedDocument: UploadedDocument) => void\n classNames?: AdditionalDocumentCaptureClassNames\n verbiage?: AdditionalDocumentCaptureVerbiage\n}\n\nexport const AdditionalDocumentCapture = ({\n document,\n onComplete,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: AdditionalDocumentCaptureProps): ReactElement => {\n const fileInput = useRef<HTMLInputElement | null>(null)\n const [file, setFile] = useState<File | null>(null)\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Additional document capture',\n captureBtnText: 'Capture',\n nextBtnText: 'Next',\n })\n\n function onFileSelected(e: React.ChangeEvent<HTMLInputElement>) {\n const file = e.target.files?.[0]\n if (file) setFile(file)\n }\n\n function onNextClicked() {\n if (!file) return\n\n const fileReader = new FileReader()\n fileReader.onloadend = () => {\n if (!fileReader.result) return\n const fileContent = fileReader.result.toString()\n onComplete?.({\n documentName: document.name,\n additionalDocument: {\n name: file.name,\n fileContent: dataUrlToBase64Sync(fileContent),\n type: contentDispositionFromDataUrl(fileContent),\n fileUploadType: 'Y',\n isImageControlData: 'Y',\n fieldId: '',\n },\n })\n }\n fileReader.readAsDataURL(file)\n }\n\n return (\n <OverlayContainer className={classNames.container}>\n <Inner className={classNames.inner}>\n <Heading className={classNames.heading}>\n {verbiage.headingText}: {document.name}\n </Heading>\n\n {document.description && (\n <Description className={classNames.description}>\n {document.description}\n </Description>\n )}\n\n <input\n ref={fileInput}\n type=\"file\"\n accept=\"image/*,.pdf\"\n onChange={onFileSelected}\n hidden\n />\n\n <StyledButtonsRow className={classNames.buttonsRow}>\n {file ? (\n <LoaderButton\n variant=\"positive\"\n className={classNames.nextBtn}\n disabled={!file}\n finished\n onClick={onNextClicked}\n >\n {verbiage.nextBtnText}\n </LoaderButton>\n ) : (\n <LoaderButton\n variant=\"primary\"\n className={classNames.captureBtn}\n finished\n onClick={() => {\n fileInput.current?.click()\n }}\n >\n {verbiage.captureBtnText}\n </LoaderButton>\n )}\n </StyledButtonsRow>\n </Inner>\n </OverlayContainer>\n )\n}\n\nconst Inner = styled(OverlayInner)`\n justify-content: center;\n`\n\nconst Heading = styled.h3`\n margin-bottom: 8px;\n`\n\nconst Description = styled.p`\n margin-bottom: 8px;\n`\n\nconst StyledButtonsRow = styled(ButtonsRow)`\n margin-top: 32px;\n`\n","import React, { ReactElement, useEffect, useState } from 'react'\nimport {\n AdditionalDocument,\n AdditionalDocumentCapture,\n AdditionalDocumentCaptureClassNames,\n AdditionalDocumentCaptureVerbiage,\n UploadedDocument,\n} from './AdditionalDocumentCapture'\n\nexport type AdditionalDocumentCaptureWizardClassNames =\n AdditionalDocumentCaptureClassNames\n\nexport type AdditionalDocumentCaptureWizardVerbiage =\n AdditionalDocumentCaptureVerbiage\n\nexport type AdditionalDocumentCaptureWizardProps = {\n documents: AdditionalDocument[]\n onComplete?: (uploadedDocuments: UploadedDocument[]) => void\n classNames?: AdditionalDocumentCaptureWizardClassNames\n verbiage?: AdditionalDocumentCaptureWizardVerbiage\n}\n\nexport const AdditionalDocumentCaptureWizard = ({\n documents,\n onComplete,\n classNames = {},\n verbiage = {},\n}: AdditionalDocumentCaptureWizardProps): ReactElement => {\n const [uploadedDocuments, setUploadedDocuments] = useState<\n (UploadedDocument | null)[]\n >([])\n const documentIndex = uploadedDocuments.length\n const currentDocument = documents[documentIndex]\n const isComplete = documentIndex >= documents.length\n\n useEffect(() => {\n if (!currentDocument?.skip) return\n ;(async () => {\n if (await currentDocument.skip?.()) {\n setUploadedDocuments((f) => [...f, null])\n }\n })()\n }, [currentDocument])\n\n useEffect(() => {\n if (isComplete) {\n onComplete?.(uploadedDocuments.filter((d) => !!d) as UploadedDocument[])\n }\n }, [isComplete, onComplete, uploadedDocuments])\n\n if (isComplete) return <>Thanks, your documents have been received.</>\n\n return (\n <AdditionalDocumentCapture\n key={documentIndex}\n document={currentDocument}\n classNames={classNames}\n verbiage={verbiage}\n onComplete={(data) => {\n setUploadedDocuments((f) => [...f, data])\n }}\n />\n )\n}\n","import ReactSignatureCanvas from 'react-signature-canvas'\nimport { dataUrlToBase64Sync } from '../../lib/utils/dataUrlToBase64'\n\nexport type SignatureData = {\n clickX_simple: number[][]\n clickY_simple: number[][]\n time_simple: string[][]\n pressure: string\n fileContent: string\n}\n\nexport function signatureDataToIdmissionFormat(\n signatureCanvas: ReactSignatureCanvas,\n): SignatureData {\n const dataURL = signatureCanvas.toDataURL() ?? null\n\n const signatureData: SignatureData = {\n clickX_simple: [],\n clickY_simple: [],\n time_simple: [],\n pressure: '',\n fileContent: dataURL ? dataUrlToBase64Sync(dataURL) : '',\n }\n\n signatureCanvas.toData().forEach((stroke) => {\n const xs: number[] = []\n const ys: number[] = []\n const times: string[] = []\n stroke.forEach((d) => {\n xs.push(d.x)\n ys.push(d.y)\n times.push(new Date(d.time).toString())\n })\n signatureData.clickX_simple.push(xs)\n signatureData.clickY_simple.push(ys)\n signatureData.time_simple.push(times)\n })\n\n return signatureData\n}\n","import styled from 'styled-components'\nimport { ButtonsRow } from './ButtonsRow'\n\nexport const SignaturePaperBacking = styled.div`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n ${(props) =>\n props.theme.signatureCapture?.background\n ? `background: ${props.theme.signatureCapture?.background};`\n : ``}\n ${(props) =>\n props.theme.signatureCapture?.backgroundSize\n ? `background-size: ${props.theme.signatureCapture?.backgroundSize};`\n : ``}\n ${(props) =>\n props.theme.signatureCapture?.backgroundPosition\n ? `background-position: ${props.theme.signatureCapture?.backgroundPosition};`\n : ``}\n`\n\nexport const SignatureCanvasContainer = styled.div`\n position: absolute;\n top: 25%;\n left: 15%;\n width: 70%;\n height: 50%;\n\n @media (max-width: 800px) {\n top: 15%;\n left: 2%;\n width: 96%;\n height: 70%;\n }\n`\n\nexport const SignaturePad = styled.div`\n position: relative;\n background: ${(props) =>\n props.theme.signatureCapture?.canvas?.background ??\n 'rgba(255, 255, 255, 0.5)'};\n border: ${(props) =>\n props.theme.signatureCapture?.canvas?.border ?? `1px solid #dedede`};\n border-radius: ${(props) =>\n props.theme.signatureCapture?.canvas?.borderRadius ?? '16px'};\n flex-grow: 1;\n z-index: 100;\n height: 100%;\n`\n\nexport const SignatureButtonsContainer = styled(ButtonsRow)`\n flex-grow: 0;\n padding-top: 12px;\n display: flex;\n z-index: 1000;\n position: relative;\n`\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport { Camera } from './Camera'\nimport log from '../utils/logger'\n\nexport const useVideoRecorder = (\n camera: Camera | null,\n audioStream?: MediaStream | null,\n mergeAVStreams = false,\n) => {\n const videoRecorder = useRef<MediaRecorder | null>(null)\n const audioRecorder = useRef<MediaRecorder | null>(null)\n const videoChunks = useRef<BlobPart[]>([])\n const audioChunks = useRef<BlobPart[]>([])\n const [videoUrl, setVideoUrl] = useState<string | null>(null)\n const [audioUrl, setAudioUrl] = useState<string | null>(null)\n const [isRecordingVideo, setIsRecordingVideo] = useState(false)\n const [isRecordingAudio, setIsRecordingAudio] = useState(false)\n\n const [videoRecordingStopped, setVideoRecordingStopped] = useState(false)\n const [audioRecordingStopped, setAudioRecordingStopped] = useState(false)\n const [\n videoRecordingIntentionallyStopped,\n setVideoRecordingIntentionallyStopped,\n ] = useState(false)\n const [\n audioRecordingIntentionallyStopped,\n setAudioRecordingIntentionallyStopped,\n ] = useState(false)\n\n const getVideoStream = useCallback(() => {\n if (!mergeAVStreams) return camera?.stream\n const videoTracks = camera?.stream?.getTracks() ?? []\n const audioTracks = audioStream?.getTracks() ?? []\n return new MediaStream([...videoTracks, ...audioTracks])\n }, [audioStream, camera?.stream, mergeAVStreams])\n\n const processVideo = useCallback(() => {\n const videoBlob = new Blob(videoChunks.current, { type: 'video/mp4' })\n videoChunks.current = []\n setVideoUrl(URL.createObjectURL(videoBlob))\n setIsRecordingVideo(false)\n camera?.release()\n }, [camera])\n\n const processAudio = useCallback(() => {\n const audioBlob = new Blob(audioChunks.current, {\n type: 'audio/ogg; codecs=opus',\n })\n audioChunks.current = []\n setAudioUrl(URL.createObjectURL(audioBlob))\n setIsRecordingAudio(false)\n audioStream?.stop?.()\n }, [audioStream])\n\n const startRecordingVideo = useCallback(() => {\n const videoStream = getVideoStream()\n if (!videoStream) return\n\n videoChunks.current = []\n setIsRecordingVideo(true)\n setVideoRecordingStopped(false)\n setVideoRecordingIntentionallyStopped(false)\n\n videoRecorder.current = new MediaRecorder(videoStream, {\n videoBitsPerSecond: 270000,\n audioBitsPerSecond: 32000,\n })\n\n videoRecorder.current.ondataavailable = (e) => {\n videoChunks.current.push(e.data)\n }\n\n videoRecorder.current.onstop = () => {\n setVideoRecordingStopped(true)\n }\n\n videoRecorder.current.start(1000)\n\n setTimeout(() => {\n if (videoRecorder.current?.state === 'inactive') {\n log('media recorder is inactive!')\n // TODO: figure out what to do here\n }\n }, 100)\n }, [getVideoStream])\n\n const startRecordingAudio = useCallback(() => {\n if (mergeAVStreams) return\n if (!audioStream) return\n\n audioChunks.current = []\n setIsRecordingAudio(true)\n setAudioRecordingStopped(false)\n setAudioRecordingIntentionallyStopped(false)\n\n audioRecorder.current = new MediaRecorder(audioStream, {\n audioBitsPerSecond: 32000,\n })\n\n audioRecorder.current.ondataavailable = (e) => {\n audioChunks.current.push(e.data)\n }\n\n audioRecorder.current.onstop = () => {\n setAudioRecordingStopped(true)\n }\n\n audioRecorder.current.start(1000)\n }, [audioStream, mergeAVStreams])\n\n const stopRecordingVideo = useCallback(() => {\n setVideoRecordingIntentionallyStopped(true)\n if (videoRecorder.current?.state !== 'inactive') {\n videoRecorder.current?.stop() // if you call this while state === 'inactive', an exception is thrown.\n }\n }, [])\n\n const stopRecordingAudio = useCallback(() => {\n setAudioRecordingIntentionallyStopped(true)\n if (audioRecorder.current?.state !== 'inactive') {\n audioRecorder.current?.stop() // if you call this while state === 'inactive', an exception is thrown.\n }\n }, [])\n\n useEffect(() => {\n if (videoRecordingStopped && videoRecordingIntentionallyStopped) {\n processVideo()\n }\n }, [processVideo, videoRecordingIntentionallyStopped, videoRecordingStopped])\n\n useEffect(() => {\n if (audioRecordingStopped && audioRecordingIntentionallyStopped) {\n processAudio()\n }\n }, [audioRecordingIntentionallyStopped, audioRecordingStopped, processAudio])\n\n return {\n isRecordingVideo,\n isRecordingAudio,\n startRecordingVideo,\n startRecordingAudio,\n stopRecordingVideo,\n stopRecordingAudio,\n videoRecordingUnintentionallyStopped:\n videoRecordingStopped && !videoRecordingIntentionallyStopped,\n audioRecordingUnintentionallyStopped:\n audioRecordingStopped && !audioRecordingIntentionallyStopped,\n videoUrl,\n audioUrl,\n }\n}\n","import React, { useContext, useEffect, useRef, useState } from 'react'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { useVideoRecorder } from '../../lib/camera/useVideoRecorder'\nimport {\n SignatureData,\n signatureDataToIdmissionFormat,\n} from '../signature_capture/data'\nimport SignatureCanvas from 'react-signature-canvas'\nimport useResizeObserver from 'use-resize-observer'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport { PageContainer } from '../common/Page'\nimport {\n SignatureButtonsContainer,\n SignatureCanvasContainer,\n SignaturePad,\n} from '../common/signature'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport { DebugStatsPane } from '../common/debug'\nimport { ExitCaptureButton } from '../common/ExitCaptureButton'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { LoaderButton } from '../common/LoaderButton'\nimport styled from 'styled-components'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\n\nexport type VideoSignatureCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guidanceMessageContainer?: string\n guidanceMessage?: string\n canvasContainer?: string\n canvasInner?: string\n canvas?: string\n buttonsRow?: string\n acceptBtn?: string\n clearBtn?: string\n exitCaptureBtn?: string\n}\n\nexport type VideoSignatureCaptureColors = {\n guidanceMessageBackgroundColor?: string\n guidanceMessageTextColor?: string\n}\n\nexport type VideoSignatureCaptureVerbiage = {\n guidanceMessageText?: CustomerSuppliedVerbiage\n acceptBtnText?: CustomerSuppliedVerbiage\n clearBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type VideoSignatureCaptureProps = {\n onVideoCaptured?: (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => void\n onFaceNotDetected?: () => void\n onExit?: () => void\n classNames?: VideoSignatureCaptureClassNames\n colors?: VideoSignatureCaptureColors\n verbiage?: VideoSignatureCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const VideoSignatureCapture = ({\n onVideoCaptured,\n onFaceNotDetected,\n onExit,\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: VideoSignatureCaptureProps): React.ReactElement => {\n const { cameraRef, videoRef } = useContext(CameraStateContext)\n const { ref, width, height } = useResizeObserver()\n const signaturePad = useRef<SignatureCanvas | null>(null)\n const signatureRecorder = useRef<MediaRecorder | null>(null)\n const recordedChunks = useRef<BlobPart[]>([])\n const { onPredictionMade } = useContext(SelfieGuidanceModelsContext)\n\n const {\n isRecordingVideo,\n startRecordingVideo,\n stopRecordingVideo,\n videoUrl,\n } = useVideoRecorder(cameraRef.current)\n const [signatureData, setSignatureData] = useState<SignatureData | null>(null)\n const [signatureDataUrl, setSignatureDataUrl] = useState<string | null>(null)\n const [signatureVideoData, setSignatureVideoData] = useState<Blob | null>(\n null,\n )\n\n colors.guidanceMessageBackgroundColor ||= '#ccc'\n colors.guidanceMessageTextColor ||= 'black'\n\n const verbiage = useTranslations(rawVerbiage, {\n guidanceMessageText: 'Please sign the box below',\n acceptBtnText: 'Accept',\n clearBtnText: 'Clear',\n })\n\n const outputCanvas = useRef<HTMLCanvasElement>(null)\n const recordingLock = useRef(false)\n\n useEffect(() => {\n if (recordingLock.current) return\n recordingLock.current = true\n ;(async () => {\n if (!outputCanvas.current) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (outputCanvas.current) {\n clearInterval(interval)\n resolve(null)\n }\n }, 10)\n })\n }\n\n startRecordingVideo()\n\n const stream = outputCanvas.current!.captureStream(24 /* fps */)\n signatureRecorder.current = new MediaRecorder(stream, {\n videoBitsPerSecond: 270000,\n })\n\n signatureRecorder.current.start()\n\n signatureRecorder.current.ondataavailable = function (event) {\n recordedChunks.current.push(event.data)\n if (signatureRecorder.current?.state === 'recording') {\n signatureRecorder.current.stop()\n }\n }\n\n signatureRecorder.current.onstop = function () {\n const blob = new Blob(recordedChunks.current, { type: 'video/mp4' })\n setSignatureVideoData(blob)\n }\n })()\n }, [isRecordingVideo, startRecordingVideo, videoUrl])\n\n useEffect(() => {\n if (signatureVideoData && signatureData && signatureDataUrl) {\n onVideoCaptured?.(signatureVideoData, signatureData, signatureDataUrl)\n }\n }, [onVideoCaptured, signatureData, signatureDataUrl, signatureVideoData])\n\n const animationFrame = useRef(0)\n useEffect(() => {\n if (\n !signaturePad.current ||\n !videoRef.current ||\n !outputCanvas.current ||\n !cameraRef.current ||\n !isRecordingVideo\n )\n return\n\n let [w, h] = [cameraRef.current.width, cameraRef.current.height]\n const isPortrait =\n typeof window !== 'undefined' && window.innerWidth < window.innerHeight\n const cameraIsLandscape = w > h\n if (isPortrait && cameraIsLandscape) [w, h] = [h, w]\n outputCanvas.current.width = w\n outputCanvas.current.height = h\n\n const ctx = outputCanvas.current.getContext('2d')\n if (!ctx) return\n\n animationFrame.current = requestAnimationFrame(async function runFrame() {\n if (!signaturePad.current || !videoRef.current || !outputCanvas.current) {\n cancelAnimationFrame(animationFrame.current)\n return\n }\n\n const rect: [number, number, number, number] = [\n w * (isPortrait ? 0.02 : 0.15),\n h * (isPortrait ? 0.15 : 0.25),\n w * (isPortrait ? 0.96 : 0.7),\n h * (isPortrait ? 0.7 : 0.5),\n ]\n\n ctx.drawImage(videoRef.current, 0, 0, w, h)\n\n ctx.beginPath()\n ctx.fillStyle = 'rgba(255,255,255,0.5)'\n ctx.roundRect(...rect, 16)\n ctx.fill()\n\n ctx.drawImage(signaturePad.current.getCanvas(), ...rect)\n\n animationFrame.current = requestAnimationFrame(runFrame)\n })\n\n return () => {\n cancelAnimationFrame(animationFrame.current)\n }\n }, [cameraRef, isRecordingVideo, onFaceNotDetected, videoRef])\n\n const [numFramesWithoutFaces, setNumFramesWithoutFaces] = useState(0)\n useEffect(() => {\n onPredictionMade((faces) => {\n setNumFramesWithoutFaces((n) => (faces.length === 0 ? n + 1 : 0))\n })\n }, [onPredictionMade])\n\n useEffect(() => {\n if (numFramesWithoutFaces >= 2) {\n onFaceNotDetected?.()\n }\n }, [numFramesWithoutFaces, onFaceNotDetected])\n\n function onAcceptClicked() {\n if (!signaturePad.current) return\n\n const signatureData = signatureDataToIdmissionFormat(signaturePad.current)\n setSignatureData(signatureData)\n setSignatureDataUrl(signaturePad.current.toDataURL())\n stopRecordingVideo()\n signatureRecorder.current?.stop()\n }\n\n return (\n <PageContainer className={`flex ${classNames.container ?? ''}`}>\n {verbiage.guidanceMessageText && (\n <GuidanceMessageContainer\n $top=\"5vh\"\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n className={classNames.guidanceMessage}\n $background={colors.guidanceMessageBackgroundColor}\n $textColor={colors.guidanceMessageTextColor}\n >\n {verbiage.guidanceMessageText}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n <SignatureCanvasContainer className={classNames.canvasContainer}>\n <SignaturePad ref={ref} className={classNames.canvasInner}>\n <SignatureCanvas\n ref={signaturePad}\n canvasProps={{ width, height, className: classNames.canvas }}\n />\n </SignaturePad>\n\n <SignatureButtonsContainer className={classNames.buttonsRow}>\n <LoaderButton\n variant=\"secondary\"\n className={classNames.clearBtn}\n onClick={signaturePad.current?.clear}\n finished\n >\n {verbiage.clearBtnText}\n </LoaderButton>\n\n <AcceptBtn\n variant=\"positive\"\n className={classNames.acceptBtn}\n style={{ marginLeft: 'auto' }}\n onClick={onAcceptClicked}\n finished\n >\n {verbiage.acceptBtnText}\n </AcceptBtn>\n </SignatureButtonsContainer>\n </SignatureCanvasContainer>\n\n {debugMode && (\n <DebugStatsPane>\n Video: {cameraRef.current?.width}x{cameraRef.current?.height}\n </DebugStatsPane>\n )}\n\n <ExitCaptureButton\n onClick={onExit}\n className={classNames.exitCaptureBtn}\n />\n\n <InvisibleCanvas ref={outputCanvas} />\n </PageContainer>\n )\n}\n\nconst AcceptBtn = styled(LoaderButton)`\n margin-left: auto;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport {\n VideoSignatureCapture,\n VideoSignatureCaptureClassNames,\n VideoSignatureCaptureColors,\n VideoSignatureCaptureVerbiage,\n} from './VideoSignatureCapture'\nimport {\n FaceLivenessCapture,\n FaceLivenessCaptureClassNames,\n} from '../face_liveness/FaceLivenessCapture'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { SignatureData } from '../signature_capture/data'\nimport {\n VideoSignatureSuccess,\n VideoSignatureSuccessClassNames,\n VideoSignatureSuccessColors,\n VideoSignatureSuccessVerbiage,\n} from './VideoSignatureSuccess'\nimport {\n FaceLivenessColors,\n FaceLivenessVerbiage,\n} from '../face_liveness/FaceLivenessWizard'\nimport { useShowSuccessScreen } from '../common/useShowSuccessScreen'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport {\n SelfieCaptureLoadingOverlay,\n SelfieCaptureLoadingOverlayAssets,\n SelfieCaptureLoadingOverlayClassNames,\n SelfieCaptureLoadingOverlayColors,\n SelfieCaptureLoadingOverlayMode,\n SelfieCaptureLoadingOverlayVerbiage,\n} from '../selfie_capture/SelfieCaptureLoadingOverlay'\nimport { CameraVideoTag } from '../camera/CameraVideoTag'\nimport { PageContainer } from '../common/Page'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\n\ntype CaptureState =\n | 'LOADING'\n | 'CHECKING_LIVENESS'\n | 'CAPTURING_SIGNATURE'\n | 'SUCCESS'\n | 'FAILED'\n\nexport type VideoSignatureAssets = {\n loadingOverlay?: SelfieCaptureLoadingOverlayAssets\n}\n\nexport type VideoSignatureClassNames = VideoSignatureCaptureClassNames & {\n loadingOverlay?: SelfieCaptureLoadingOverlayClassNames\n faceLiveness?: FaceLivenessCaptureClassNames\n success?: VideoSignatureSuccessClassNames\n}\n\nexport type VideoSignatureColors = VideoSignatureCaptureColors & {\n faceLiveness?: FaceLivenessColors\n loadingOverlay?: SelfieCaptureLoadingOverlayColors\n success?: VideoSignatureSuccessColors\n}\n\nexport type VideoSignatureVerbiage = VideoSignatureCaptureVerbiage & {\n loadingOverlay?: SelfieCaptureLoadingOverlayVerbiage\n faceLiveness?: FaceLivenessVerbiage\n success?: VideoSignatureSuccessVerbiage\n}\n\nexport type VideoSignatureWizardProps = {\n onComplete?: () => void\n onVideoCaptured?: (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => void\n onRetryClicked?: () => void\n onExitCapture?: () => void\n onUserCancel?: () => void\n onModelError?: (error: Error) => void\n\n loadingOverlayMode?: SelfieCaptureLoadingOverlayMode\n modelLoadTimeoutMs?: number\n skipSuccessScreen?: boolean | (() => Promise<boolean>)\n\n assets?: VideoSignatureAssets\n classNames?: VideoSignatureClassNames\n colors?: VideoSignatureColors\n verbiage?: VideoSignatureVerbiage\n debugMode?: boolean\n}\n\nexport const VideoSignatureWizard = ({\n onComplete,\n onVideoCaptured,\n onRetryClicked,\n onExitCapture,\n onUserCancel,\n loadingOverlayMode = 'default',\n skipSuccessScreen = false,\n assets = {},\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: VideoSignatureWizardProps): ReactElement => {\n const {\n selfieImage,\n signatureVideoUrl,\n setSelfieImage,\n setSignatureData,\n setSignatureVideoUrl,\n logSelfieCaptureAttempt,\n } = useContext(SubmissionContext)\n const { cameraAccessDenied } = useContext(CameraStateContext)\n const [captureState, setCaptureState] = useState<CaptureState>('LOADING')\n const operationStartedAt = useRef<Date>()\n const captureStartedAt = useRef<Date>()\n const captureEndedAt = useRef<Date>()\n const { start, stop } = useContext(SelfieGuidanceModelsContext)\n\n useEffect(() => {\n operationStartedAt.current = new Date()\n }, [])\n\n useEffect(() => {\n if (captureState !== 'CHECKING_LIVENESS') return\n captureStartedAt.current = new Date()\n }, [captureState])\n\n const shouldRun = ['CHECKING_LIVENESS', 'CAPTURING_SIGNATURE'].includes(\n captureState,\n )\n useEffect(() => {\n if (!shouldRun) return\n start()\n return () => {\n stop()\n }\n }, [shouldRun, start, stop])\n\n const logCaptureMetadata = useCallback(() => {\n logSelfieCaptureAttempt({\n autoCapture: 'Y',\n captureTime:\n (captureEndedAt.current ?? new Date()).getTime() -\n (captureStartedAt.current ?? new Date()).getTime(),\n operationTime:\n new Date().getTime() -\n (operationStartedAt.current ?? new Date()).getTime(),\n })\n\n operationStartedAt.current = new Date()\n }, [logSelfieCaptureAttempt])\n\n const onLoadingOverlayDismissed = useCallback(() => {\n setCaptureState('CHECKING_LIVENESS')\n }, [])\n\n const onFaceCaptureSuccess = useCallback(\n async (faceCropImageUrl: string) => {\n setCaptureState('CAPTURING_SIGNATURE')\n logCaptureMetadata()\n if (!selfieImage) {\n setSelfieImage(await dataUrlToBase64(faceCropImageUrl))\n }\n },\n [logCaptureMetadata, selfieImage, setSelfieImage],\n )\n\n const onSignatureCaptureCompleted = useCallback(\n (\n videoData: Blob,\n signatureData: SignatureData,\n signatureImageData: string,\n ) => {\n setSignatureData(signatureData)\n setSignatureVideoUrl(URL.createObjectURL(videoData))\n setCaptureState('SUCCESS')\n onVideoCaptured?.(videoData, signatureData, signatureImageData)\n },\n [onVideoCaptured, setSignatureData, setSignatureVideoUrl],\n )\n\n const onSignatureCaptureFacesNotDetected = useCallback(() => {\n setCaptureState('CHECKING_LIVENESS')\n }, [])\n\n const [attempt, setAttempt] = useState(0)\n const onExit = useCallback(() => {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n onExitCapture?.()\n }, [onExitCapture])\n const onRetry = useCallback(() => {\n onRetryClicked?.()\n onExit()\n }, [onExit, onRetryClicked])\n\n const showSuccessScreen = useShowSuccessScreen(\n skipSuccessScreen,\n captureState === 'SUCCESS',\n onComplete,\n )\n\n useEffect(() => {\n if (cameraAccessDenied) {\n setAttempt((n) => n + 1)\n setCaptureState('LOADING')\n }\n }, [cameraAccessDenied])\n\n return (\n <>\n <PageContainer className={`flex ${classNames?.container ?? ''}`}>\n <CameraVideoTag className={classNames.cameraFeed} />\n\n {captureState !== 'LOADING' &&\n (() => {\n switch (captureState) {\n case 'CHECKING_LIVENESS':\n return (\n <FaceLivenessCapture\n onSuccess={onFaceCaptureSuccess}\n onExit={onExit}\n classNames={classNames.faceLiveness}\n colors={colors.faceLiveness}\n verbiage={verbiage.faceLiveness}\n debugMode={debugMode}\n />\n )\n\n case 'CAPTURING_SIGNATURE':\n return (\n <VideoSignatureCapture\n onVideoCaptured={onSignatureCaptureCompleted}\n onFaceNotDetected={onSignatureCaptureFacesNotDetected}\n onExit={onExit}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n )\n\n case 'SUCCESS':\n if (!showSuccessScreen) return\n return (\n <VideoSignatureSuccess\n videoUrl={signatureVideoUrl ?? ''}\n onDoneClick={onComplete}\n onRetryClick={onRetry}\n classNames={classNames.success}\n colors={colors.success}\n verbiage={verbiage.success}\n />\n )\n\n default:\n return null\n }\n })()}\n </PageContainer>\n\n <SelfieCaptureLoadingOverlay\n key={attempt}\n mode={loadingOverlayMode}\n assets={assets.loadingOverlay}\n classNames={classNames.loadingOverlay}\n colors={colors.loadingOverlay}\n verbiage={verbiage.loadingOverlay}\n onDismissed={onLoadingOverlayDismissed}\n onUserCancel={onUserCancel}\n />\n </>\n )\n}\n","import React, { ReactElement, useContext, useEffect, useState } from 'react'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport styled from 'styled-components'\n\nexport type IdVideoCaptureFlipIdPromptAssets = {\n frontImageUrl?: string\n backImageUrl?: string\n}\n\nexport type IdVideoCaptureFlipIdPromptProps = {\n className?: string\n imageWidth?: number\n imageHeight?: number\n borderWidth?: number\n assets?: IdVideoCaptureFlipIdPromptAssets\n}\n\nexport const IdVideoCaptureFlipIdPrompt = ({\n className,\n imageWidth,\n imageHeight,\n borderWidth = 4,\n assets = {},\n}: IdVideoCaptureFlipIdPromptProps): ReactElement => {\n const { cameraRef } = useContext(CameraStateContext)\n\n assets.frontImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const isMirrored = !cameraRef.current?.isRearFacing\n\n const [transitionTime, setTransitionTime] = useState(1)\n const [rotationAngle, setRotationAngle] = useState(0)\n const frontTransforms = [`rotateY(${rotationAngle}deg)`]\n if (isMirrored) frontTransforms.push('scaleX(-1)')\n const backTransforms = [`rotateY(${180 - rotationAngle}deg)`]\n if (isMirrored) backTransforms.push('scaleX(-1)')\n\n useEffect(() => {\n let timeout: NodeJS.Timeout\n\n function doFlip() {\n setTransitionTime(1)\n setRotationAngle(180)\n\n timeout = setTimeout(() => {\n setTransitionTime(0)\n setRotationAngle(0)\n }, 1500)\n }\n\n const interval = setInterval(doFlip, 2500)\n timeout = setTimeout(doFlip, 250)\n\n return () => {\n clearInterval(interval)\n clearTimeout(timeout)\n }\n }, [])\n\n return (\n <>\n <FlipImage\n src={assets.frontImageUrl}\n alt=\"\"\n className={className}\n $transforms={frontTransforms.join(' ')}\n $transitionTime={transitionTime}\n $borderWidth={borderWidth}\n $imageWidth={imageWidth!}\n $imageHeight={imageHeight!}\n />\n\n <FlipImage\n src={assets.backImageUrl}\n alt=\"\"\n className={className}\n $transforms={backTransforms.join(' ')}\n $transitionTime={transitionTime}\n $borderWidth={borderWidth}\n $imageWidth={imageWidth!}\n $imageHeight={imageHeight!}\n $isBack\n />\n </>\n )\n}\n\nconst FlipImage = styled.img<{\n $transforms: string\n $transitionTime: number\n $borderWidth: number\n $imageWidth: number\n $imageHeight: number\n $isBack?: boolean\n}>`\n backface-visibility: hidden;\n transition: transform ${(props) => props.$transitionTime}s;\n transform: ${(props) => props.$transforms};\n transform-style: preserve-3d;\n position: ${(props) => (props.$isBack ? 'absolute' : 'relative')};\n display: block;\n top: ${(props) => -props.$borderWidth / 2}px;\n width: ${(props) => props.$imageWidth}px;\n height: ${(props) => props.$imageHeight + props.$borderWidth}px;\n`\n","import React, { ReactElement, useContext, useRef, useState } from 'react'\nimport { DEFAULT_CDN_URL } from '../common/cdn'\nimport { IdVideoCaptureFlipIdPrompt } from './IdVideoCaptureFlipIdPrompt'\nimport { CustomerSuppliedVerbiage, useTranslations } from '../../lib/locales'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport styled, { useTheme } from 'styled-components'\nimport { GuidanceMessage } from '../common/GuidanceMessage'\n\nexport type Action = 'SHOW_ID_FRONT' | 'FLIP_ID' | 'SHOW_ID_BACK' | 'READ_TEXT'\n\nexport type IdVideoCaptureGuidesAssets = {\n frontImageUrl?: string\n backImageUrl?: string\n}\n\nexport type IdVideoCaptureGuidesClassNames = {\n container?: string\n faceGuide?: string\n idCardGuideContainer?: string\n idCardGuideInstructionsContainer?: string\n idCardGuideInstructions?: string\n idCardGuideImageContainer?: string\n idCardGuideImage?: string\n flipIdPromptImage?: string\n}\n\nexport type IdVideoCaptureGuidesVerbiage = {\n idFrontInstructionText?: CustomerSuppliedVerbiage\n idBackInstructionText?: CustomerSuppliedVerbiage\n flipIdInstructionText?: CustomerSuppliedVerbiage\n}\n\nexport type IdVideoCaptureGuidesProps = {\n requestedAction?: Action\n satisfied?: boolean\n faceGuideBorderWidth?: number\n faceGuideBorderColor?: string\n idCardGuideBorderWidth?: number\n idCardGuideBorderColor?: string\n assets?: IdVideoCaptureGuidesAssets\n classNames?: IdVideoCaptureGuidesClassNames\n verbiage?: IdVideoCaptureGuidesVerbiage\n}\n\nexport const IdVideoCaptureGuides = ({\n requestedAction = 'SHOW_ID_FRONT',\n satisfied = false,\n faceGuideBorderWidth,\n faceGuideBorderColor,\n idCardGuideBorderWidth,\n idCardGuideBorderColor,\n assets = {},\n classNames = {},\n verbiage: rawVerbiage = {},\n}: IdVideoCaptureGuidesProps): ReactElement => {\n const { cameraRef } = useContext(CameraStateContext)\n const imageRef = useRef<HTMLImageElement | null>(null)\n const [imageWidth, setImageWidth] = useState(0)\n const [imageHeight, setImageHeight] = useState(0)\n assets.frontImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Front-SVG-Landscape-2.svg`\n assets.backImageUrl ||= `${DEFAULT_CDN_URL}/Shieldout-IDCard-Back-SVG-Landscape-2.svg`\n\n const verbiage = useTranslations(rawVerbiage, {\n idFrontInstructionText: 'Display the front of your ID card...',\n idBackInstructionText: 'Display the back of your ID card...',\n flipIdInstructionText: 'Please flip your ID card...',\n })\n\n const instructionText =\n requestedAction === 'SHOW_ID_FRONT'\n ? verbiage.idFrontInstructionText\n : requestedAction === 'FLIP_ID'\n ? verbiage.flipIdInstructionText\n : verbiage.idBackInstructionText\n\n const theme = useTheme()\n if (faceGuideBorderWidth === undefined)\n faceGuideBorderWidth = theme.idVideoCapture?.faceGuides?.borderWidth ?? 4\n if (faceGuideBorderColor === undefined)\n faceGuideBorderColor =\n (satisfied\n ? theme.idVideoCapture?.faceGuides?.satisfiedColor\n : theme.idVideoCapture?.faceGuides?.unsatisfiedColor) ?? 'white'\n\n if (idCardGuideBorderWidth === undefined)\n idCardGuideBorderWidth =\n theme.idVideoCapture?.idCardGuides?.borderWidth ?? 4\n if (idCardGuideBorderColor === undefined)\n idCardGuideBorderColor =\n (satisfied\n ? theme.idVideoCapture?.idCardGuides?.satisfiedColor\n : theme.idVideoCapture?.idCardGuides?.unsatisfiedColor) ?? 'white'\n\n const captureImageSize = () => {\n if (!imageWidth) setImageWidth(imageRef.current?.width ?? 0)\n if (!imageHeight) setImageHeight(imageRef.current?.height ?? 0)\n }\n\n return (\n <Container className={classNames.container}>\n <FaceGuide\n className={classNames.faceGuide}\n $borderWidth={faceGuideBorderWidth}\n $borderColor={faceGuideBorderColor}\n />\n\n <IdCardGuideContainer className={classNames.idCardGuideContainer}>\n <IdCardGuideInstructionsContainer\n className={classNames.idCardGuideInstructionsContainer}\n >\n <IdCardGuideInstructions\n className={classNames.idCardGuideInstructions}\n $textColor={\n theme.idVideoCapture?.idCardGuides?.instructionsTextColor\n }\n $background={\n theme.idVideoCapture?.idCardGuides?.instructionsBackgroundColor\n }\n >\n {instructionText}\n </IdCardGuideInstructions>\n </IdCardGuideInstructionsContainer>\n\n <IdCardGuideImageContainer\n $borderWidth={idCardGuideBorderWidth}\n $borderColor={idCardGuideBorderColor}\n className={classNames.idCardGuideImageContainer}\n >\n {requestedAction === 'FLIP_ID' ? (\n <IdVideoCaptureFlipIdPrompt\n assets={assets}\n imageWidth={imageWidth}\n imageHeight={imageHeight}\n borderWidth={idCardGuideBorderWidth}\n className={classNames.flipIdPromptImage}\n />\n ) : (\n <IdCardGuideImage\n ref={imageRef}\n src={\n requestedAction === 'SHOW_ID_BACK'\n ? assets.backImageUrl\n : assets.frontImageUrl\n }\n alt=\"\"\n className={classNames.idCardGuideImage}\n $isMirrored={!cameraRef.current?.isRearFacing}\n onLoad={captureImageSize}\n onResize={captureImageSize}\n />\n )}\n </IdCardGuideImageContainer>\n </IdCardGuideContainer>\n </Container>\n )\n}\n\nconst Container = styled.div`\n position: fixed;\n z-index: 1000;\n width: 100dvw;\n height: 100dvh;\n display: flex;\n flex-direction: column;\n font-family: ${(props) => props.theme?.fontFamily};\n`\n\nconst FaceGuide = styled.div<{ $borderWidth?: number; $borderColor?: string }>`\n border-width: ${(props) => props.$borderWidth ?? 0}px;\n border-color: ${(props) => props.$borderColor ?? 'white'};\n border-style: solid;\n border-radius: 50%;\n aspect-ratio: 1 / 1.618;\n height: 50%;\n min-height: 33dvh;\n margin: 4% auto auto;\n`\n\nconst IdCardGuideContainer = styled.div`\n height: 50%;\n padding: 0 40px;\n display: flex;\n flex-flow: column nowrap;\n margin: 2% auto;\n`\n\nexport const IdCardGuideInstructionsContainer = styled.div`\n width: 100%;\n text-align: center;\n color: white;\n display: flex;\n flex-direction: column;\n justify-content: end;\n`\n\nexport const IdCardGuideInstructions = styled(GuidanceMessage)`\n align-content: center;\n margin-top: 12px;\n margin-bottom: 12px;\n padding: 8px 12px;\n font-weight: bold;\n`\n\nconst IdCardGuideImageContainer = styled.div<{\n $borderWidth?: number\n $borderColor?: string\n}>`\n position: relative;\n border: ${(props) => props.$borderWidth}px solid\n ${(props) => props.$borderColor};\n`\n\nconst IdCardGuideImage = styled.img<{ $isMirrored?: boolean }>`\n width: 100%;\n max-height: 100%;\n ${(props) => (props.$isMirrored ? 'transform: scaleX(-1);' : '')}\n`\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport { LoaderButton } from '../common/LoaderButton'\nimport {\n CustomerSuppliedVerbiage,\n useTranslations,\n useVerbiage,\n} from '../../lib/locales'\nimport styled from 'styled-components'\nimport { ButtonsRow } from '../common/ButtonsRow'\n\nexport type ReadTextPromptClassNames = {\n container?: string\n heading?: string\n prompt?: string\n buttonsRow?: string\n timeRemaining?: string\n doneBtn?: string\n}\n\nexport type ReadTextPromptVerbiage = {\n headingText?: CustomerSuppliedVerbiage\n doneBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type ReadTextPromptProps = {\n text: CustomerSuppliedVerbiage\n onComplete?: () => void\n startedAt?: Date\n durationMs?: number\n minReadingMs?: number\n classNames?: ReadTextPromptClassNames\n verbiage?: ReadTextPromptVerbiage\n}\n\nexport const ReadTextPrompt = ({\n text,\n onComplete,\n durationMs = 15000,\n minReadingMs = 10000,\n classNames = {},\n verbiage: rawVerbiage = {},\n}: ReadTextPromptProps) => {\n text = useVerbiage(text, '')\n const countdownTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)\n const [countdownRemaining, setCountdownRemaining] = useState(\n durationMs / 1000,\n )\n\n const verbiage = useTranslations(rawVerbiage, {\n headingText: 'Please read the following text aloud',\n doneBtnText: 'Done',\n })\n\n const manualCountdown = useCallback((remainingTime: number) => {\n if (remainingTime > 0) {\n const nextCycle = remainingTime - 1\n setCountdownRemaining(nextCycle)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(nextCycle),\n 1000,\n )\n }\n }, [])\n\n useEffect(() => {\n setCountdownRemaining(countdownRemaining)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(countdownRemaining),\n 1000,\n )\n\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [countdownRemaining, manualCountdown])\n\n const [minReadingTimeElapsed, setMinReadingTimeElapsed] = useState(false)\n\n useEffect(\n function trackReadingTime() {\n const timeout = setTimeout(() => {\n setMinReadingTimeElapsed(true)\n }, minReadingMs)\n\n return () => {\n clearTimeout(timeout)\n }\n },\n [minReadingMs],\n )\n\n return (\n <ReadTextPromptContainer className={classNames.container}>\n <ReadTextPromptHeading className={classNames.heading}>\n {verbiage.headingText}\n </ReadTextPromptHeading>\n\n <ReadTextPromptText className={classNames.prompt}>\n {text}\n </ReadTextPromptText>\n\n <ReadTextPromptButtonsRow className={classNames.buttonsRow}>\n <ReadTextPromptTimeRemaining className={classNames.timeRemaining}>\n {countdownRemaining}\n </ReadTextPromptTimeRemaining>\n\n <DoneButton\n variant=\"positive\"\n className={classNames.doneBtn}\n onClick={minReadingTimeElapsed ? onComplete : undefined}\n disabled={!minReadingTimeElapsed}\n finished\n >\n {verbiage.doneBtnText}\n </DoneButton>\n </ReadTextPromptButtonsRow>\n </ReadTextPromptContainer>\n )\n}\n\nconst ReadTextPromptContainer = styled.div`\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n`\n\nconst ReadTextPromptHeading = styled.div`\n padding: 20px;\n font-weight: bold;\n margin: auto auto 32px;\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.heading?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.heading?.borderRadius};`\n : ``};\n`\n\nconst ReadTextPromptText = styled.div`\n margin: 0 auto;\n text-align: center;\n padding: 50px;\n font-size: 24px;\n max-width: ${typeof window !== 'undefined' &&\n window.innerWidth > window.innerHeight\n ? '40%'\n : '90%'};\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.prompt?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.prompt?.borderRadius};`\n : ``};\n`\n\nconst ReadTextPromptButtonsRow = styled(ButtonsRow)`\n margin: 32px auto auto;\n gap: 20px;\n`\n\nconst ReadTextPromptTimeRemaining = styled.div`\n padding: 20px;\n\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.backgroundColor\n ? `background: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.backgroundColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.textColor\n ? `color: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.textColor};`\n : ``};\n ${(props) =>\n props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.borderRadius\n ? `border-radius: ${props.theme.idVideoCapture?.readTextPrompt?.timeRemaining?.borderRadius};`\n : ``};\n`\n\nconst DoneButton = styled(LoaderButton)`\n margin: auto 0;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { PageContainer } from '../common/Page'\nimport { SelfieGuidanceModelsContext } from '../selfie_capture/SelfieGuidanceModelsProvider'\nimport {\n DebugBoundingBoxOverlay,\n DebugStatsPane,\n IdCaptureDetectedObjectDebugBox,\n ObjectDetectionDebugOverlayDiv,\n SelfieCaptureFaceDebugBox,\n useDebugScalingDetails,\n} from '../common/debug'\nimport { CameraStateContext } from '../camera/CameraProvider'\nimport useResizeObserver from 'use-resize-observer'\nimport { IdCaptureModelsContext } from '../id_capture/IdCaptureModelsProvider'\nimport {\n IdVideoCaptureGuides,\n IdVideoCaptureGuidesAssets,\n IdVideoCaptureGuidesClassNames,\n IdVideoCaptureGuidesVerbiage,\n} from './IdVideoCaptureGuides'\nimport { useVideoRecorder } from '../../lib/camera/useVideoRecorder'\nimport {\n CustomerSuppliedVerbiage,\n useTranslations,\n useVerbiage,\n} from '../../lib/locales'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { LoaderButton, LoaderButtonColors } from '../common/LoaderButton'\nimport {\n ReadTextPrompt,\n ReadTextPromptClassNames,\n ReadTextPromptVerbiage,\n} from '../read_text_prompt/ReadTextPrompt'\nimport {\n GuidanceMessage,\n GuidanceMessageContainer,\n} from '../common/GuidanceMessage'\nimport styled, { useTheme } from 'styled-components'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { DetectedObject } from '../../lib/models/DocumentDetection'\nimport { Face } from '../../lib/models/FaceDetection'\n\nexport type Action = 'SHOW_ID_FRONT' | 'FLIP_ID' | 'SHOW_ID_BACK' | 'READ_TEXT'\n\nconst edgeBoundary = 0.05\n\nexport type IdVideoCaptureAssets = {\n guides?: IdVideoCaptureGuidesAssets\n}\n\nexport type IdVideoCaptureClassNames = {\n container?: string\n cameraFeed?: string\n guides?: IdVideoCaptureGuidesClassNames\n guidanceMessageContainer?: string\n guidanceMessage?: string\n readTextPrompt?: ReadTextPromptClassNames\n countdownContainer?: string\n countdown?: string\n captureBtnContainer?: string\n captureBtn?: string\n}\n\nexport type IdVideoCaptureColors = {\n guidesSatisfiedColor?: string\n guidesUnsatisfiedColor?: string\n readTextDoneBtn?: LoaderButtonColors\n}\n\nexport type IdVideoCaptureVerbiage = {\n guides?: IdVideoCaptureGuidesVerbiage\n readTextPrompt?: ReadTextPromptVerbiage\n faceNotCenteredText?: CustomerSuppliedVerbiage\n searchingForIdCardText?: CustomerSuppliedVerbiage\n captureBtnText?: CustomerSuppliedVerbiage\n}\n\nexport type IdVideoCaptureProps = {\n onComplete?: (videoUrl: string, audioUrl: string | null) => void\n onIdFrontImageCaptured?: (imageUrl: string) => void\n onIdBackImageCaptured?: (imageUrl: string) => void\n onFaceNotDetected?: () => void\n onRecordingFailed?: () => void\n\n idCaptureModelsEnabled?: boolean\n idCardFrontDelay?: number\n idCardFrontDetectionThreshold?: number\n idCardBackDetectionThreshold?: number\n idCardFrontFocusThreshold?: number\n idCardBackFocusThreshold?: number\n goodIdCardFrontFramesThreshold?: number\n goodIdCardBackFramesThreshold?: number\n skipShowIdCardBack?: boolean | (() => Promise<boolean>)\n captureCountdownSeconds?: number\n readTextPrompt?: CustomerSuppliedVerbiage\n readTextTimeoutDurationMs?: number\n readTextMinReadingMs?: number\n disableFaceDetectionWhileAudioCapture: boolean\n disableFaceDetectionWhileAudioCaptureMsDelay: number\n mergeAVStreams?: boolean\n\n assets?: IdVideoCaptureAssets\n classNames?: IdVideoCaptureClassNames\n colors?: IdVideoCaptureColors\n verbiage?: IdVideoCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const IdVideoCapture = ({\n onComplete,\n onIdFrontImageCaptured,\n onIdBackImageCaptured,\n onFaceNotDetected,\n onRecordingFailed,\n\n idCaptureModelsEnabled = true,\n idCardFrontDelay = 1000,\n idCardFrontDetectionThreshold = 0.6,\n idCardFrontFocusThreshold = 0,\n goodIdCardFrontFramesThreshold = 1,\n idCardBackDetectionThreshold = 0.6,\n idCardBackFocusThreshold = 0,\n goodIdCardBackFramesThreshold = 1,\n skipShowIdCardBack = false,\n captureCountdownSeconds = 3,\n readTextPrompt,\n readTextTimeoutDurationMs = 15000,\n readTextMinReadingMs = 10000,\n disableFaceDetectionWhileAudioCapture = false,\n disableFaceDetectionWhileAudioCaptureMsDelay = 2000,\n mergeAVStreams = false,\n\n assets = {},\n classNames = {},\n colors = {},\n verbiage: rawVerbiage = {},\n debugMode = false,\n}: IdVideoCaptureProps): ReactElement => {\n const { ref, width = 1, height = 1 } = useResizeObserver<HTMLDivElement>()\n const {\n cameraRef,\n videoRef,\n videoLoaded,\n cameraReady,\n microphoneReady,\n audioStream,\n setVideoLoaded,\n takePhoto,\n } = useContext(CameraStateContext)\n const [detectedObjects, setDetectedObjects] = useState<DetectedObject[]>([])\n const [faces, setFaces] = useState<Face[]>([])\n const {\n ready: idModelsReady,\n start: startIdModels,\n stop: stopIdModels,\n onPredictionMade: onIdPredictionMade,\n setThresholds,\n bestFrameDetails,\n resetBestFrame,\n modelError: idModelError,\n } = useContext(IdCaptureModelsContext)\n const [videoStartsAt, setVideoStartsAt] = useState<Date | null>(null)\n const { setIdCaptureVideoAudioStartsAt, setExpectedAudioText } =\n useContext(SubmissionContext)\n const { onPredictionMade: onSelfiePredictionMade, error: selfieModelError } =\n useContext(SelfieGuidanceModelsContext)\n const {\n isRecordingVideo,\n startRecordingVideo,\n startRecordingAudio,\n stopRecordingVideo,\n stopRecordingAudio,\n videoRecordingUnintentionallyStopped,\n audioRecordingUnintentionallyStopped,\n videoUrl,\n audioUrl,\n } = useVideoRecorder(cameraRef.current, audioStream, mergeAVStreams)\n const countdownTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined)\n const [countdownRemaining, setCountdownRemaining] = useState(0)\n\n useEffect(() => {\n if (!isRecordingVideo && !videoUrl) {\n startRecordingVideo()\n setVideoStartsAt(new Date())\n }\n\n // if the mergeAVStreams flag is present, the audio stream is on the video\n // stream, so we won't wait for a separate data url containing audio only.\n const needsAudio = !!readTextPrompt && !mergeAVStreams\n const audioReady = !needsAudio || audioUrl\n if (videoUrl && audioReady) {\n setVideoLoaded(false)\n onComplete?.(videoUrl, audioUrl)\n }\n }, [\n audioUrl,\n isRecordingVideo,\n mergeAVStreams,\n onComplete,\n readTextPrompt,\n setVideoLoaded,\n startRecordingVideo,\n videoUrl,\n ])\n\n useEffect(() => {\n if (\n videoRecordingUnintentionallyStopped ||\n audioRecordingUnintentionallyStopped\n ) {\n onRecordingFailed?.()\n }\n }, [\n audioRecordingUnintentionallyStopped,\n onRecordingFailed,\n videoRecordingUnintentionallyStopped,\n ])\n\n const shouldCaptureFrames = useRef(false)\n\n useEffect(() => {\n shouldCaptureFrames.current =\n videoLoaded &&\n cameraReady &&\n idModelsReady &&\n !idModelError &&\n (!readTextPrompt || microphoneReady)\n }, [\n cameraReady,\n idModelError,\n idModelsReady,\n microphoneReady,\n readTextPrompt,\n videoLoaded,\n ])\n\n const [requestedAction, setRequestedAction] =\n useState<Action>('SHOW_ID_FRONT')\n\n useEffect(\n function startModelsWhenCapturing() {\n if (\n !shouldCaptureFrames.current &&\n requestedAction !== 'SHOW_ID_FRONT' &&\n requestedAction !== 'SHOW_ID_BACK'\n )\n return\n\n startIdModels()\n return () => {\n stopIdModels()\n }\n },\n [requestedAction, startIdModels, stopIdModels],\n )\n\n useEffect(() => {\n setThresholds({\n idCard:\n requestedAction === 'SHOW_ID_FRONT'\n ? idCardFrontDetectionThreshold\n : requestedAction === 'SHOW_ID_BACK'\n ? idCardBackDetectionThreshold\n : 1,\n passport: 1,\n focus: {\n idCard: {\n mobile:\n requestedAction === 'SHOW_ID_FRONT'\n ? idCardFrontFocusThreshold\n : requestedAction === 'SHOW_ID_BACK'\n ? idCardBackFocusThreshold\n : 0,\n },\n },\n })\n }, [\n idCardBackDetectionThreshold,\n idCardBackFocusThreshold,\n idCardFrontDetectionThreshold,\n idCardFrontFocusThreshold,\n requestedAction,\n setThresholds,\n ])\n\n const [currentDetectionScore, setCurrentDetectionScore] = useState(0)\n const [currentFocusScore, setCurrentFocusScore] = useState(0)\n const [goodFramesCount, setGoodFramesCount] = useState(0)\n const goodFramesThreshold =\n requestedAction === 'SHOW_ID_FRONT'\n ? goodIdCardFrontFramesThreshold\n : goodIdCardBackFramesThreshold\n const goodFramesThresholdMet = goodFramesCount >= goodFramesThreshold\n useEffect(() => {\n if (!idCaptureModelsEnabled || idModelError) return\n onIdPredictionMade((prediction) => {\n setDetectedObjects(prediction.detectedObjects)\n setCurrentDetectionScore(prediction.detectionScore)\n setCurrentFocusScore(prediction.focusScore)\n\n if (prediction.detectionThresholdMet && prediction.focusThresholdMet) {\n setGoodFramesCount((n) => n + 1)\n } else {\n setGoodFramesCount(0)\n }\n })\n }, [\n idCaptureModelsEnabled,\n idCardFrontDetectionThreshold,\n onIdPredictionMade,\n idModelError,\n ])\n\n const [idFrontCaptureStartedAt, setFirstGoodFrameTime] = useState<\n number | null\n >(null)\n\n useEffect(() => {\n if (goodFramesCount === 1) setFirstGoodFrameTime(new Date().getTime())\n }, [goodFramesCount])\n\n const delaySatisfied =\n requestedAction !== 'SHOW_ID_FRONT' ||\n (idFrontCaptureStartedAt !== null &&\n new Date().getTime() > idFrontCaptureStartedAt + idCardFrontDelay)\n\n const translatedText = useVerbiage(readTextPrompt, '')\n const onIdBackCaptureComplete = useCallback(() => {\n if (translatedText) {\n setRequestedAction('READ_TEXT')\n startRecordingAudio()\n setIdCaptureVideoAudioStartsAt(\n new Date().getTime() - (videoStartsAt?.getTime() ?? 0),\n )\n setExpectedAudioText(translatedText)\n } else {\n stopRecordingVideo()\n }\n }, [\n setExpectedAudioText,\n setIdCaptureVideoAudioStartsAt,\n startRecordingAudio,\n stopRecordingVideo,\n translatedText,\n videoStartsAt,\n ])\n\n const frameWidth = videoRef.current?.videoWidth ?? 0\n const frameHeight = videoRef.current?.videoHeight ?? 0\n const faceBox = faces?.[0]?.box\n const faceCentered =\n !faceBox ||\n !frameWidth ||\n (faceBox.xMin > frameWidth * edgeBoundary &&\n faceBox.yMin > frameHeight * edgeBoundary &&\n faceBox.xMax < frameWidth * (1 - edgeBoundary) &&\n faceBox.yMax < frameHeight * (1 - edgeBoundary))\n\n const [countdownStartedAt, setCountdownStartedAt] = useState<Date>()\n\n const frameLock = useRef(false)\n const captureFrame = useCallback(async () => {\n if (frameLock.current) return\n frameLock.current = true\n\n const frame = await takePhoto()\n if (!frame) {\n frameLock.current = false\n return\n }\n\n try {\n const frameBase64 =\n frame &&\n (await new Promise<string>((resolve) => {\n const reader = new FileReader()\n reader.onloadend = () => resolve(reader.result as string)\n reader.readAsDataURL(frame)\n }))\n\n if (requestedAction == 'SHOW_ID_FRONT') {\n if (onIdFrontImageCaptured) {\n frameBase64 && onIdFrontImageCaptured(frameBase64)\n }\n\n if (skipShowIdCardBack) {\n if (skipShowIdCardBack === true) {\n return onIdBackCaptureComplete()\n } else if (await skipShowIdCardBack()) {\n return onIdBackCaptureComplete()\n }\n }\n\n setRequestedAction('FLIP_ID')\n setTimeout(() => {\n setRequestedAction('SHOW_ID_BACK')\n }, 6000)\n } else if (requestedAction == 'SHOW_ID_BACK') {\n if (onIdBackImageCaptured) {\n frameBase64 && onIdBackImageCaptured(frameBase64)\n }\n\n onIdBackCaptureComplete()\n }\n } finally {\n setDetectedObjects([])\n setCurrentDetectionScore(0)\n setCurrentFocusScore(0)\n setGoodFramesCount(0)\n setCountdownStartedAt(undefined)\n resetBestFrame()\n frameLock.current = false\n if (countdownTimeoutRef.current) {\n clearTimeout(countdownTimeoutRef.current)\n }\n }\n }, [\n onIdBackCaptureComplete,\n onIdBackImageCaptured,\n onIdFrontImageCaptured,\n requestedAction,\n resetBestFrame,\n skipShowIdCardBack,\n takePhoto,\n ])\n\n const stopRecording = useCallback(() => {\n stopRecordingVideo()\n stopRecordingAudio()\n }, [stopRecordingAudio, stopRecordingVideo])\n\n const satisfied = goodFramesThresholdMet && faceCentered && delaySatisfied\n\n useEffect(() => {\n if (satisfied && !countdownStartedAt) {\n setCountdownStartedAt(new Date())\n }\n }, [countdownStartedAt, satisfied])\n\n useEffect(() => {\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [])\n\n const manualCountdown = useCallback(\n (remainingTime: number) => {\n if (remainingTime > 0) {\n const nextCycle = remainingTime - 1\n setCountdownRemaining(nextCycle)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(nextCycle),\n 1000,\n )\n return\n }\n if (countdownStartedAt) {\n captureFrame()\n }\n },\n [captureFrame, countdownStartedAt, countdownTimeoutRef],\n )\n\n useEffect(() => {\n if (!countdownStartedAt) return\n setCountdownRemaining(captureCountdownSeconds)\n countdownTimeoutRef.current = setTimeout(\n () => manualCountdown(captureCountdownSeconds),\n 1000,\n )\n\n return () => {\n clearTimeout(countdownTimeoutRef.current)\n }\n }, [\n captureCountdownSeconds,\n captureFrame,\n countdownStartedAt,\n manualCountdown,\n ])\n\n const { timeoutStartedAt } = useTimeout(\n readTextTimeoutDurationMs,\n stopRecording,\n requestedAction !== 'READ_TEXT',\n false,\n requestedAction === 'READ_TEXT',\n )\n\n const [numFramesWithoutFaces, setNumFramesWithoutFaces] = useState(0)\n useEffect(() => {\n if (!selfieModelError) {\n onSelfiePredictionMade((faces) => {\n setFaces(faces)\n setNumFramesWithoutFaces((n) => (faces.length === 0 ? n + 1 : 0))\n })\n }\n }, [onSelfiePredictionMade, selfieModelError])\n\n useEffect(() => {\n const ignoreMissingFaces =\n disableFaceDetectionWhileAudioCapture &&\n timeoutStartedAt?.getTime() &&\n new Date().getTime() - timeoutStartedAt?.getTime() >\n disableFaceDetectionWhileAudioCaptureMsDelay\n if (!ignoreMissingFaces && numFramesWithoutFaces >= 2) {\n onFaceNotDetected?.()\n }\n }, [\n disableFaceDetectionWhileAudioCapture,\n disableFaceDetectionWhileAudioCaptureMsDelay,\n numFramesWithoutFaces,\n onFaceNotDetected,\n timeoutStartedAt,\n ])\n\n const theme = useTheme()\n\n const { captureBtnText, faceNotCenteredText, searchingForIdCardText } =\n useTranslations(rawVerbiage, {\n faceNotCenteredText: 'Please move your face to the center...',\n searchingForIdCardText: 'Searching for ID card...',\n captureBtnText: 'Capture',\n })\n\n const debugScalingDetails = useDebugScalingDetails({\n enabled: debugMode,\n pageWidth: width,\n pageHeight: height,\n videoWidth: videoRef.current?.videoWidth ?? 0,\n videoHeight: videoRef.current?.videoHeight ?? 0,\n })\n\n const capturingId = ['SHOW_ID_FRONT', 'SHOW_ID_BACK'].includes(\n requestedAction,\n )\n\n const searchingForIdCard =\n idCaptureModelsEnabled && capturingId && !goodFramesThresholdMet\n const guidanceText = !faceCentered\n ? faceNotCenteredText\n : searchingForIdCard\n ? searchingForIdCardText\n : undefined\n\n return (\n <PageContainer ref={ref} className={`flex ${classNames.container ?? ''}`}>\n {requestedAction === 'READ_TEXT' ? (\n <ReadTextPrompt\n text={readTextPrompt}\n startedAt={timeoutStartedAt || undefined}\n durationMs={readTextTimeoutDurationMs}\n minReadingMs={readTextMinReadingMs}\n classNames={classNames.readTextPrompt}\n verbiage={rawVerbiage.readTextPrompt}\n onComplete={stopRecording}\n />\n ) : (\n <>\n <IdVideoCaptureGuides\n assets={assets.guides}\n classNames={classNames.guides}\n verbiage={rawVerbiage.guides}\n requestedAction={requestedAction}\n satisfied={satisfied}\n faceGuideBorderColor={\n satisfied\n ? colors.guidesSatisfiedColor\n : colors.guidesUnsatisfiedColor\n }\n idCardGuideBorderColor={\n satisfied\n ? colors.guidesSatisfiedColor\n : colors.guidesUnsatisfiedColor\n }\n />\n\n {debugMode && capturingId && (\n <>\n <ObjectDetectionDebugOverlayDiv\n $flipX={!cameraRef.current?.isRearFacing}\n >\n {detectedObjects.map((obj, i) => (\n <IdCaptureDetectedObjectDebugBox\n key={i}\n obj={obj}\n scaling={debugScalingDetails}\n color=\"blue\"\n flipX={!cameraRef.current?.isRearFacing}\n />\n ))}\n </ObjectDetectionDebugOverlayDiv>\n\n <DebugBoundingBoxOverlay>\n {faces.map((face, i) => (\n <SelfieCaptureFaceDebugBox\n key={i}\n face={face}\n scaling={debugScalingDetails}\n />\n ))}\n </DebugBoundingBoxOverlay>\n </>\n )}\n </>\n )}\n\n {guidanceText && idCaptureModelsEnabled && !idModelError && (\n <GuidanceMessageContainer\n className={classNames.guidanceMessageContainer}\n >\n <GuidanceMessage\n className={classNames.guidanceMessage}\n $background={\n theme.guidanceMessages?.negative?.backgroundColor ?? 'red'\n }\n $textColor={theme.guidanceMessages?.negative?.textColor ?? 'white'}\n >\n {guidanceText}\n </GuidanceMessage>\n </GuidanceMessageContainer>\n )}\n\n {debugMode && (\n <DebugStatsPane>\n {cameraRef.current ? (\n <>\n ✅ Camera: {cameraRef.current.label} ({cameraRef.current.width}x\n {cameraRef.current.height})\n </>\n ) : (\n '❌ Camera not ready'\n )}\n <br />\n {isRecordingVideo ? '✅ Recording' : '❌ Not recording'}\n <br />\n {goodFramesThresholdMet ? '✅' : '❌'} Good Frame Count:{' '}\n {goodFramesCount}/{goodFramesThreshold}\n <br />\n Detection Score: {currentDetectionScore}\n <br />\n Focus Score: {currentFocusScore}\n <br />\n Best Frame Detection Score: {bestFrameDetails?.detectionScore ?? 0}\n <br />\n Best Frame Focus Score: {bestFrameDetails?.focusScore ?? 0}\n </DebugStatsPane>\n )}\n\n {!!countdownRemaining && capturingId && (\n <CountdownContainer className={classNames.countdownContainer}>\n <Countdown className={classNames.countdown}>\n {countdownRemaining}\n </Countdown>\n </CountdownContainer>\n )}\n\n {(!idCaptureModelsEnabled || idModelError) && capturingId && (\n <CaptureButtonContainer className={classNames.captureBtnContainer}>\n <CaptureButton\n finished\n onClick={() => {\n setCountdownStartedAt(new Date())\n }}\n disabled={!!countdownStartedAt || frameLock.current}\n className={classNames.captureBtn}\n >\n {captureBtnText}\n </CaptureButton>\n </CaptureButtonContainer>\n )}\n </PageContainer>\n )\n}\n\nconst CountdownContainer = styled.div`\n position: fixed;\n top: 0;\n left: 0;\n width: 100dvw;\n height: 100dvh;\n z-index: 99999;\n display: flex;\n`\n\nconst Countdown = styled.div`\n color: white;\n font-size: 64px;\n font-weight: bold;\n margin: auto;\n`\n\nconst CaptureButtonContainer = styled.div`\n position: fixed;\n bottom: 0;\n width: 100dvw;\n display: flex;\n z-index: 100000;\n`\n\nconst CaptureButton = styled(LoaderButton)`\n margin: 0 auto 25px;\n`\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport {\n IdCaptureSubmission,\n IdCaptureWizard,\n IdCaptureWizardProps,\n} from './id_capture/IdCaptureWizard'\nimport {\n FaceLivenessWizard,\n FaceLivenessWizardProps,\n} from './face_liveness/FaceLivenessWizard'\nimport { IdCaptureModelsProvider } from './id_capture/IdCaptureModelsProvider'\nimport { CameraProvider } from './camera/CameraProvider'\nimport { GuideOrientationProvider } from './GuideOrientationProvider'\nimport {\n SubmissionContext,\n SubmissionProvider,\n} from './submission/SubmissionProvider'\nimport {\n LivenessCheckRequest,\n SubmissionAction,\n SubmissionResponse,\n SubmissionStatus,\n} from '../contexts/SubmissionContext'\nimport { SubmissionSuccess } from './submission/SubmissionSuccess'\nimport { Spinner } from './common/spinner'\nimport {\n AdditionalDocumentCaptureWizard,\n AdditionalDocumentCaptureWizardProps,\n} from './additional_document_capture/AdditionalDocumentCaptureWizard'\nimport {\n SignatureCapture,\n SignatureCaptureProps,\n} from './signature_capture/SignatureCapture'\nimport { SelfieGuidanceModelsProvider } from './selfie_capture/SelfieGuidanceModelsProvider'\nimport {\n VideoSignatureWizard,\n VideoSignatureWizardProps,\n} from './video_signature_capture/VideoSignatureWizard'\nimport { SignatureData } from './signature_capture/data'\nimport { UploadedDocument } from './additional_document_capture/AdditionalDocumentCapture'\nimport { PageContainer } from './common/Page'\nimport {\n VideoIdWizard,\n VideoIdWizardProps,\n} from './video_id/IdVideoCaptureWizard'\nimport { IdCaptureStateProvider } from './id_capture/IdCaptureStateProvider'\nimport { AuthProvider } from '../contexts/AuthStateContext'\n\nexport type CompositeWizardCheck =\n | 'IdCapture'\n | 'FaceLiveness'\n | 'SignatureCapture'\n | 'VideoSignatureCapture'\n | 'AdditionalDocumentCapture'\n | 'VideoIdCapture'\n\nexport type CompositeWizardComponentProps = {\n checks: CompositeWizardCheck[]\n\n idCaptureProps?: IdCaptureWizardProps\n faceLivenessProps?: FaceLivenessWizardProps\n additionalDocumentCaptureProps?: AdditionalDocumentCaptureWizardProps\n signatureCaptureProps?: SignatureCaptureProps\n videoSignatureCaptureProps?: VideoSignatureWizardProps\n videoIdCaptureProps?: VideoIdWizardProps\n captureSignature?: boolean | (() => Promise<boolean>)\n captureSignatureVideo?: boolean | (() => Promise<boolean>)\n\n onCameraAccessDenied?: () => void\n onMicrophoneAccessDenied?: () => void\n\n debugMode?: boolean\n}\n\nexport type CompositeWizardProps = CompositeWizardComponentProps & {\n sessionId: string\n submissionAction?: SubmissionAction\n submissionUrl?: string\n authUrl?: string\n onComplete?: (submissionResponse: SubmissionResponse) => void\n}\n\nexport const CompositeWizard = (props: CompositeWizardProps): ReactElement => (\n <AuthProvider authUrl={props.authUrl} sessionId={props.sessionId}>\n <SubmissionProvider\n action={props.submissionAction ?? SubmissionAction.VALIDATE}\n submissionUrl={props.submissionUrl}\n onResponseReceived={props.onComplete}\n >\n <CompositeWizardComponent {...props} />\n </SubmissionProvider>\n </AuthProvider>\n)\n\nexport const CompositeWizardComponent = ({\n checks: userChecks,\n idCaptureProps = {},\n faceLivenessProps = {},\n additionalDocumentCaptureProps,\n signatureCaptureProps = {},\n videoSignatureCaptureProps = {},\n videoIdCaptureProps = {},\n captureSignature = false,\n captureSignatureVideo = false,\n onCameraAccessDenied,\n onMicrophoneAccessDenied,\n debugMode = false,\n}: CompositeWizardComponentProps): ReactElement => {\n const { submit, submissionStatus, setSignatureData, setAdditionalDocuments } =\n useContext(SubmissionContext)\n const [checkIndex, setCheckIndex] = useState(0)\n const checks = useMemo(() => {\n const checks = [...userChecks]\n if (captureSignature && captureSignatureVideo) {\n throw new Error(\n 'captureSignature and captureSignatureVideo cannot be used together',\n )\n }\n if (captureSignature) {\n checks.push('SignatureCapture')\n }\n if (captureSignatureVideo) {\n checks.push('VideoSignatureCapture')\n // remove face liveness because video signature already has it.\n if (checks.includes('FaceLiveness'))\n checks.splice(checks.indexOf('FaceLiveness'), 1)\n }\n if (additionalDocumentCaptureProps?.documents?.length ?? 0 > 0) {\n checks.push('AdditionalDocumentCapture')\n }\n return checks\n }, [\n additionalDocumentCaptureProps?.documents?.length,\n captureSignature,\n captureSignatureVideo,\n userChecks,\n ])\n const currentCheck = checks[checkIndex]\n const isComplete = checkIndex >= checks.length\n\n useEffect(() => {\n if (\n currentCheck === 'SignatureCapture' &&\n typeof captureSignature === 'function'\n ) {\n captureSignature().then((shouldProceed) => {\n if (!shouldProceed) {\n setCheckIndex((i) => i + 1)\n }\n })\n } else if (\n currentCheck === 'VideoSignatureCapture' &&\n typeof captureSignatureVideo === 'function'\n ) {\n captureSignatureVideo().then((shouldProceed) => {\n if (!shouldProceed) {\n setCheckIndex((i) => i + 1)\n }\n })\n }\n }, [captureSignature, captureSignatureVideo, currentCheck])\n\n useEffect(() => {\n if (isComplete) submit()\n }, [isComplete, submit])\n\n const onIdCaptureSuccessProp = idCaptureProps.onSuccess\n const onIdCaptureSuccess = useCallback(\n (submission: IdCaptureSubmission) => {\n onIdCaptureSuccessProp?.(submission)\n setCheckIndex((i) => i + 1)\n },\n [onIdCaptureSuccessProp],\n )\n\n const onVideoIdCaptureCompleteProp = videoIdCaptureProps.onComplete\n const onVideoIdCaptureComplete = useCallback(() => {\n onVideoIdCaptureCompleteProp?.()\n setCheckIndex((i) => i + 1)\n }, [onVideoIdCaptureCompleteProp])\n\n const onFaceLivenessCompleteProp = faceLivenessProps.onComplete\n const onFaceLivenessComplete = useCallback(\n (resp: SubmissionResponse | null, req: LivenessCheckRequest | null) => {\n onFaceLivenessCompleteProp?.(resp, req)\n setCheckIndex((i) => i + 1)\n },\n [onFaceLivenessCompleteProp],\n )\n\n const onSignatureCaptureSuccess = useCallback(\n (signatureData: SignatureData) => {\n setSignatureData(signatureData)\n setCheckIndex((i) => i + 1)\n },\n [setSignatureData],\n )\n\n const onVideoSignatureCompleteProp = videoSignatureCaptureProps.onComplete\n const onVideoSignatureComplete = useCallback(() => {\n onVideoSignatureCompleteProp?.()\n setCheckIndex((i) => i + 1)\n }, [onVideoSignatureCompleteProp])\n const [videoSignatureAttempts, setVideoSignatureAttempts] = useState(0)\n const onVideoSignatureRetryProp = videoSignatureCaptureProps.onRetryClicked\n const onVideoSignatureRetry = useCallback(() => {\n onVideoSignatureRetryProp?.()\n setVideoSignatureAttempts((n) => n + 1)\n }, [onVideoSignatureRetryProp])\n\n const onAdditionalDocumentCaptureCompleteProp =\n additionalDocumentCaptureProps?.onComplete\n const onAdditionalDocumentCaptureComplete = useCallback(\n (uploadedDocuments: UploadedDocument[]) => {\n setAdditionalDocuments(uploadedDocuments)\n onAdditionalDocumentCaptureCompleteProp?.(uploadedDocuments)\n setCheckIndex((i) => i + 1)\n },\n [onAdditionalDocumentCaptureCompleteProp, setAdditionalDocuments],\n )\n\n const documents = useMemo(\n () => additionalDocumentCaptureProps?.documents ?? [],\n [additionalDocumentCaptureProps?.documents],\n )\n\n if (isComplete) {\n switch (submissionStatus) {\n case SubmissionStatus.SUBMITTING:\n return (\n <PageContainer className=\"flex\">\n <Spinner />\n </PageContainer>\n )\n\n case SubmissionStatus.SUBMITTED:\n return <SubmissionSuccess />\n\n case SubmissionStatus.FAILED:\n return <>Submission failed!</>\n\n default:\n return <>Complete!!</>\n }\n }\n\n switch (checks[checkIndex]) {\n case 'IdCapture':\n return (\n <CameraProvider\n key=\"IdCaptureCamera\"\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <IdCaptureModelsProvider\n autoStart={false}\n documentDetectionModelUrl={\n idCaptureProps.assets?.documentDetectionModelUrl ?? ''\n }\n focusModelUrl={idCaptureProps.assets?.focusModelUrl ?? ''}\n onModelError={idCaptureProps.onModelError}\n modelLoadTimeoutMs={idCaptureProps.modelLoadTimeoutMs}\n >\n <IdCaptureStateProvider>\n <GuideOrientationProvider>\n <IdCaptureWizard\n {...idCaptureProps}\n onSuccess={onIdCaptureSuccess}\n />\n </GuideOrientationProvider>\n </IdCaptureStateProvider>\n </IdCaptureModelsProvider>\n </CameraProvider>\n )\n\n case 'VideoIdCapture':\n return (\n <VideoIdWizard\n {...videoIdCaptureProps}\n onComplete={onVideoIdCaptureComplete}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n />\n )\n\n case 'FaceLiveness':\n return (\n <CameraProvider\n key=\"FaceLivenessCamera\"\n preferFrontFacingCamera={true}\n preferContinuityCamera={false}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <SelfieGuidanceModelsProvider\n autoStart={false}\n onModelError={faceLivenessProps.onModelError}\n modelLoadTimeoutMs={faceLivenessProps.modelLoadTimeoutMs}\n >\n <FaceLivenessWizard\n {...faceLivenessProps}\n onComplete={onFaceLivenessComplete}\n />\n </SelfieGuidanceModelsProvider>\n </CameraProvider>\n )\n\n case 'SignatureCapture':\n return (\n <SignatureCapture\n {...signatureCaptureProps}\n onAccept={onSignatureCaptureSuccess}\n />\n )\n\n case 'VideoSignatureCapture':\n return (\n <CameraProvider\n key={`SignatureKycCamera-${videoSignatureAttempts}`}\n preferContinuityCamera={false}\n preferFrontFacingCamera={true}\n maxVideoWidth={1280}\n maxFps={30}\n onCameraAccessDenied={onCameraAccessDenied}\n onMicrophoneAccessDenied={onMicrophoneAccessDenied}\n debugMode={debugMode}\n >\n <SelfieGuidanceModelsProvider\n autoStart={false}\n throttleMs={250}\n onModelError={videoSignatureCaptureProps.onModelError}\n modelLoadTimeoutMs={videoSignatureCaptureProps.modelLoadTimeoutMs}\n >\n <VideoSignatureWizard\n {...videoSignatureCaptureProps}\n onComplete={onVideoSignatureComplete}\n onRetryClicked={onVideoSignatureRetry}\n />\n </SelfieGuidanceModelsProvider>\n </CameraProvider>\n )\n\n case 'AdditionalDocumentCapture':\n return (\n <AdditionalDocumentCaptureWizard\n {...additionalDocumentCaptureProps}\n documents={documents}\n onComplete={onAdditionalDocumentCaptureComplete}\n />\n )\n\n default:\n return <></>\n }\n}\n","import React, { ReactNode, useEffect } from 'react'\nimport {\n DefaultTheme,\n ThemeProvider as ScThemeProvider,\n} from 'styled-components'\nimport { Color } from './color'\n\nexport interface Theme {\n isFullscreen?: boolean\n fontFamily?: string\n background?: string\n padding?: string\n textAlign?: string\n textColor?: string\n\n colors?: {\n primary?: Color\n secondary?: Color\n positive?: Color\n negative?: Color\n warning?: Color\n }\n\n buttons?: {\n style?: 'bootstrap' | 'none'\n primary?: {\n backgroundColor?: string\n textColor?: string\n }\n secondary?: {\n backgroundColor?: string\n textColor?: string\n }\n positive?: {\n backgroundColor?: string\n textColor?: string\n }\n negative?: {\n backgroundColor?: string\n textColor?: string\n }\n warning?: {\n backgroundColor?: string\n textColor?: string\n }\n loading?: {\n backgroundColor?: string\n textColor?: string\n }\n }\n\n guidanceMessages?: {\n default?: {\n backgroundColor?: string\n textColor?: string\n }\n positive?: {\n backgroundColor?: string\n textColor?: string\n }\n negative?: {\n backgroundColor?: string\n textColor?: string\n }\n }\n\n idCapture?: {\n loadingOverlay?: {\n backgroundColor?: string\n textColor?: string\n loadingGraphicAccentColor?: string\n loadingGraphicAccentOpacity?: number\n progressBarBackgroundColor?: string\n progressBarBackgroundOpacity?: number\n progressBarIndicatorColor?: string\n progressBarTextColor?: string\n progressBarFontSize?: string\n continueBtnBorder?: string\n }\n guideOverlay?: {\n backgroundColor?: string\n textColor?: string\n }\n guideBox?: {\n unsatisfiedColor?: string\n satisfiedColor?: string\n borderWidth?: number\n desktopPadding?: number\n mobilePadding?: number\n imagePadding?: number\n }\n capturePreview?: {\n disabled?: boolean\n }\n success?: {\n imageBorderColor?: string\n }\n }\n\n selfieCapture?: {\n loadingOverlay?: {\n backgroundColor?: string\n textColor?: string\n loadingGraphicAccentColor?: string\n progressBarBackgroundOpacity?: number\n progressBarBackgroundColor?: string\n progressBarIndicatorColor?: string\n progressBarTextColor?: string\n progressBarFontSize?: string\n continueBtnBorder?: string\n }\n guides?: {\n unsatisfiedColor?: string\n satisfiedColor?: string\n }\n capturePreview?: {\n disabled?: boolean\n }\n }\n\n signatureCapture?: {\n background?: string\n backgroundSize?: string\n backgroundPosition?: string\n\n canvas?: {\n background?: string\n border?: string\n borderRadius?: string\n }\n }\n\n idVideoCapture?: {\n faceGuides?: {\n borderWidth?: number\n unsatisfiedColor?: string\n satisfiedColor?: string\n }\n\n idCardGuides?: {\n borderWidth?: number\n unsatisfiedColor?: string\n satisfiedColor?: string\n instructionsTextColor?: string\n instructionsBackgroundColor?: string\n }\n\n readTextPrompt?: {\n heading?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n prompt?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n timeRemaining?: {\n backgroundColor?: string\n textColor?: string\n borderRadius?: string\n }\n }\n }\n\n documentCapture?: {\n guideBox?: {\n borderWidth?: number\n mobilePadding?: number\n desktopPadding?: number\n maskColor?: string\n }\n instructions?: {\n maxHeight?: number\n }\n }\n}\n\nconst noneTheme = {} satisfies Theme\nconst defaultTheme = {\n fontFamily: `Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif`,\n isFullscreen: true,\n background: 'white',\n textColor: 'black',\n textAlign: 'center',\n padding: '25px',\n\n colors: {\n primary: {\n '50': '#eef8ff',\n '100': '#d8eeff',\n '200': '#b9e0ff',\n '300': '#89cfff',\n '400': '#52b4ff',\n '500': '#2a91ff',\n '600': '#0d6efd', // default\n '700': '#0c5ae9',\n '800': '#1149bc',\n '900': '#144194',\n '950': '#11295a',\n },\n secondary: {\n '50': '#f6f6f6',\n '100': '#e7e7e7',\n '200': '#d1d1d1',\n '300': '#b0b0b0',\n '400': '#888888',\n '500': '#666666', // default\n '600': '#5d5d5d',\n '700': '#4f4f4f',\n '800': '#454545',\n '900': '#3d3d3d',\n '950': '#262626',\n },\n positive: {\n '50': '#f1fcf9',\n '100': '#cef9eb',\n '200': '#9df2d8',\n '300': '#65e3c2',\n '400': '#4fd4ad',\n '500': '#1cb090',\n '600': '#16a085', // default\n '700': '#147160',\n '800': '#155a4f',\n '900': '#164b42',\n '950': '#062d28',\n },\n negative: {\n '50': '#fff1f2',\n '100': '#ffe4e6',\n '200': '#fecdd3',\n '300': '#fda4af',\n '400': '#fb7185',\n '500': '#f43f5e', // default\n '600': '#e11d48',\n '700': '#be123c',\n '800': '#9f1239',\n '900': '#881337',\n '950': '#4c0519',\n },\n warning: {\n '50': '#fdf5ef',\n '100': '#fbe7d9',\n '200': '#f6cdb2',\n '300': '#f0ab81',\n '400': '#ea8557', // default\n '500': '#e35e2c',\n '600': '#d54621',\n '700': '#b1341d',\n '800': '#8d2b1f',\n '900': '#72261c',\n '950': '#3d100d',\n },\n },\n\n buttons: {\n style: 'bootstrap',\n\n primary: {\n backgroundColor: 'var(--idm-color-primary-600)',\n textColor: 'white',\n },\n secondary: {\n backgroundColor: 'var(--idm-color-secondary-500)',\n textColor: 'white',\n },\n positive: {\n backgroundColor: 'var(--idm-color-positive-600)',\n textColor: 'white',\n },\n negative: {\n backgroundColor: 'var(--idm-color-negative-400)',\n textColor: 'white',\n },\n warning: {\n backgroundColor: 'var(--idm-color-warning-400)',\n textColor: 'white',\n },\n loading: {\n backgroundColor: 'gray',\n textColor: 'white',\n },\n },\n\n guidanceMessages: {\n default: {\n backgroundColor: 'var(--idm-color-secondary-200)',\n textColor: 'black',\n },\n positive: {\n backgroundColor: 'var(--idm-color-positive-700)',\n textColor: 'white',\n },\n negative: {\n backgroundColor: 'var(--idm-color-negative-600)',\n textColor: 'white',\n },\n },\n\n idCapture: {\n loadingOverlay: {\n backgroundColor: '#ecedf3',\n textColor: 'black',\n loadingGraphicAccentColor: 'var(--idm-color-positive-600)',\n loadingGraphicAccentOpacity: 0.2,\n progressBarBackgroundColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundOpacity: 0.75,\n progressBarIndicatorColor: 'var(--idm-color-positive-600)',\n progressBarTextColor: 'white',\n continueBtnBorder: '2px solid white',\n },\n guideOverlay: {\n backgroundColor: '#708090',\n textColor: 'white',\n },\n guideBox: {\n unsatisfiedColor: 'white',\n satisfiedColor: 'var(--idm-color-positive-500)',\n borderWidth: 4,\n desktopPadding: 50,\n mobilePadding: 0,\n imagePadding: 25,\n },\n },\n\n selfieCapture: {\n loadingOverlay: {\n backgroundColor: '#ecedf3',\n textColor: 'black',\n loadingGraphicAccentColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundColor: 'var(--idm-color-positive-600)',\n progressBarBackgroundOpacity: 0.75,\n progressBarIndicatorColor: 'var(--idm-color-positive-600)',\n progressBarTextColor: 'white',\n continueBtnBorder: '2px solid white',\n },\n guides: {\n unsatisfiedColor: 'white',\n satisfiedColor: 'var(--idm-color-positive-500)',\n },\n },\n\n signatureCapture: {\n background:\n 'radial-gradient(#444cf7 0.5px, transparent 0.5px), radial-gradient(#444cf7 0.5px, #e5e5f7 0.5px)',\n backgroundSize: '20px 20px',\n backgroundPosition: '0 0, 10px 10px',\n },\n\n idVideoCapture: {\n readTextPrompt: {\n heading: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '8px',\n },\n prompt: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '8px',\n },\n timeRemaining: {\n backgroundColor: 'rgba(255, 255, 255, 0.5)',\n textColor: 'black',\n borderRadius: '4px',\n },\n },\n },\n} satisfies Theme\n\nexport const themes = {\n default: defaultTheme,\n none: noneTheme,\n}\n\nexport type ThemeInput = keyof typeof themes | Theme\n\nexport const resolveTheme = (input: ThemeInput): DefaultTheme => {\n if (typeof input === 'string') {\n if (input in themes) return themes[input]\n return themes.none\n }\n\n return input\n}\n\nexport const ThemeProvider = ({\n children,\n theme: themeInput,\n}: {\n children: ReactNode\n theme: ThemeInput\n}) => {\n const theme = resolveTheme(themeInput)\n const colors = theme.colors\n\n useEffect(() => {\n for (const name in colors) {\n const variants = colors[name as keyof typeof colors]\n for (const num in variants) {\n const color = variants[num as keyof typeof variants]\n document.documentElement.style.setProperty(\n `--idm-color-${name}-${num}`,\n color,\n )\n }\n }\n }, [colors])\n\n return <ScThemeProvider theme={theme}>{children}</ScThemeProvider>\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\nconst ALLOWED_RETRIES = 0\n\ntype IdentificationState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'VERIFYING'\n | 'VERIFIED'\n | 'REJECTED'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n imageUrl: string | null\n requestState: IdentificationState\n requestError: Error | null\n unverifiedTimes: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n imageUrl: null,\n requestState: 'CAPTURING',\n requestError: null,\n unverifiedTimes: 0,\n}\n\ntype Action =\n | {\n type: 'verificationReady'\n payload: { frame: ImageData; face: Face }\n }\n | { type: 'verifying'; payload: { imageUrl: string } }\n | {\n type: 'verificationCompleted'\n payload: { response: SubmissionResponse }\n }\n | { type: 'verificationFailed'; payload: { error: Error } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'verificationReady': {\n const allowedStates = ['CAPTURING', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'verifying':\n return {\n ...state,\n requestState: 'VERIFYING',\n imageUrl: action.payload.imageUrl,\n }\n\n case 'verificationCompleted': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n let { requestState, unverifiedTimes } = state\n const customerMatched = resultData.verificationResultCode === '00'\n if (customerMatched) {\n requestState = 'VERIFIED'\n } else {\n if (unverifiedTimes < ALLOWED_RETRIES) {\n requestState = 'CAPTURING'\n unverifiedTimes += 1\n } else {\n requestState = 'REJECTED'\n }\n }\n\n return { ...state, requestState, unverifiedTimes }\n }\n\n case 'verificationFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type CustomerVerificationCaptureClassNames = SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n}\n\nexport type CustomerVerificationCaptureColors = SelfieCaptureColors\n\nexport type CustomerVerificationCaptureVerbiage = SelfieCaptureVerbiage & {\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type CustomerVerificationCaptureProps = {\n onCustomerMatched?: (resp: SubmissionResponse, req: SubmissionRequest) => void\n onCustomerNotMatched?: (\n resp: SubmissionResponse,\n req: SubmissionRequest,\n ) => void\n onCaptureGuidanceTimeout?: () => void\n onExit?: () => void\n captureGuidanceTimeoutDurationMs?: number\n classNames?: CustomerVerificationCaptureClassNames\n colors?: CustomerVerificationCaptureColors\n verbiage?: CustomerVerificationCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const CustomerVerificationCapture = ({\n onCustomerMatched,\n onCustomerNotMatched,\n onCaptureGuidanceTimeout,\n onExit,\n captureGuidanceTimeoutDurationMs,\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: CustomerVerificationCaptureProps): ReactElement => {\n const [state, dispatch] = useReducer(reducer, initialState)\n const { frame, face } = state\n const {\n submit,\n submissionRequest,\n submissionResponse,\n submissionError,\n selfieImage,\n setSelfieImage,\n } = useContext(SubmissionContext)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n\n const onSelfieCaptured = useCallback((frame: ImageData, face: Face) => {\n dispatch({ type: 'verificationReady', payload: { frame, face } })\n }, [])\n\n const isReady = state.requestState === 'CAPTURED'\n useEffect(() => {\n if (!frame || !face || submissionError) return\n\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n dataUrlToBase64(imageUrl).then((img) => {\n setSelfieImage(img)\n })\n }, [face, frame, setSelfieImage, submissionError])\n\n useEffect(() => {\n if (!isReady || !selfieImage || submissionError) return\n ;(async () => {\n try {\n dispatch({ type: 'verifying', payload: { imageUrl: selfieImage } })\n const submissionResponse = await submit()\n if (!submissionResponse) throw new Error('submission failed!')\n\n dispatch({\n type: 'verificationCompleted',\n payload: { response: submissionResponse },\n })\n } catch (e) {\n dispatch({\n type: 'verificationFailed',\n payload: { error: e as Error },\n })\n }\n })()\n }, [\n isReady,\n onCustomerMatched,\n onCustomerNotMatched,\n selfieImage,\n state.requestState,\n submissionError,\n submit,\n ])\n\n useEffect(() => {\n if (!submissionRequest || !submissionResponse) return\n if (state.requestState === 'VERIFIED') {\n onCustomerMatched?.(submissionResponse, submissionRequest)\n } else if (state.requestState === 'REJECTED') {\n onCustomerNotMatched?.(submissionResponse, submissionRequest)\n }\n }, [\n onCustomerMatched,\n onCustomerNotMatched,\n state.requestState,\n submissionRequest,\n submissionResponse,\n ])\n\n useTimeout(\n captureGuidanceTimeoutDurationMs,\n onCaptureGuidanceTimeout,\n ['VERIFIED', 'REJECTED'].includes(state.requestState),\n state.requestState === 'VERIFYING',\n )\n\n const progressPreviewText = useVerbiage(\n verbiage.progressPreviewText,\n 'Processing...',\n )\n\n const theme = useTheme()\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={captureGuidanceTimeoutDurationMs}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n imageUrl={imageUrl}\n text={progressPreviewText}\n classNames={classNames.imagePreview}\n />\n )}\n </>\n )\n}\n","import React, {\n ReactElement,\n useCallback,\n useContext,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from 'react'\nimport {\n SelfieCapture,\n SelfieCaptureClassNames,\n SelfieCaptureColors,\n SelfieCaptureVerbiage,\n} from '../selfie_capture/SelfieCapture'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from '../../contexts/SubmissionContext'\nimport { dataUrlToBase64 } from '../../lib/utils/dataUrlToBase64'\nimport { cropToShoulders } from '../../lib/utils/cropping'\nimport {\n SelfieProgressPreview,\n SelfieProgressPreviewClassNames,\n} from '../common/SelfieProgressPreview'\nimport { useTimeout } from '../../lib/utils/useTimeout'\nimport { InvisibleCanvas } from '../common/InvisibleCanvas'\nimport { CustomerSuppliedVerbiage, useVerbiage } from '../../lib/locales'\nimport { SubmissionContext } from '../submission/SubmissionProvider'\nimport { useTheme } from 'styled-components'\nimport { Face } from '../../lib/models/FaceDetection'\n\nconst ALLOWED_RETRIES = 0\n\ntype IdentificationState =\n | 'CAPTURING'\n | 'CAPTURED'\n | 'IDENTIFYING'\n | 'FOUND'\n | 'NOT_FOUND'\n | 'ERROR'\n\ntype State = {\n frame: ImageData | null\n face: Face | null\n imageUrl: string | null\n requestState: IdentificationState\n requestError: Error | null\n notFoundTimes: number\n}\n\nconst initialState: State = {\n frame: null,\n face: null,\n imageUrl: null,\n requestState: 'CAPTURING',\n requestError: null,\n notFoundTimes: 0,\n}\n\ntype Action =\n | {\n type: 'identificationReady'\n payload: { frame: ImageData; face: Face }\n }\n | { type: 'identifying'; payload: { imageUrl: string } }\n | {\n type: 'identificationCompleted'\n payload: { response: SubmissionResponse }\n }\n | { type: 'identificationFailed'; payload: { error: Error } }\n\nconst reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'identificationReady': {\n const allowedStates = ['CAPTURING', 'ERROR']\n if (allowedStates.includes(state.requestState)) {\n return {\n ...state,\n requestState: 'CAPTURED',\n frame: action.payload.frame,\n face: action.payload.face,\n }\n } else {\n return state\n }\n }\n\n case 'identifying':\n return {\n ...state,\n requestState: 'IDENTIFYING',\n imageUrl: action.payload.imageUrl,\n }\n\n case 'identificationCompleted': {\n const {\n status: { statusCode, statusMessage, errorData },\n resultData,\n } = action.payload.response\n\n if (statusCode !== '000') {\n return {\n ...state,\n requestState: 'ERROR',\n requestError: new Error(`${statusMessage}: ${errorData}`),\n }\n }\n\n let { requestState, notFoundTimes } = state\n const customerMatched = resultData.verificationResultCode === '46'\n if (customerMatched) {\n requestState = 'FOUND'\n } else if (notFoundTimes < ALLOWED_RETRIES) {\n requestState = 'CAPTURING'\n notFoundTimes += 1\n } else {\n requestState = 'NOT_FOUND'\n }\n\n return { ...state, requestState, notFoundTimes }\n }\n\n case 'identificationFailed':\n return {\n ...state,\n requestState: 'ERROR',\n requestError: action.payload.error,\n }\n\n default:\n return state\n }\n}\n\nexport type CustomerIdentificationCaptureClassNames =\n SelfieCaptureClassNames & {\n imagePreview?: SelfieProgressPreviewClassNames\n }\n\nexport type CustomerIdentificationCaptureColors = SelfieCaptureColors\n\nexport type CustomerIdentificationCaptureVerbiage = SelfieCaptureVerbiage & {\n progressPreviewText?: CustomerSuppliedVerbiage\n}\n\nexport type CustomerIdentificationCaptureProps = {\n onCustomerMatched?: (resp: SubmissionResponse, req: SubmissionRequest) => void\n onCustomerNotMatched?: (\n resp: SubmissionResponse,\n req: SubmissionRequest,\n ) => void\n onCaptureGuidanceTimeout?: () => void\n onExit?: () => void\n captureGuidanceTimeoutDurationMs?: number\n classNames?: CustomerIdentificationCaptureClassNames\n colors?: CustomerIdentificationCaptureColors\n verbiage?: CustomerIdentificationCaptureVerbiage\n debugMode?: boolean\n}\n\nexport const CustomerIdentificationCapture = ({\n onCustomerMatched,\n onCustomerNotMatched,\n onCaptureGuidanceTimeout,\n onExit,\n captureGuidanceTimeoutDurationMs,\n classNames = {},\n colors = {},\n verbiage = {},\n debugMode = false,\n}: CustomerIdentificationCaptureProps): ReactElement => {\n const [state, dispatch] = useReducer(reducer, initialState)\n const {\n submit,\n submissionRequest,\n submissionResponse,\n submissionError,\n selfieImage,\n setSelfieImage,\n } = useContext(SubmissionContext)\n const [imageUrl, setImageUrl] = useState<string | null>(null)\n const rawCanvas = useRef<HTMLCanvasElement | null>(null)\n const cropCanvas = useRef<HTMLCanvasElement | null>(null)\n\n const onSelfieCaptured = useCallback((frame: ImageData, face: Face) => {\n dispatch({ type: 'identificationReady', payload: { frame, face } })\n }, [])\n\n const { frame, face } = state\n const isReady = state.requestState === 'CAPTURED'\n useEffect(() => {\n if (!frame || !face || submissionError) return\n\n const imageUrl = cropToShoulders(\n rawCanvas.current,\n cropCanvas.current,\n frame,\n face,\n )\n setImageUrl(imageUrl)\n\n dataUrlToBase64(imageUrl).then((img) => {\n setSelfieImage(img)\n })\n }, [face, frame, setSelfieImage, submissionError])\n\n useEffect(() => {\n if (!isReady || !selfieImage || submissionError) return\n ;(async () => {\n try {\n dispatch({ type: 'identifying', payload: { imageUrl: selfieImage } })\n const submissionResponse = await submit()\n if (!submissionResponse) throw new Error('submission failed!')\n\n dispatch({\n type: 'identificationCompleted',\n payload: { response: submissionResponse },\n })\n } catch (e) {\n dispatch({\n type: 'identificationFailed',\n payload: { error: e as Error },\n })\n }\n })()\n }, [\n isReady,\n onCustomerMatched,\n onCustomerNotMatched,\n selfieImage,\n state.requestState,\n submissionError,\n submit,\n ])\n\n useEffect(() => {\n if (!submissionRequest || !submissionResponse) return\n if (state.requestState === 'FOUND') {\n onCustomerMatched?.(submissionResponse, submissionRequest)\n } else if (state.requestState === 'NOT_FOUND') {\n onCustomerNotMatched?.(submissionResponse, submissionRequest)\n }\n }, [\n onCustomerMatched,\n onCustomerNotMatched,\n state.requestState,\n submissionRequest,\n submissionResponse,\n ])\n\n useTimeout(\n captureGuidanceTimeoutDurationMs,\n onCaptureGuidanceTimeout,\n ['FOUND', 'NOT_FOUND'].includes(state.requestState),\n state.requestState === 'IDENTIFYING',\n )\n\n const progressPreviewText = useVerbiage(\n verbiage.progressPreviewText,\n 'Processing...',\n )\n\n const theme = useTheme()\n\n return (\n <>\n <InvisibleCanvas ref={rawCanvas} />\n <InvisibleCanvas ref={cropCanvas} />\n\n <SelfieCapture\n onSelfieCaptured={onSelfieCaptured}\n onExit={onExit}\n timeoutDurationMs={captureGuidanceTimeoutDurationMs}\n classNames={classNames}\n colors={colors}\n verbiage={verbiage}\n debugMode={debugMode}\n />\n\n {!theme.selfieCapture?.capturePreview?.disabled && imageUrl && (\n <SelfieProgressPreview\n text={progressPreviewText}\n imageUrl={imageUrl}\n classNames={classNames.imagePreview}\n />\n )}\n </>\n )\n}\n","import React, { FC, PropsWithChildren, ReactNode } from 'react'\nimport * as ReactDOM from 'react-dom/client'\nimport {\n IdValidation,\n IdValidationProps,\n} from './components/customer_flows/IdValidation'\nimport {\n FaceValidation,\n FaceValidationProps,\n} from './components/customer_flows/FaceValidation'\nimport {\n IdAndFaceValidation,\n IdAndFaceValidationProps,\n} from './components/customer_flows/IdAndFaceValidation'\nimport {\n CustomerEnrollmentProps,\n CustomerIdAndBiometricsEnrollment,\n} from './components/customer_flows/CustomerIdAndBiometricsEnrollment'\nimport {\n CustomerVerification,\n CustomerVerificationProps,\n} from './components/customer_flows/CustomerVerification'\nimport {\n CustomerIdentification,\n CustomerIdentificationProps,\n} from './components/customer_flows/CustomerIdentification'\nimport {\n SignatureKYC,\n SignatureKYCProps,\n} from './components/customer_flows/SignatureKYC'\nimport {\n VideoIdValidation,\n VideoIdValidationProps,\n} from './components/customer_flows/VideoIdValidation'\nimport { preloadModels } from './lib/models/preloadModels'\nimport { initializeI18n } from './lib/locales'\nimport {\n CustomerBiometricsEnrollment,\n CustomerBiometricsEnrollmentProps,\n} from './components/customer_flows/CustomerBiometricsEnrollment'\nimport { OverlayContainer } from './components/common/overlay'\nimport { webSdkVersion } from './version'\nimport { Theme, themes } from './themes'\nimport {\n SubmissionRequest,\n SubmissionResponse,\n} from './contexts/SubmissionContext'\nimport {\n DocumentCapture,\n DocumentCaptureProps,\n} from './components/customer_flows/DocumentCapture'\nimport { CapturedDocumentImg } from './components/common/CapturedDocumentImg'\nimport { defaultSubmissionUrl } from './components/submission/SubmissionProvider'\nimport { defaultAuthUrl, allowedAuthUrls } from './contexts/AuthStateContext'\n\ninitializeI18n()\n\ntype TargetElement = Element | DocumentFragment | string | undefined\n\nfunction renderElement(\n component: ReactNode,\n targetElement?: TargetElement,\n): Element | DocumentFragment {\n if (typeof targetElement === 'string') {\n const result = document.querySelector(targetElement)\n if (!result) throw new Error(`targetElement ${targetElement} not found`)\n targetElement = result\n } else if (!targetElement) {\n targetElement = document.createElement('div')\n document.body.append(targetElement)\n }\n\n const root = ReactDOM.createRoot(targetElement)\n root.render(<OverlayContainer>{component}</OverlayContainer>)\n\n if ('remove' in targetElement) {\n const originalRemove = targetElement.remove\n targetElement.remove = () => {\n try {\n root.unmount()\n originalRemove()\n } catch (e) {}\n }\n }\n\n return targetElement\n}\n\nfunction renderComponent<T extends PropsWithChildren>(\n Component: FC<T>,\n targetElement: TargetElement | T,\n options?: T,\n): Element | DocumentFragment {\n if (!options) {\n options = targetElement as T\n targetElement = undefined\n }\n\n return renderElement(\n <Component {...options} />,\n targetElement as TargetElement,\n )\n}\n\nexport const renderIdValidation = (\n optionsOrTargetElement: TargetElement | IdValidationProps,\n options?: IdValidationProps,\n) => renderComponent(IdValidation, optionsOrTargetElement, options)\n\nexport const renderFaceValidation = (\n optionsOrTargetElement: TargetElement | FaceValidationProps,\n options?: FaceValidationProps,\n) => renderComponent(FaceValidation, optionsOrTargetElement, options)\n\nexport const renderIdAndFaceValidation = (\n optionsOrTargetElement: TargetElement | IdAndFaceValidationProps,\n options?: IdAndFaceValidationProps,\n) => renderComponent(IdAndFaceValidation, optionsOrTargetElement, options)\n\nexport const renderCustomerIdAndBiometricsEnrollment = (\n optionsOrTargetElement: TargetElement | CustomerEnrollmentProps,\n options?: CustomerEnrollmentProps,\n) =>\n renderComponent(\n CustomerIdAndBiometricsEnrollment,\n optionsOrTargetElement,\n options,\n )\n\nexport const renderCustomerBiometricsEnrollment = (\n optionsOrTargetElement: TargetElement | CustomerBiometricsEnrollmentProps,\n options?: CustomerBiometricsEnrollmentProps,\n) =>\n renderComponent(CustomerBiometricsEnrollment, optionsOrTargetElement, options)\n\nexport const renderCustomerVerification = (\n optionsOrTargetElement: TargetElement | CustomerVerificationProps,\n options?: CustomerVerificationProps,\n) => renderComponent(CustomerVerification, optionsOrTargetElement, options)\n\nexport const renderCustomerIdentification = (\n optionsOrTargetElement: TargetElement | CustomerIdentificationProps,\n options?: CustomerIdentificationProps,\n) => renderComponent(CustomerIdentification, optionsOrTargetElement, options)\n\nexport const renderSignatureKYC = (\n optionsOrTargetElement: TargetElement | SignatureKYCProps,\n options?: SignatureKYCProps,\n) => renderComponent(SignatureKYC, optionsOrTargetElement, options)\n\nexport const renderVideoIdValidation = (\n optionsOrTargetElement: TargetElement | VideoIdValidationProps,\n options?: VideoIdValidationProps,\n) => renderComponent(VideoIdValidation, optionsOrTargetElement, options)\n\nexport const renderDocumentCapture = (\n optionsOrTargetElement: TargetElement | DocumentCaptureProps,\n options?: DocumentCaptureProps,\n) => renderComponent(DocumentCapture, optionsOrTargetElement, options)\n\nexport type IDmissionSDK = {\n renderIdValidation: typeof renderIdValidation\n renderFaceValidation: typeof renderFaceValidation\n renderIdAndFaceValidation: typeof renderIdAndFaceValidation\n renderCustomerIdAndBiometricsEnrollment: typeof renderCustomerIdAndBiometricsEnrollment\n renderCustomerBiometricsEnrollment: typeof renderCustomerBiometricsEnrollment\n renderCustomerVerification: typeof renderCustomerVerification\n renderCustomerIdentification: typeof renderCustomerIdentification\n renderSignatureKYC: typeof renderSignatureKYC\n renderVideoIdValidation: typeof renderVideoIdValidation\n renderDocumentCapture: typeof renderDocumentCapture\n\n preloadModels: typeof preloadModels\n themes: typeof themes\n version: string\n ready: boolean\n authMode?: 'session'\n allowedAuthUrls?: string[]\n defaultAuthUrl?: string\n defaultSubmissionUrl?: string\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var IDmissionSDK: IDmissionSDK\n}\n\nglobalThis.IDmissionSDK = {\n renderIdValidation,\n renderFaceValidation,\n renderIdAndFaceValidation,\n renderCustomerIdAndBiometricsEnrollment,\n renderCustomerBiometricsEnrollment,\n renderCustomerVerification,\n renderCustomerIdentification,\n renderSignatureKYC,\n renderVideoIdValidation,\n renderDocumentCapture,\n preloadModels,\n themes,\n version: webSdkVersion,\n ready: true,\n authMode: 'session',\n allowedAuthUrls,\n defaultAuthUrl,\n defaultSubmissionUrl,\n}\n\nexport {\n preloadModels,\n themes,\n Theme,\n IdValidation,\n FaceValidation,\n IdAndFaceValidation,\n CustomerIdAndBiometricsEnrollment,\n CustomerBiometricsEnrollment,\n CustomerVerification,\n CustomerIdentification,\n SignatureKYC,\n VideoIdValidation,\n DocumentCapture,\n SubmissionRequest,\n SubmissionResponse,\n CapturedDocumentImg,\n allowedAuthUrls,\n defaultAuthUrl,\n defaultSubmissionUrl,\n}\n"],"names":["useTranslation","__awaiter","useState","ImageClassifier","global","this","FaceDetector","ObjectDetector","__assign","useCallback","useRef","React","templateObject_1","__makeTemplateObject","useTheme","styled","templateObject_2","templateObject_3","useContext","useMemo","__spreadArray"],"mappings":"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,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC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AAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,C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AC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC5f,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC;AACtc,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACza,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CA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,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC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AAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;AACnf,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,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CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACr4C,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CA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EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACrf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;AACpf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACrf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACxf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACtf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpf,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;AACpf,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACrf,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACvf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACtf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACpf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACvf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACtf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACrf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;AACpf,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;AACxf,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GA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"}
|