@myazahq/kyc-sdk-react-native 2.5.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +277 -7
- package/android/build.gradle +30 -16
- package/android/consumer-rules.pro +22 -0
- package/android/src/main/AndroidManifest.xml +17 -6
- package/android/src/main/java/com/margelo/nitro/myazakyc/HybridMyazaFaceDetector.kt +27 -70
- package/android/src/main/java/com/margelo/nitro/myazakyc/HybridMyazaTextRecognizer.kt +14 -0
- package/android/src/main/java/com/margelo/nitro/myazakyc/MlKitModelReadiness.kt +154 -0
- package/app.plugin.js +146 -10
- package/ios/HybridMyazaFaceDetector.swift +8 -3
- package/ios/HybridMyazaTextRecognizer.swift +8 -0
- package/nitrogen/generated/android/c++/JHybridMyazaTextRecognizerSpec.cpp +21 -0
- package/nitrogen/generated/android/c++/JHybridMyazaTextRecognizerSpec.hpp +2 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/myazakyc/HybridMyazaTextRecognizerSpec.kt +8 -0
- package/nitrogen/generated/ios/c++/HybridMyazaTextRecognizerSpecSwift.hpp +16 -0
- package/nitrogen/generated/ios/swift/HybridMyazaTextRecognizerSpec.swift +2 -0
- package/nitrogen/generated/ios/swift/HybridMyazaTextRecognizerSpec_cxx.swift +31 -0
- package/nitrogen/generated/shared/c++/HybridMyazaTextRecognizerSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridMyazaTextRecognizerSpec.hpp +2 -0
- package/package.json +30 -9
- package/src/MyazaKYC.tsx +4 -11
- package/src/assets/fonts/Karla_400Regular.ttf +0 -0
- package/src/assets/fonts/Karla_500Medium.ttf +0 -0
- package/src/assets/fonts/Karla_600SemiBold.ttf +0 -0
- package/src/assets/fonts/Karla_700Bold.ttf +0 -0
- package/src/assets/fonts/OFL-Karla.txt +93 -0
- package/src/assets/fonts/OFL-SpaceGrotesk.txt +93 -0
- package/src/assets/fonts/README.md +12 -0
- package/src/assets/fonts/SpaceGrotesk_500Medium.ttf +0 -0
- package/src/assets/fonts/SpaceGrotesk_600SemiBold.ttf +0 -0
- package/src/assets/fonts/SpaceGrotesk_700Bold.ttf +0 -0
- package/src/capture/useAutoCapture.ts +8 -1
- package/src/components/CountryField.tsx +8 -0
- package/src/components/CountryRegionPicker.tsx +184 -0
- package/src/components/DialCodePicker.tsx +47 -68
- package/src/components/DialCodeRow.tsx +102 -0
- package/src/components/DocumentCropper.tsx +30 -24
- package/src/components/DocumentReview.tsx +11 -1
- package/src/components/DocumentReviewSide.tsx +6 -2
- package/src/components/DocumentReviewZoom.tsx +5 -1
- package/src/components/FramedMapPicker.tsx +122 -0
- package/src/components/GeoBadge.tsx +34 -0
- package/src/components/Icon.tsx +10 -192
- package/src/components/KycFlow.tsx +69 -34
- package/src/components/LineSkeleton.tsx +100 -0
- package/src/components/MapChrome.tsx +67 -0
- package/src/components/MapPinMarker.tsx +54 -0
- package/src/components/MapPinPicker.tsx +179 -0
- package/src/components/MilestoneTrack.tsx +155 -0
- package/src/components/MyazaButton.tsx +9 -0
- package/src/components/MyazaInput.tsx +17 -1
- package/src/components/OptionRow.tsx +22 -3
- package/src/components/PhoneNumberInput.tsx +8 -0
- package/src/components/PoweredBy.tsx +5 -5
- package/src/components/PresenceBlocks.tsx +153 -0
- package/src/components/RequiredDocumentPill.tsx +114 -0
- package/src/components/StepHeader.tsx +23 -3
- package/src/components/StepView.tsx +17 -0
- package/src/components/StickyActions.tsx +56 -0
- package/src/components/dialCodeRows.ts +64 -0
- package/src/components/documentReviewCopy.ts +39 -0
- package/src/components/fonts.ts +14 -17
- package/src/components/icon-map.ts +176 -0
- package/src/components/stepHeaderMeta.tsx +48 -5
- package/src/config/addressCollection.ts +125 -0
- package/src/config/biometricOptions.ts +100 -0
- package/src/config/business.ts +20 -1
- package/src/config/businessSteps.ts +8 -2
- package/src/config/consentStep.ts +19 -0
- package/src/config/documentCaptureMethods.ts +31 -0
- package/src/config/proofOfAddress.ts +54 -11
- package/src/config/regions.ts +24 -0
- package/src/config/stepOrder.ts +79 -5
- package/src/config/uploadLimits.ts +35 -0
- package/src/config/workflowMerge.ts +13 -5
- package/src/index.ts +49 -1
- package/src/lib/address-current-location.ts +171 -0
- package/src/lib/address-field-modes.ts +119 -0
- package/src/lib/address-flow.ts +172 -0
- package/src/lib/address-helpers.ts +48 -0
- package/src/lib/address-line.ts +76 -0
- package/src/lib/address-pin-move.ts +97 -0
- package/src/lib/address-step-recovery.ts +63 -0
- package/src/lib/authed-image.ts +78 -0
- package/src/lib/biometric-copy.ts +51 -0
- package/src/lib/captureRing.ts +83 -0
- package/src/lib/country-adoption.ts +89 -0
- package/src/lib/documentCaptureCheck.ts +136 -0
- package/src/lib/inferred-country.ts +65 -0
- package/src/lib/livenessLayout.ts +49 -0
- package/src/lib/map-frame.ts +159 -0
- package/src/lib/map-tiles.ts +143 -0
- package/src/lib/model-ready.ts +82 -0
- package/src/lib/poa-country-gate.ts +27 -0
- package/src/lib/prime-models.ts +50 -0
- package/src/lib/resubmit.ts +36 -7
- package/src/lib/result-copy.ts +116 -0
- package/src/lib/result-wait.ts +53 -0
- package/src/lib/review-map-surface.ts +26 -0
- package/src/lib/scope.ts +31 -0
- package/src/lib/selfie-sharpness.ts +211 -0
- package/src/lib/selfie-upload-wait.ts +79 -0
- package/src/lib/street-view-fov.ts +42 -0
- package/src/lib/webview-available.ts +47 -0
- package/src/liveness/avatarSource.ts +59 -0
- package/src/liveness/useLiveness.ts +6 -1
- package/src/liveness/useModelReady.ts +9 -55
- package/src/mrz/extract.ts +71 -4
- package/src/mrz/textRecognizer.ts +36 -0
- package/src/mrz/useTextModelReady.ts +21 -0
- package/src/presence/background-math.ts +100 -0
- package/src/presence/background-store.ts +82 -0
- package/src/presence/background.ts +165 -0
- package/src/presence/foreground-service.ts +193 -0
- package/src/presence/fs.ts +51 -0
- package/src/presence/geofence.ts +41 -0
- package/src/presence/math.ts +44 -0
- package/src/presence/post.ts +40 -0
- package/src/presence/report.ts +87 -0
- package/src/presence/sampler.ts +110 -0
- package/src/presence/status.ts +92 -0
- package/src/presence/store.ts +94 -0
- package/src/presence/tier.ts +36 -0
- package/src/presence/watch-wait.ts +81 -0
- package/src/screens/AddressCountryControl.tsx +115 -0
- package/src/screens/BusinessDetailsFields.tsx +3 -0
- package/src/screens/BusinessDetailsStep.tsx +2 -0
- package/src/screens/BusinessDocumentSlot.tsx +3 -2
- package/src/screens/BusinessDocumentsStep.tsx +4 -55
- package/src/screens/CompanyInfoFields.tsx +6 -1
- package/src/screens/ConsentStep.tsx +6 -17
- package/src/screens/ContactActions.tsx +54 -0
- package/src/screens/ContactDestinationField.tsx +4 -0
- package/src/screens/ContactEntryPanel.tsx +75 -0
- package/src/screens/ContactVerificationStep.tsx +26 -56
- package/src/screens/CountrySelectStep.tsx +13 -147
- package/src/screens/DocumentCaptureStep.tsx +177 -93
- package/src/screens/LivenessAvatar.tsx +33 -16
- package/src/screens/LivenessStep.tsx +188 -49
- package/src/screens/MrzScanView.tsx +33 -0
- package/src/screens/PoaDocumentTypeList.tsx +66 -0
- package/src/screens/ProofOfAddressParts.tsx +151 -0
- package/src/screens/ProofOfAddressStep.tsx +58 -99
- package/src/screens/SubmittedBadge.tsx +25 -0
- package/src/screens/SubmittedError.tsx +64 -0
- package/src/screens/SubmittedResult.tsx +117 -0
- package/src/screens/SubmittedStep.tsx +71 -164
- package/src/screens/SubmittedSuccess.tsx +127 -0
- package/src/screens/SubmittedWaiting.tsx +45 -0
- package/src/screens/address/AddressEntranceStep.tsx +161 -0
- package/src/screens/address/AddressIntroGate.tsx +148 -0
- package/src/screens/address/AddressMapStub.tsx +50 -0
- package/src/screens/address/AddressPinStep.tsx +178 -0
- package/src/screens/address/AddressReviewStep.tsx +162 -0
- package/src/screens/address/AddressSandboxTabs.tsx +158 -0
- package/src/screens/address/AddressSearchField.tsx +115 -0
- package/src/screens/address/AddressSearchStep.tsx +94 -0
- package/src/screens/address/CurrentLocationRow.tsx +135 -0
- package/src/screens/address/DetailsSheet.tsx +175 -0
- package/src/screens/address/DetailsSheetFields.tsx +184 -0
- package/src/screens/address/EntranceDropzone.tsx +178 -0
- package/src/screens/address/EntranceFraming.tsx +66 -0
- package/src/screens/address/EntrancePills.tsx +60 -0
- package/src/screens/address/FramedStreetView.tsx +155 -0
- package/src/screens/address/IntroDisclosures.tsx +210 -0
- package/src/screens/address/LabelDecisionRow.tsx +113 -0
- package/src/screens/address/PinSummaryRow.tsx +105 -0
- package/src/screens/address/ReviewAddressBand.tsx +111 -0
- package/src/screens/address/ReviewEntranceThumbs.tsx +64 -0
- package/src/screens/address/ReviewMapPicture.tsx +106 -0
- package/src/screens/address/SearchResults.tsx +105 -0
- package/src/screens/address/SearchScreen.tsx +176 -0
- package/src/screens/address/SkipForNow.tsx +43 -0
- package/src/screens/address/StreetViewChrome.tsx +81 -0
- package/src/screens/address/detail-values.ts +22 -0
- package/src/screens/address/fix-source.ts +27 -0
- package/src/screens/address/index.ts +8 -0
- package/src/screens/address/meta.ts +44 -0
- package/src/screens/address/use-address-flow.ts +200 -0
- package/src/screens/address/use-label-pin.ts +80 -0
- package/src/screens/address/use-pin-actions.ts +192 -0
- package/src/screens/consent/model.ts +79 -10
- package/src/screens/document/CaptureCheckNotice.tsx +77 -0
- package/src/screens/document/UploadPhase.tsx +177 -0
- package/src/screens/document/useDocumentCamera.ts +109 -0
- package/src/screens/liveness/CaptureRing.tsx +91 -0
- package/src/screens/liveness/LivenessCamera.tsx +63 -0
- package/src/screens/liveness/LivenessHandover.tsx +43 -0
- package/src/screens/liveness/LivenessOutcome.tsx +8 -4
- package/src/screens/liveness/SelfiePreview.tsx +31 -7
- package/src/screens/liveness/ShutterFlash.tsx +25 -0
- package/src/screens/liveness/index.ts +4 -0
- package/src/screens/liveness/useSelfieUpload.ts +23 -3
- package/src/screens/nfc/NfcScanIllustration.tsx +7 -18
- package/src/screens/useAddressPhotoAttach.ts +77 -0
- package/src/screens/useBusinessDocumentAttach.ts +93 -0
- package/src/screens/usePoaAttach.ts +12 -15
- package/src/services/api-types.ts +119 -1
- package/src/services/api-verify-types.ts +37 -0
- package/src/services/api.ts +149 -3
- package/src/services/deviceMetadata.ts +1 -1
- package/src/services/location.ts +234 -0
- package/src/services/mediaCompress.ts +23 -5
- package/src/services/uploadErrors.ts +30 -0
- package/src/services/workflowGate.ts +7 -0
- package/src/specs/MyazaTextRecognizer.nitro.ts +29 -0
- package/src/store/address.ts +97 -0
- package/src/store/derive.ts +29 -4
- package/src/store/kycStore.ts +120 -5
- package/src/store/serverConfig.ts +18 -0
- package/src/store/session.ts +23 -4
- package/src/store/state.ts +134 -0
- package/src/store/submit.ts +18 -1
- package/src/types/config.ts +63 -1
- package/src/types/verification.ts +12 -0
- package/src/types/workflow.ts +97 -1
- package/src/assets/liveness/Blink.gif +0 -0
- package/src/assets/liveness/Nod.gif +0 -0
- package/src/assets/liveness/Smile.gif +0 -0
- package/src/assets/liveness/Turn.gif +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2019 The Karla Project Authors (https://github.com/googlefonts/karla)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
https://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Bundled typefaces
|
|
2
|
+
|
|
3
|
+
The seven faces the SDK draws with, and nothing else: Karla 400/500/600/700
|
|
4
|
+
(body) and Space Grotesk 500/600/700 (headings). Both families are Google
|
|
5
|
+
Fonts under the SIL Open Font License 1.1; the licence for each sits beside
|
|
6
|
+
the files (`OFL-Karla.txt`, `OFL-SpaceGrotesk.txt`).
|
|
7
|
+
|
|
8
|
+
They are vendored rather than imported from the `@expo-google-fonts` packages
|
|
9
|
+
because Metro bundles every `require` in a package index whether or not the
|
|
10
|
+
export is used, so those two packages put all 19 of their font files (1.85 MB)
|
|
11
|
+
into every integrator's app for the seven faces the SDK uses. Add a weight here
|
|
12
|
+
only when `config/font-resolve.ts` resolves to it.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
|
2
2
|
import { useFrameOutput } from 'react-native-vision-camera';
|
|
3
3
|
import { runOnJS } from 'react-native-worklets';
|
|
4
4
|
|
|
5
|
-
import { hasTextRecognizer, recognizeAllLines } from '../mrz/textRecognizer';
|
|
5
|
+
import { hasTextRecognizer, primeTextModel, recognizeAllLines } from '../mrz/textRecognizer';
|
|
6
6
|
import { extractMrz } from '../mrz/extract';
|
|
7
7
|
import type { MrzScan } from '../mrz/parse';
|
|
8
8
|
import { DocumentTextGate } from './documentTextGate';
|
|
@@ -97,6 +97,13 @@ export function useAutoCapture({
|
|
|
97
97
|
// body is the one place that is both.
|
|
98
98
|
hasTextRecognizer();
|
|
99
99
|
hasRectDetector();
|
|
100
|
+
// Android fetches the text model through Play Services, so start it here too.
|
|
101
|
+
// The flow primes at open and this is normally a no-op, but the document step
|
|
102
|
+
// can be reached directly in a resumed session. Auto-capture deliberately does
|
|
103
|
+
// NOT gate on readiness: it is an accelerator, the manual shutter is live
|
|
104
|
+
// throughout, so a model that never arrives costs convenience rather than
|
|
105
|
+
// leaving the user stuck.
|
|
106
|
+
primeTextModel();
|
|
100
107
|
|
|
101
108
|
const gate = useMemo(() => new DocumentTextGate(), []);
|
|
102
109
|
const [guidance, setGuidance] = useState<DocumentGuidance>(INITIAL);
|
|
@@ -21,6 +21,8 @@ export function CountryField({
|
|
|
21
21
|
value,
|
|
22
22
|
options,
|
|
23
23
|
onChange,
|
|
24
|
+
geoCountry,
|
|
25
|
+
grouped,
|
|
24
26
|
placeholder = 'Select a country',
|
|
25
27
|
searchPlaceholder = 'Search country',
|
|
26
28
|
}: {
|
|
@@ -29,6 +31,10 @@ export function CountryField({
|
|
|
29
31
|
/** The pickable countries — all ISO, or a workflow's registry subset. */
|
|
30
32
|
options: DialCodeOption[];
|
|
31
33
|
onChange: (code: string) => void;
|
|
34
|
+
/** The visitor's inferred country, pinned on top of the sheet as "Your location". */
|
|
35
|
+
geoCountry?: string | null;
|
|
36
|
+
/** Region headers between the rows, the country-select step's way. */
|
|
37
|
+
grouped?: boolean;
|
|
32
38
|
placeholder?: string;
|
|
33
39
|
searchPlaceholder?: string;
|
|
34
40
|
}): React.ReactElement {
|
|
@@ -75,6 +81,8 @@ export function CountryField({
|
|
|
75
81
|
visible={open}
|
|
76
82
|
options={options}
|
|
77
83
|
selected={value ?? ''}
|
|
84
|
+
pinned={geoCountry}
|
|
85
|
+
grouped={grouped}
|
|
78
86
|
searchPlaceholder={searchPlaceholder}
|
|
79
87
|
onPick={(code) => {
|
|
80
88
|
setOpen(false);
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { Pressable, ScrollView, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { radius, spacing } from '../config/theme';
|
|
5
|
+
import { groupCountriesByRegion, pinGeoRow, regionCountryName } from '../config/regions';
|
|
6
|
+
import { useTheme } from './runtime';
|
|
7
|
+
import { MyazaText } from './Typography';
|
|
8
|
+
import { MyazaInput } from './MyazaInput';
|
|
9
|
+
import { CountryFlag } from './CountryFlag';
|
|
10
|
+
import { Icon } from './Icon';
|
|
11
|
+
import { GeoBadge } from './GeoBadge';
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Searchable, region-grouped country picker for the country-select step. Used
|
|
15
|
+
// when a workflow offers many countries (Global Documents): a flat 200-country
|
|
16
|
+
// list is a scroll, not a chooser, so this adds a pinned search box and
|
|
17
|
+
// continent headers over a bounded scroll area. Mirrors the web SDK's
|
|
18
|
+
// CountryRegionPicker and Flutter's country_region_picker.dart.
|
|
19
|
+
//
|
|
20
|
+
// Split from CountrySelectStep (200-line rule); the step keeps the flat list
|
|
21
|
+
// and the threshold that decides between the two.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
export function CountryRegionPicker({
|
|
25
|
+
countries,
|
|
26
|
+
selected,
|
|
27
|
+
geoCountry,
|
|
28
|
+
onPick,
|
|
29
|
+
}: {
|
|
30
|
+
countries: string[];
|
|
31
|
+
selected: string | null;
|
|
32
|
+
/**
|
|
33
|
+
* The visitor's IP country. Lifted out of its continent to the very top and
|
|
34
|
+
* tagged, so the one country most likely to be theirs is the first thing
|
|
35
|
+
* they see rather than something to scroll for.
|
|
36
|
+
*/
|
|
37
|
+
geoCountry?: string | null;
|
|
38
|
+
onPick: (country: string) => void;
|
|
39
|
+
}): React.ReactElement {
|
|
40
|
+
const { colors } = useTheme();
|
|
41
|
+
const [query, setQuery] = useState('');
|
|
42
|
+
|
|
43
|
+
const { pinned, groups } = useMemo(() => {
|
|
44
|
+
const needle = query.trim().toLowerCase();
|
|
45
|
+
const visible = needle
|
|
46
|
+
? countries.filter(
|
|
47
|
+
(code) =>
|
|
48
|
+
code.toLowerCase().includes(needle) ||
|
|
49
|
+
regionCountryName(code).toLowerCase().includes(needle),
|
|
50
|
+
)
|
|
51
|
+
: countries;
|
|
52
|
+
const split = pinGeoRow(visible, geoCountry, (code) => code);
|
|
53
|
+
return { pinned: split.pinned, groups: groupCountriesByRegion(split.rest) };
|
|
54
|
+
}, [countries, query, geoCountry]);
|
|
55
|
+
|
|
56
|
+
const empty = groups.length === 0 && pinned === null;
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
// The search box stays put and the list owns its own scroll, so a
|
|
60
|
+
// ~240-country flow does not scroll the search field off the top. That
|
|
61
|
+
// relies on the SHEET rendering this step with `fillsViewport` — inside a
|
|
62
|
+
// scroll view the nested list below would take an unbounded height, outgrow
|
|
63
|
+
// the viewport, and drag the search box off the top with it.
|
|
64
|
+
<View style={{ flex: 1 }}>
|
|
65
|
+
<MyazaInput
|
|
66
|
+
value={query}
|
|
67
|
+
onChangeText={setQuery}
|
|
68
|
+
placeholder="Search countries…"
|
|
69
|
+
autoCapitalize="none"
|
|
70
|
+
prefix={<Icon name="search" size={18} color={colors.textSecondary} />}
|
|
71
|
+
/>
|
|
72
|
+
<View style={{ height: spacing.md }} />
|
|
73
|
+
|
|
74
|
+
{empty ? (
|
|
75
|
+
<MyazaText variant="bodyMedium" style={{ textAlign: 'center', marginTop: spacing.lg }}>
|
|
76
|
+
No countries match your search.
|
|
77
|
+
</MyazaText>
|
|
78
|
+
) : (
|
|
79
|
+
// `nestedScrollEnabled` stays: Android refuses to scroll a nested
|
|
80
|
+
// same-direction list without it, and this is still nested on the
|
|
81
|
+
// flat-list path and inside any future scrolling parent.
|
|
82
|
+
<ScrollView
|
|
83
|
+
nestedScrollEnabled
|
|
84
|
+
keyboardShouldPersistTaps="handled"
|
|
85
|
+
showsVerticalScrollIndicator={false}
|
|
86
|
+
>
|
|
87
|
+
{pinned ? (
|
|
88
|
+
<CountryRow
|
|
89
|
+
code={pinned}
|
|
90
|
+
name={regionCountryName(pinned)}
|
|
91
|
+
selected={pinned === selected}
|
|
92
|
+
badge="Your location"
|
|
93
|
+
onPress={() => onPick(pinned)}
|
|
94
|
+
/>
|
|
95
|
+
) : null}
|
|
96
|
+
{groups.map((group) => (
|
|
97
|
+
<View key={group.region}>
|
|
98
|
+
{/* Uppercase, tracked-out section label — Flutter's region
|
|
99
|
+
header. Lowercase text at the default weight read as another
|
|
100
|
+
list row rather than a divider. */}
|
|
101
|
+
<MyazaText
|
|
102
|
+
variant="bodySmall"
|
|
103
|
+
color={colors.textSecondary}
|
|
104
|
+
style={{
|
|
105
|
+
fontWeight: '700',
|
|
106
|
+
letterSpacing: 0.6,
|
|
107
|
+
paddingHorizontal: spacing.xs,
|
|
108
|
+
paddingVertical: spacing.sm,
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{group.region.toUpperCase()}
|
|
112
|
+
</MyazaText>
|
|
113
|
+
{group.countries.map((entry) => (
|
|
114
|
+
<CountryRow
|
|
115
|
+
key={entry.code}
|
|
116
|
+
code={entry.code}
|
|
117
|
+
name={entry.name}
|
|
118
|
+
selected={entry.code === selected}
|
|
119
|
+
onPress={() => onPick(entry.code)}
|
|
120
|
+
/>
|
|
121
|
+
))}
|
|
122
|
+
</View>
|
|
123
|
+
))}
|
|
124
|
+
</ScrollView>
|
|
125
|
+
)}
|
|
126
|
+
</View>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* One selectable country row, shared by the flat list and the region picker
|
|
132
|
+
* so the two cannot drift apart. `badge` tags the pinned geo row; it is the
|
|
133
|
+
* same control in a second position, differing only by the tag.
|
|
134
|
+
*/
|
|
135
|
+
export function CountryRow({
|
|
136
|
+
code,
|
|
137
|
+
name,
|
|
138
|
+
selected,
|
|
139
|
+
badge,
|
|
140
|
+
onPress,
|
|
141
|
+
}: {
|
|
142
|
+
code: string;
|
|
143
|
+
name: string;
|
|
144
|
+
selected: boolean;
|
|
145
|
+
badge?: string;
|
|
146
|
+
onPress: () => void;
|
|
147
|
+
}): React.ReactElement {
|
|
148
|
+
const { colors } = useTheme();
|
|
149
|
+
return (
|
|
150
|
+
<Pressable
|
|
151
|
+
onPress={onPress}
|
|
152
|
+
accessibilityRole="radio"
|
|
153
|
+
accessibilityState={{ checked: selected }}
|
|
154
|
+
accessibilityLabel={badge ? `${name}, ${badge.toLowerCase()}` : name}
|
|
155
|
+
// Matches the Flutter SDK's CountryOptionTile exactly — the two had
|
|
156
|
+
// drifted (24px flag / 12px padding here vs 32 / 16 there), which is why
|
|
157
|
+
// the same screen looked like a different component on each platform. The
|
|
158
|
+
// spacing and radius scales are identical across the SDKs, so there is
|
|
159
|
+
// nothing platform-specific to reconcile: `md` means 16 on both.
|
|
160
|
+
style={{
|
|
161
|
+
flexDirection: 'row',
|
|
162
|
+
alignItems: 'center',
|
|
163
|
+
padding: spacing.md,
|
|
164
|
+
borderRadius: radius.md,
|
|
165
|
+
borderWidth: selected ? 1.5 : 1,
|
|
166
|
+
borderColor: selected ? colors.primary : colors.border,
|
|
167
|
+
backgroundColor: selected ? colors.primary50 : colors.background,
|
|
168
|
+
marginBottom: spacing.sm,
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
<CountryFlag country={code} size={32} />
|
|
172
|
+
<View style={{ width: 12 }} />
|
|
173
|
+
<MyazaText variant="label" style={{ flex: 1, fontWeight: '500' }}>
|
|
174
|
+
{name}
|
|
175
|
+
</MyazaText>
|
|
176
|
+
{badge ? <GeoBadge label={badge} /> : null}
|
|
177
|
+
<Icon
|
|
178
|
+
name="chevron-right"
|
|
179
|
+
size={18}
|
|
180
|
+
color={selected ? colors.primary : colors.textSecondary}
|
|
181
|
+
/>
|
|
182
|
+
</Pressable>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
@@ -13,8 +13,9 @@ import { useTheme } from './runtime';
|
|
|
13
13
|
import { MyazaText } from './Typography';
|
|
14
14
|
import { MyazaInput } from './MyazaInput';
|
|
15
15
|
import { Icon } from './Icon';
|
|
16
|
-
import { CountryFlag } from './CountryFlag';
|
|
17
16
|
import { FloatingSheet } from './glass/FloatingSheet';
|
|
17
|
+
import { DialCodeDivider, DialCodeRegionHeader, DialCodeRow } from './DialCodeRow';
|
|
18
|
+
import { buildDialCodeItems, dialCodeItemKey, filterDialCodeOptions, type DialCodeItem } from './dialCodeRows';
|
|
18
19
|
|
|
19
20
|
// ---------------------------------------------------------------------------
|
|
20
21
|
// THE country sheet — the phone field's dial-code picker, generalised.
|
|
@@ -33,6 +34,10 @@ import { FloatingSheet } from './glass/FloatingSheet';
|
|
|
33
34
|
// The sheet is sized against the space left ABOVE the keyboard, like Flutter's.
|
|
34
35
|
// The search field autofocuses, so measuring against the full screen would put
|
|
35
36
|
// every result underneath the keys the moment the user started typing.
|
|
37
|
+
//
|
|
38
|
+
// `grouped` lists the countries under region headers (Africa first), the way
|
|
39
|
+
// the country-select step does — what the address-scope country control asks
|
|
40
|
+
// for. The list itself is built by dialCodeRows.ts.
|
|
36
41
|
// ---------------------------------------------------------------------------
|
|
37
42
|
|
|
38
43
|
export interface DialCodeOption {
|
|
@@ -46,6 +51,8 @@ export function DialCodePicker({
|
|
|
46
51
|
visible,
|
|
47
52
|
options,
|
|
48
53
|
selected,
|
|
54
|
+
pinned,
|
|
55
|
+
grouped = false,
|
|
49
56
|
onPick,
|
|
50
57
|
onClose,
|
|
51
58
|
searchPlaceholder = 'Search country or code',
|
|
@@ -53,6 +60,14 @@ export function DialCodePicker({
|
|
|
53
60
|
visible: boolean;
|
|
54
61
|
options: DialCodeOption[];
|
|
55
62
|
selected: string;
|
|
63
|
+
/**
|
|
64
|
+
* The visitor's IP country. Lifted out of the alphabet to the top and
|
|
65
|
+
* tagged, so a guess we made on their behalf is visible AS a guess and one
|
|
66
|
+
* tap away rather than buried among two hundred others.
|
|
67
|
+
*/
|
|
68
|
+
pinned?: string | null;
|
|
69
|
+
/** Region headers between the rows (the pinned row stays on top). */
|
|
70
|
+
grouped?: boolean;
|
|
56
71
|
onPick: (code: string) => void;
|
|
57
72
|
onClose: () => void;
|
|
58
73
|
searchPlaceholder?: string;
|
|
@@ -78,19 +93,13 @@ export function DialCodePicker({
|
|
|
78
93
|
const available = screenHeight - keyboard;
|
|
79
94
|
const maxHeight = Math.min(Math.max(available * 0.85, 240), screenHeight * 0.6);
|
|
80
95
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
(o) =>
|
|
89
|
-
o.name.toLowerCase().includes(q) ||
|
|
90
|
-
o.code.toLowerCase() === q ||
|
|
91
|
-
(o.dialCode != null && o.dialCode.replace(/^\+/, '').startsWith(bare)),
|
|
92
|
-
);
|
|
93
|
-
}, [options, query]);
|
|
96
|
+
// Where they appear to be, lifted out of the alphabet. It stays subject to
|
|
97
|
+
// the search, so typing still narrows to what was asked for rather than
|
|
98
|
+
// keeping a row that does not match.
|
|
99
|
+
const rows = useMemo(
|
|
100
|
+
() => buildDialCodeItems(filterDialCodeOptions(options, query), pinned, grouped),
|
|
101
|
+
[options, query, pinned, grouped],
|
|
102
|
+
);
|
|
94
103
|
|
|
95
104
|
const close = (): void => {
|
|
96
105
|
setQuery('');
|
|
@@ -121,67 +130,37 @@ export function DialCodePicker({
|
|
|
121
130
|
</View>
|
|
122
131
|
|
|
123
132
|
<FlatList
|
|
124
|
-
data={
|
|
125
|
-
keyExtractor={
|
|
133
|
+
data={rows.items}
|
|
134
|
+
keyExtractor={dialCodeItemKey}
|
|
126
135
|
keyboardShouldPersistTaps="handled"
|
|
136
|
+
// A hairline under the pinned row only: the alphabet below it is one
|
|
137
|
+
// list, and a rule between every row is noise.
|
|
138
|
+
ItemSeparatorComponent={({ leadingItem }: { leadingItem: DialCodeItem }) =>
|
|
139
|
+
rows.geo != null && leadingItem.kind === 'row' && leadingItem.option.code === rows.geo.code ? (
|
|
140
|
+
<DialCodeDivider />
|
|
141
|
+
) : null
|
|
142
|
+
}
|
|
127
143
|
ListEmptyComponent={
|
|
128
144
|
<MyazaText variant="bodyMedium" style={{ padding: spacing.lg, textAlign: 'center' }}>
|
|
129
145
|
No countries match your search.
|
|
130
146
|
</MyazaText>
|
|
131
147
|
}
|
|
132
|
-
renderItem={({ item }) =>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
renderItem={({ item }) =>
|
|
149
|
+
item.kind === 'header' ? (
|
|
150
|
+
<DialCodeRegionHeader region={item.region} />
|
|
151
|
+
) : (
|
|
152
|
+
<DialCodeRow
|
|
153
|
+
option={item.option}
|
|
154
|
+
isSelected={item.option.code === selected}
|
|
155
|
+
badge={rows.geo != null && item.option.code === rows.geo.code ? 'Your location' : undefined}
|
|
156
|
+
onPress={() => {
|
|
157
|
+
setQuery('');
|
|
158
|
+
onPick(item.option.code);
|
|
159
|
+
}}
|
|
160
|
+
/>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
142
163
|
/>
|
|
143
164
|
</FloatingSheet>
|
|
144
165
|
);
|
|
145
166
|
}
|
|
146
|
-
|
|
147
|
-
function CountryRow({
|
|
148
|
-
option,
|
|
149
|
-
isSelected,
|
|
150
|
-
onPress,
|
|
151
|
-
}: {
|
|
152
|
-
option: DialCodeOption;
|
|
153
|
-
isSelected: boolean;
|
|
154
|
-
onPress: () => void;
|
|
155
|
-
}): React.ReactElement {
|
|
156
|
-
const { colors } = useTheme();
|
|
157
|
-
return (
|
|
158
|
-
<Pressable
|
|
159
|
-
onPress={onPress}
|
|
160
|
-
accessibilityRole="radio"
|
|
161
|
-
accessibilityState={{ checked: isSelected }}
|
|
162
|
-
style={{
|
|
163
|
-
flexDirection: 'row',
|
|
164
|
-
alignItems: 'center',
|
|
165
|
-
paddingHorizontal: spacing.md,
|
|
166
|
-
// Roomier rows: a country list is a long scan, and cramped rows make
|
|
167
|
-
// every tap a precision job. Matches the web dropdown's row height.
|
|
168
|
-
paddingVertical: 12,
|
|
169
|
-
backgroundColor: isSelected ? colors.primary50 : 'transparent',
|
|
170
|
-
}}
|
|
171
|
-
>
|
|
172
|
-
<CountryFlag country={option.code} size={28} />
|
|
173
|
-
<View style={{ width: spacing.md }} />
|
|
174
|
-
{/* No line clamp: "Bosnia & Herzegovina" and the like must read in full,
|
|
175
|
-
which is what Flutter's Expanded(Text) gives. Full body size (16),
|
|
176
|
-
the web dropdown's reading size — 14 read small against the flags. */}
|
|
177
|
-
<MyazaText variant="body" style={{ flex: 1 }}>
|
|
178
|
-
{option.name}
|
|
179
|
-
</MyazaText>
|
|
180
|
-
{option.dialCode != null ? (
|
|
181
|
-
<MyazaText variant="bodyMedium" color={colors.textSecondary}>
|
|
182
|
-
{option.dialCode}
|
|
183
|
-
</MyazaText>
|
|
184
|
-
) : null}
|
|
185
|
-
</Pressable>
|
|
186
|
-
);
|
|
187
|
-
}
|