@sanctum-key/react-native-sdk 1.0.57 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/build/package.json +12 -2
  2. package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
  3. package/build/src/components/EnhancedCameraView.js +5 -1
  4. package/build/src/components/EnhancedCameraView.js.map +1 -1
  5. package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  6. package/build/src/components/KYCElements/IDCardCapture.js +34 -13
  7. package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
  8. package/build/src/components/TemplateKYCExample.d.ts +2 -1
  9. package/build/src/components/TemplateKYCExample.d.ts.map +1 -1
  10. package/build/src/components/TemplateKYCExample.js +2 -2
  11. package/build/src/components/TemplateKYCExample.js.map +1 -1
  12. package/build/src/components/TemplateKYCFlowRefactored.d.ts +1 -0
  13. package/build/src/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  14. package/build/src/components/TemplateKYCFlowRefactored.js +56 -12
  15. package/build/src/components/TemplateKYCFlowRefactored.js.map +1 -1
  16. package/build/src/config/countriesData.d.ts.map +1 -1
  17. package/build/src/config/countriesData.js +249 -77
  18. package/build/src/config/countriesData.js.map +1 -1
  19. package/build/src/config/region_mapping.d.ts.map +1 -1
  20. package/build/src/config/region_mapping.js +45 -15
  21. package/build/src/config/region_mapping.js.map +1 -1
  22. package/build/src/modules/api/CardAuthentification.d.ts.map +1 -1
  23. package/build/src/modules/api/CardAuthentification.js +10 -2
  24. package/build/src/modules/api/CardAuthentification.js.map +1 -1
  25. package/build/src/utils/cropByObb.d.ts +1 -1
  26. package/build/src/utils/cropByObb.d.ts.map +1 -1
  27. package/build/src/utils/cropByObb.js +112 -5
  28. package/build/src/utils/cropByObb.js.map +1 -1
  29. package/build/src/utils/logger.d.ts +1 -0
  30. package/build/src/utils/logger.d.ts.map +1 -1
  31. package/build/src/utils/logger.js +37 -73
  32. package/build/src/utils/logger.js.map +1 -1
  33. package/build/src/web/WebKYCEntry.d.ts.map +1 -1
  34. package/build/src/web/WebKYCEntry.js +0 -2
  35. package/build/src/web/WebKYCEntry.js.map +1 -1
  36. package/package.json +12 -2
  37. package/src/components/EnhancedCameraView.tsx +4 -0
  38. package/src/components/KYCElements/IDCardCapture.tsx +49 -21
  39. package/src/components/TemplateKYCExample.tsx +4 -1
  40. package/src/components/TemplateKYCFlowRefactored.tsx +66 -11
  41. package/src/config/countriesData.ts +250 -78
  42. package/src/config/region_mapping.ts +700 -670
  43. package/src/modules/api/CardAuthentification.ts +11 -3
  44. package/src/utils/cropByObb.ts +160 -6
  45. package/src/utils/logger.ts +42 -93
  46. package/src/web/WebKYCEntry.tsx +0 -2
@@ -624,31 +624,59 @@ export const IDCardCapture: React.FC<IDCardCaptureProps> = ({ component, value =
624
624
 
625
625
  try {
626
626
  let imagePathForUpload = capturePath;
627
- const overlayBbox = cameraConfig.overlay.bbox;
627
+ const overlayBbox = cameraConfig.overlay.bbox;
628
628
 
629
- // 1. Default: Crop based on the landscape UI box
630
- let uiCropBbox = {
631
- minX: overlayBbox.xMin / 100,
632
- minY: overlayBbox.yMin / 100,
633
- width: (overlayBbox.xMax - overlayBbox.xMin) / 100,
634
- height: (overlayBbox.yMax - overlayBbox.yMin) / 100
635
- };
629
+ // Prefer the backend-detected card bounds. Front verification returns the
630
+ // detect_face OBB-derived bbox; back verification returns extract_mrz's
631
+ // OBB-derived bbox when MRZ is used. The fixed UI guide is only a fallback.
632
+ const detectedBbox = verified.bbox;
633
+ const hasDetectedBbox = detectedBbox
634
+ && Number.isFinite(detectedBbox.minX)
635
+ && Number.isFinite(detectedBbox.minY)
636
+ && Number.isFinite(detectedBbox.width)
637
+ && Number.isFinite(detectedBbox.height)
638
+ && detectedBbox.width > 0
639
+ && detectedBbox.height > 0;
640
+
641
+ let cropBbox: IBbox = hasDetectedBbox
642
+ ? detectedBbox
643
+ : {
644
+ minX: overlayBbox.xMin / 100,
645
+ minY: overlayBbox.yMin / 100,
646
+ width: (overlayBbox.xMax - overlayBbox.xMin) / 100,
647
+ height: (overlayBbox.yMax - overlayBbox.yMin) / 100,
648
+ };
649
+ const isSpecificPortrait = Boolean(
650
+ verified.templatePath?.includes('cameroon_id_front_1_1_new'),
651
+ );
636
652
 
637
- try {
638
- const isSpecificPortrait = verified.templatePath && verified.templatePath.includes('cameroon_id_front_1_1_new');
639
-
640
- if (isSpecificPortrait) {
641
- uiCropBbox = {
642
- minX: 0.15,
643
- minY: 0.15,
644
- width: 0.70,
645
- height: 0.70
646
- };
647
- }
653
+ try {
654
+ if (!hasDetectedBbox && isSpecificPortrait) {
655
+ cropBbox = {
656
+ minX: 0.15,
657
+ minY: 0.15,
658
+ width: 0.70,
659
+ height: 0.70,
660
+ };
661
+ }
648
662
 
649
- const cropTolerance = isSpecificPortrait ? 0.15 : 0.06;
663
+ // OBB bounds already track the physical card, so only retain a small
664
+ // safety margin. UI-guide fallbacks remain more forgiving.
665
+ const cropTolerance = hasDetectedBbox ? 0.025 : (isSpecificPortrait ? 0.15 : 0.06);
650
666
 
651
- imagePathForUpload = await cropImageWithBBoxWithTolerance(safeCapturePath, uiCropBbox, cropTolerance);
667
+ imagePathForUpload = await cropImageWithBBoxWithTolerance(
668
+ safeCapturePath,
669
+ cropBbox,
670
+ cropTolerance,
671
+ isSpecificPortrait ? 'portrait' : 'landscape',
672
+ );
673
+ sdkLogger.info('Prepared captured document using verified card bounds', {
674
+ side: captureSide,
675
+ cropSource: hasDetectedBbox
676
+ ? (captureSide === 'front' ? 'detect_face_obb' : 'extract_mrz_or_template_obb')
677
+ : 'camera_overlay_fallback',
678
+ bbox: cropBbox,
679
+ });
652
680
  } catch (e) {
653
681
  console.warn("Crop failed, falling back to original image", e);
654
682
  imagePathForUpload = safeCapturePath;
@@ -59,6 +59,7 @@ export interface TemplateKYCExampleProps {
59
59
  referenceId?: string;
60
60
  onSessionSave?: (sessionId: string) => void;
61
61
  kyc_session_id?: string;
62
+ templateConfig?: Record<string, string>;
62
63
  }
63
64
 
64
65
  export function TemplateKYCExample({
@@ -77,7 +78,8 @@ export function TemplateKYCExample({
77
78
  initialCountryResume,
78
79
  referenceId,
79
80
  onSessionSave,
80
- kyc_session_id
81
+ kyc_session_id,
82
+ templateConfig,
81
83
  }: TemplateKYCExampleProps): JSX.Element {
82
84
 
83
85
  const handleComplete = (data: VerificationState) => {
@@ -150,6 +152,7 @@ export function TemplateKYCExample({
150
152
  <TemplateKYCFlow
151
153
  template={templateToUse}
152
154
  templateId={templateId}
155
+ templateConfig={templateConfig}
153
156
  onComplete={handleComplete}
154
157
  onError={handleError}
155
158
  onCancel={handleCancel}
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { View, Text, StyleSheet, SafeAreaView, TouchableOpacity, ActivityIndicator, Dimensions, ScrollView, Platform } from 'react-native';
3
3
  import { KYCTemplate, VerificationState } from '../types/KYC.types';
4
4
  import { TemplateKYCFlowProvider, useTemplateKYCFlowContext } from '../hooks/useTemplateKYCFlow';
@@ -39,6 +39,7 @@ interface TemplateKYCFlowProps {
39
39
  referenceId?: string;
40
40
  onSessionSave?: (sessionId: string) => void;
41
41
  kyc_session_id?: string;
42
+ templateConfig?: Record<string, string>;
42
43
  }
43
44
 
44
45
  export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
@@ -58,9 +59,12 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
58
59
  referenceId,
59
60
  onSessionSave,
60
61
  kyc_session_id,
62
+ templateConfig,
61
63
  }) => {
62
64
  const { t } = useI18n();
63
65
  const { template: loadedTemplate, isLoading, error, loadTemplate } = useTemplateLoader();
66
+ const [resolvedTemplateId, setResolvedTemplateId] = useState<string | undefined>(templateId);
67
+ const [isResolving, setIsResolving] = useState<boolean>(!templateId && !!templateConfig);
64
68
 
65
69
  // 🚨 1. Determine the active API key based on the environment
66
70
  const activeApiKey = env === 'PRODUCTION' ? API_KEY : (TEST_API_KEY || API_KEY);
@@ -77,23 +81,74 @@ export const TemplateKYCFlow: React.FC<TemplateKYCFlowProps> = ({
77
81
  }
78
82
  }, [serverEnv]);
79
83
 
84
+
80
85
  useEffect(() => {
81
- if (!providedTemplate && !templateId) {
82
- const errorMsg = 'Either template or templateId must be provided';
86
+ // If a strict templateId is provided, use it immediately and skip geolocation
87
+ if (templateId) {
88
+ setResolvedTemplateId(templateId);
89
+ setIsResolving(false);
90
+ return;
91
+ }
92
+
93
+ // If neither templateId nor templateConfig is provided, skip to the next effect
94
+ if (!templateConfig) {
95
+ setIsResolving(false);
96
+ return;
97
+ }
98
+
99
+ const fetchLocationAndRoute = async () => {
100
+ setIsResolving(true);
101
+ let selected = templateConfig['DEFAULT'];
102
+
103
+ try {
104
+ const response = await fetch('https://ipapi.co/json/');
105
+ const data = await response.json();
106
+
107
+ // Priority: Exact Country -> Continent -> DEFAULT
108
+ selected =
109
+ templateConfig[data.country_code] ||
110
+ templateConfig[data.continent_code] ||
111
+ selected;
112
+
113
+ logger.info('Template dynamically resolved via location', {
114
+ country: data.country_code,
115
+ continent: data.continent_code,
116
+ selected_template: selected
117
+ });
118
+
119
+ } catch (error) {
120
+ logger.warn('Location detection failed, using default template');
121
+ } finally {
122
+ setResolvedTemplateId(selected);
123
+ setIsResolving(false);
124
+ }
125
+ };
126
+
127
+ fetchLocationAndRoute();
128
+ }, [templateId, templateConfig]); // Only re-run if the props change
129
+
130
+
131
+
132
+ useEffect(() => {
133
+ if (isResolving) return;
134
+
135
+ // Updated error check to include templateConfig
136
+ if (!providedTemplate && !resolvedTemplateId) {
137
+ const errorMsg = 'Either template, templateId, or templateConfig must be provided';
83
138
  logger.error("Template Loading Failed: Missing Props", { errorMsg });
84
139
  onError?.(errorMsg);
85
140
  return;
86
141
  }
87
142
 
88
- if (templateId && !activeApiKey) {
89
- logger.log(`Fetching template ${templateId} via token authentication`);
90
- loadTemplate(templateId);
91
- } else if (templateId && activeApiKey) {
92
- logger.log(`Fetching template ${templateId} via API Key`);
93
- // 🚨 2. Use the resolved active key here
94
- loadTemplate(templateId, activeApiKey);
143
+ // Load using the newly resolved ID
144
+ if (resolvedTemplateId && !activeApiKey) {
145
+ logger.log(`Fetching template ${resolvedTemplateId} via token authentication`);
146
+ loadTemplate(resolvedTemplateId);
147
+ } else if (resolvedTemplateId && activeApiKey) {
148
+ logger.log(`Fetching template ${resolvedTemplateId} via API Key`);
149
+ loadTemplate(resolvedTemplateId, activeApiKey);
95
150
  }
96
- }, [templateId, activeApiKey, providedTemplate, loadTemplate, onError]);
151
+ }, [resolvedTemplateId, activeApiKey, providedTemplate, loadTemplate, onError, isResolving]);
97
152
 
98
153
  useEffect(() => {
99
154
  if (error) {
@@ -1,81 +1,253 @@
1
1
  import { Country } from "../types/KYC.types";
2
2
 
3
3
  export const countryData: Record<string, Country> = {
4
- FR: { name: 'France', name_en: "France", flag: '🇫🇷' },
5
- CM: { name: 'Cameroun', name_en: "Cameroon", flag: '🇨🇲' },
6
- US: { name: 'États-Unis', name_en: "United States of America", flag: '🇺🇸' },
7
- DE: { name: 'Allemagne', name_en: "Germany", flag: '🇩🇪' },
8
- BE: { name: 'Belgique', name_en: "Belgium", flag: '🇧🇪' },
9
- LU: { name: 'Luxembourg', name_en: "Luxembourg", flag: '🇱🇺' },
10
- IT: { name: 'Italie', name_en: "Italy", flag: '🇮🇹' },
11
- ES: { name: 'Espagne', name_en: "Spain", flag: '🇪🇸' },
12
- PT: { name: 'Portugal', name_en: "Portugal", flag: '🇵🇹' },
13
- AT: { name: 'Autriche', name_en: "Austria", flag: '🇦🇹' },
14
- CH: { name: 'Suisse', name_en: "Switzerland", flag: '🇨🇭' },
15
- NL: { name: 'Pays-Bas', name_en: "Netherlands", flag: '🇳🇱' },
16
- CA: { name: 'Canada', name_en: "Canada", flag: '🇨🇦', hasRegions: true },
17
- GB: { name: 'Royaume-Uni', name_en: "United Kingdom", flag: '🇬🇧' },
18
- AU: { name: 'Australie', name_en: "Australia", flag: '🇦🇺' },
19
- JP: { name: 'Japon', name_en: "Japan", flag: '🇯🇵' },
20
- KR: { name: 'Corée du Sud', name_en: "South Korea", flag: '🇰🇷' },
21
- SG: { name: 'Singapour', name_en: "Singapore", flag: '🇸🇬' },
22
- HK: { name: 'Hong Kong', name_en: "Hong Kong", flag: '🇭🇰' },
23
- AE: { name: 'Émirats Arabes Unis', name_en: "United Arab Emirates", flag: '🇦🇪' },
24
- SA: { name: 'Arabie Saoudite', name_en: "Saudi Arabia", flag: '🇸🇦' },
25
- QA: { name: 'Qatar', name_en: "Qatar", flag: '🇶🇦' },
26
- KW: { name: 'Koweït', name_en: "Kuwait", flag: '🇰🇼' },
27
- BH: { name: 'Bahreïn', name_en: "Bahrain", flag: '🇧🇭' },
28
- OM: { name: 'Oman', name_en: "Oman", flag: '🇴🇲' },
29
- JO: { name: 'Jordanie', name_en: "Jordan", flag: '🇯🇴' },
30
- LB: { name: 'Liban', name_en: "Lebanon", flag: '🇱🇧' },
31
- EG: { name: 'Égypte', name_en: "Egypt", flag: '🇪🇬' },
32
- MA: { name: 'Maroc', name_en: "Morocco", flag: '🇲🇦' },
33
- TN: { name: 'Tunisie', name_en: "Tunisia", flag: '🇹🇳' },
34
- DZ: { name: 'Algérie', name_en: "Algeria", flag: '🇩🇿' },
35
- SN: { name: 'Sénégal', name_en: "Senegal", flag: '🇸🇳' },
36
- CI: { name: 'Côte d\'Ivoire', name_en: "Ivory Coast", flag: '🇨🇮' },
37
- NG: { name: 'Nigeria', name_en: "Nigeria", flag: '🇳🇬' },
38
- KE: { name: 'Kenya', name_en: "Kenya", flag: '🇰🇪' },
39
- ZA: { name: 'Afrique du Sud', name_en: "South Africa", flag: '🇿🇦' },
40
- BR: { name: 'Brésil', name_en: "Brazil", flag: '🇧🇷' },
41
- MX: { name: 'Mexique', name_en: "Mexico", flag: '🇲🇽' },
42
- AR: { name: 'Argentine', name_en: "Argentina", flag: '🇦🇷' },
43
- CL: { name: 'Chili', name_en: "Chile", flag: '🇨🇱' },
44
- PE: { name: 'Pérou', name_en: "Peru", flag: '🇵🇪' },
45
- CO: { name: 'Colombie', name_en: "Colombia", flag: '🇨🇴' },
46
- VE: { name: 'Venezuela', name_en: "Venezuela", flag: '🇻🇪' },
47
- EC: { name: 'Équateur', name_en: "Ecuador", flag: '🇪🇨' },
48
- UY: { name: 'Uruguay', name_en: "Uruguay", flag: '🇺🇾' },
49
- PY: { name: 'Paraguay', name_en: "Paraguay", flag: '🇵🇾' },
50
- BO: { name: 'Bolivie', name_en: "Bolivia", flag: '🇧🇴' },
51
- IN: { name: 'Inde', name_en: "India", flag: '🇮🇳' },
52
- CN: { name: 'Chine', name_en: "China", flag: '🇨🇳' },
53
- TH: { name: 'Thaïlande', name_en: "Thailand", flag: '🇹🇭' },
54
- VN: { name: 'Vietnam', name_en: "Vietnam", flag: '🇻🇳' },
55
- ID: { name: 'Indonésie', name_en: "Indonesia", flag: '🇮🇩' },
56
- MY: { name: 'Malaisie', name_en: "Malaysia", flag: '🇲🇾' },
57
- PH: { name: 'Philippines', name_en: "Philippines", flag: '🇵🇭' },
58
- TR: { name: 'Turquie', name_en: "Turkey", flag: '🇹🇷' },
59
- IL: { name: 'Israël', name_en: "Israel", flag: '🇮🇱' },
60
- RU: { name: 'Russie', name_en: "Russia", flag: '🇷🇺' },
61
- UA: { name: 'Ukraine', name_en: "Ukraine", flag: '🇺🇦' },
62
- PL: { name: 'Pologne', name_en: "Poland", flag: '🇵🇱' },
63
- CZ: { name: 'République Tchèque', name_en: "Czech Republic", flag: '🇨🇿' },
64
- HU: { name: 'Hongrie', name_en: "Hungary", flag: '🇭🇺' },
65
- RO: { name: 'Roumanie', name_en: "Romania", flag: '🇷🇴' },
66
- BG: { name: 'Bulgarie', name_en: "Bulgaria", flag: '🇧🇬' },
67
- HR: { name: 'Croatie', name_en: "Croatia", flag: '🇭🇷' },
68
- SI: { name: 'Slovénie', name_en: "Slovenia", flag: '🇸🇮' },
69
- SK: { name: 'Slovaquie', name_en: "Slovakia", flag: '🇸🇰' },
70
- LT: { name: 'Lituanie', name_en: "Lithuania", flag: '🇱🇹' },
71
- LV: { name: 'Lettonie', name_en: "Latvia", flag: '🇱🇻' },
72
- EE: { name: 'Estonie', name_en: "Estonia", flag: '🇪🇪' },
73
- FI: { name: 'Finlande', name_en: "Finland", flag: '🇫🇮' },
74
- SE: { name: 'Suède', name_en: "Sweden", flag: '🇸🇪' },
75
- NO: { name: 'Norvège', name_en: "Norway", flag: '🇳🇴' },
76
- DK: { name: 'Danemark', name_en: "Denmark", flag: '🇩🇰' },
77
- IS: { name: 'Islande', name_en: "Iceland", flag: '🇮🇸' },
78
- IE: { name: 'Irlande', name_en: "Ireland", flag: '🇮🇪' },
79
- NZ: { name: 'Nouvelle-Zélande', name_en: "New Zealand", flag: '🇳🇿' },
80
- GH: { name: 'Ghana', name_en: "Ghana", flag: '🇬🇭' },
81
- };
4
+ AD: { name: "Andorre", name_en: "Andorra", flag: "🇦🇩" },
5
+ AE: { name: "Émirats Arabes Unis", name_en: "United Arab Emirates", flag: "🇦🇪" },
6
+ AF: { name: "Afghanistan", name_en: "Afghanistan", flag: "🇦🇫" },
7
+ AG: { name: "Antigua-et-Barbuda", name_en: "Antigua and Barbuda", flag: "🇦🇬" },
8
+ AI: { name: "Anguilla", name_en: "Anguilla", flag: "🇦🇮" },
9
+ AL: { name: "Albanie", name_en: "Albania", flag: "🇦🇱" },
10
+ AM: { name: "Arménie", name_en: "Armenia", flag: "🇦🇲" },
11
+ AO: { name: "Angola", name_en: "Angola", flag: "🇦🇴" },
12
+ AQ: { name: "Antarctique", name_en: "Antarctica", flag: "🇦🇶" },
13
+ AR: { name: "Argentine", name_en: "Argentina", flag: "🇦🇷" },
14
+ AS: { name: "Samoa Américaines", name_en: "American Samoa", flag: "🇦🇸" },
15
+ AT: { name: "Autriche", name_en: "Austria", flag: "🇦🇹" },
16
+ AU: { name: "Australie", name_en: "Australia", flag: "🇦🇺" },
17
+ AW: { name: "Aruba", name_en: "Aruba", flag: "🇦🇼" },
18
+ AX: { name: "Îles Åland", name_en: "Åland Islands", flag: "🇦🇽" },
19
+ AZ: { name: "Azerbaïdjan", name_en: "Azerbaijan", flag: "🇦🇿" },
20
+ BA: { name: "Bosnie-Herzégovine", name_en: "Bosnia and Herzegovina", flag: "🇧🇦" },
21
+ BB: { name: "Barbade", name_en: "Barbados", flag: "🇧🇧" },
22
+ BD: { name: "Bangladesh", name_en: "Bangladesh", flag: "🇧🇩" },
23
+ BE: { name: "Belgique", name_en: "Belgium", flag: "🇧🇪" },
24
+ BF: { name: "Burkina Faso", name_en: "Burkina Faso", flag: "🇧🇫" },
25
+ BG: { name: "Bulgarie", name_en: "Bulgaria", flag: "🇧🇬" },
26
+ BH: { name: "Bahreïn", name_en: "Bahrain", flag: "🇧🇭" },
27
+ BI: { name: "Burundi", name_en: "Burundi", flag: "🇧🇮" },
28
+ BJ: { name: "Bénin", name_en: "Benin", flag: "🇧🇯" },
29
+ BL: { name: "Saint-Barthélemy", name_en: "Saint Barthélemy", flag: "🇧🇱" },
30
+ BM: { name: "Bermudes", name_en: "Bermuda", flag: "🇧🇲" },
31
+ BN: { name: "Brunéi Darussalam", name_en: "Brunei", flag: "🇧🇳" },
32
+ BO: { name: "Bolivie", name_en: "Bolivia", flag: "🇧🇴" },
33
+ BQ: { name: "Pays-Bas caribéens", name_en: "Caribbean Netherlands", flag: "🇧🇶" },
34
+ BR: { name: "Brésil", name_en: "Brazil", flag: "🇧🇷" },
35
+ BS: { name: "Bahamas", name_en: "Bahamas", flag: "🇧🇸" },
36
+ BT: { name: "Bhoutan", name_en: "Bhutan", flag: "🇧🇹" },
37
+ BV: { name: "Île Bouvet", name_en: "Bouvet Island", flag: "🇧🇻" },
38
+ BW: { name: "Botswana", name_en: "Botswana", flag: "🇧🇼" },
39
+ BY: { name: "Biélorussie", name_en: "Belarus", flag: "🇧🇾" },
40
+ BZ: { name: "Belize", name_en: "Belize", flag: "🇧🇿" },
41
+ CA: { name: "Canada", name_en: "Canada", flag: "🇨🇦", hasRegions: true },
42
+ CC: { name: "Îles Cocos", name_en: "Cocos (Keeling) Islands", flag: "🇨🇨" },
43
+ CD: { name: "République démocratique du Congo", name_en: "DR Congo", flag: "🇨🇩" },
44
+ CF: { name: "République centrafricaine", name_en: "Central African Republic", flag: "🇨🇫" },
45
+ CG: { name: "Congo", name_en: "Republic of the Congo", flag: "🇨🇬" },
46
+ CH: { name: "Suisse", name_en: "Switzerland", flag: "🇨🇭" },
47
+ CI: { name: "Côte d'Ivoire", name_en: "Ivory Coast", flag: "🇨🇮" },
48
+ CK: { name: "Îles Cook", name_en: "Cook Islands", flag: "🇨🇰" },
49
+ CL: { name: "Chili", name_en: "Chile", flag: "🇨🇱" },
50
+ CM: { name: "Cameroun", name_en: "Cameroon", flag: "🇨🇲" },
51
+ CN: { name: "Chine", name_en: "China", flag: "🇨🇳" },
52
+ CO: { name: "Colombie", name_en: "Colombia", flag: "🇨🇴" },
53
+ CR: { name: "Costa Rica", name_en: "Costa Rica", flag: "🇨🇷" },
54
+ CU: { name: "Cuba", name_en: "Cuba", flag: "🇨🇺" },
55
+ CV: { name: "Cap-Vert", name_en: "Cape Verde", flag: "🇨🇻" },
56
+ CW: { name: "Curaçao", name_en: "Curaçao", flag: "🇨🇼" },
57
+ CX: { name: "Île Christmas", name_en: "Christmas Island", flag: "🇨🇽" },
58
+ CY: { name: "Chypre", name_en: "Cyprus", flag: "🇨🇾" },
59
+ CZ: { name: "République Tchèque", name_en: "Czech Republic", flag: "🇨🇿" },
60
+ DE: { name: "Allemagne", name_en: "Germany", flag: "🇩🇪" },
61
+ DJ: { name: "Djibouti", name_en: "Djibouti", flag: "🇩🇯" },
62
+ DK: { name: "Danemark", name_en: "Denmark", flag: "🇩🇰" },
63
+ DM: { name: "Dominique", name_en: "Dominica", flag: "🇩🇲" },
64
+ DO: { name: "République dominicaine", name_en: "Dominican Republic", flag: "🇩🇴" },
65
+ DZ: { name: "Algérie", name_en: "Algeria", flag: "🇩🇿" },
66
+ EC: { name: "Équateur", name_en: "Ecuador", flag: "🇪🇨" },
67
+ EE: { name: "Estonie", name_en: "Estonia", flag: "🇪🇪" },
68
+ EG: { name: "Égypte", name_en: "Egypt", flag: "🇪🇬" },
69
+ EH: { name: "Sahara occidental", name_en: "Western Sahara", flag: "🇪🇭" },
70
+ ER: { name: "Érythrée", name_en: "Eritrea", flag: "🇪🇷" },
71
+ ES: { name: "Espagne", name_en: "Spain", flag: "🇪🇸" },
72
+ ET: { name: "Éthiopie", name_en: "Ethiopia", flag: "🇪🇹" },
73
+ FI: { name: "Finlande", name_en: "Finland", flag: "🇫🇮" },
74
+ FJ: { name: "Fidji", name_en: "Fiji", flag: "🇫🇯" },
75
+ FK: { name: "Îles Malouines", name_en: "Falkland Islands", flag: "🇫🇰" },
76
+ FM: { name: "Micronésie", name_en: "Micronesia", flag: "🇫🇲" },
77
+ FO: { name: "Îles Féroé", name_en: "Faroe Islands", flag: "🇫🇴" },
78
+ FR: { name: "France", name_en: "France", flag: "🇫🇷" },
79
+ GA: { name: "Gabon", name_en: "Gabon", flag: "🇬🇦" },
80
+ GB: { name: "Royaume-Uni", name_en: "United Kingdom", flag: "🇬🇧" },
81
+ GD: { name: "Grenade", name_en: "Grenada", flag: "🇬🇩" },
82
+ GE: { name: "Géorgie", name_en: "Georgia", flag: "🇬🇪" },
83
+ GF: { name: "Guyane", name_en: "French Guiana", flag: "🇬🇫" },
84
+ GG: { name: "Guernesey", name_en: "Guernsey", flag: "🇬🇬" },
85
+ GH: { name: "Ghana", name_en: "Ghana", flag: "🇬🇭" },
86
+ GI: { name: "Gibraltar", name_en: "Gibraltar", flag: "🇬🇮" },
87
+ GL: { name: "Groenland", name_en: "Greenland", flag: "🇬🇱" },
88
+ GM: { name: "Gambie", name_en: "Gambia", flag: "🇬🇲" },
89
+ GN: { name: "Guinée", name_en: "Guinea", flag: "🇬🇳" },
90
+ GP: { name: "Guadeloupe", name_en: "Guadeloupe", flag: "🇬🇵" },
91
+ GQ: { name: "Guinée équatoriale", name_en: "Equatorial Guinea", flag: "🇬🇶" },
92
+ GR: { name: "Grèce", name_en: "Greece", flag: "🇬🇷" },
93
+ GS: { name: "Géorgie du Sud-et-les Îles Sandwich du Sud", name_en: "South Georgia", flag: "🇬🇸" },
94
+ GT: { name: "Guatemala", name_en: "Guatemala", flag: "🇬🇹" },
95
+ GU: { name: "Guam", name_en: "Guam", flag: "🇬🇺" },
96
+ GW: { name: "Guinée-Bissau", name_en: "Guinea-Bissau", flag: "🇬🇼" },
97
+ GY: { name: "Guyana", name_en: "Guyana", flag: "🇬🇾" },
98
+ HK: { name: "Hong Kong", name_en: "Hong Kong", flag: "🇭🇰" },
99
+ HM: { name: "Îles Heard-et-MacDonald", name_en: "Heard Island and McDonald Islands", flag: "🇭🇲" },
100
+ HN: { name: "Honduras", name_en: "Honduras", flag: "🇭🇳" },
101
+ HR: { name: "Croatie", name_en: "Croatia", flag: "🇭🇷" },
102
+ HT: { name: "Haïti", name_en: "Haiti", flag: "🇭🇹" },
103
+ HU: { name: "Hongrie", name_en: "Hungary", flag: "🇭🇺" },
104
+ ID: { name: "Indonésie", name_en: "Indonesia", flag: "🇮🇩" },
105
+ IE: { name: "Irlande", name_en: "Ireland", flag: "🇮🇪" },
106
+ IL: { name: "Israël", name_en: "Israel", flag: "🇮🇱" },
107
+ IM: { name: "Île de Man", name_en: "Isle of Man", flag: "🇮🇲" },
108
+ IN: { name: "Inde", name_en: "India", flag: "🇮🇳" },
109
+ IO: { name: "Territoire britannique de l'océan Indien", name_en: "British Indian Ocean Territory", flag: "🇮🇴" },
110
+ IQ: { name: "Irak", name_en: "Iraq", flag: "🇮🇶" },
111
+ IR: { name: "Iran", name_en: "Iran", flag: "🇮🇷" },
112
+ IS: { name: "Islande", name_en: "Iceland", flag: "🇮🇸" },
113
+ IT: { name: "Italie", name_en: "Italy", flag: "🇮🇹" },
114
+ JE: { name: "Jersey", name_en: "Jersey", flag: "🇯🇪" },
115
+ JM: { name: "Jamaïque", name_en: "Jamaica", flag: "🇯🇲" },
116
+ JO: { name: "Jordanie", name_en: "Jordan", flag: "🇯🇴" },
117
+ JP: { name: "Japon", name_en: "Japan", flag: "🇯🇵" },
118
+ KE: { name: "Kenya", name_en: "Kenya", flag: "🇰🇪" },
119
+ KG: { name: "Kirghizistan", name_en: "Kyrgyzstan", flag: "🇰🇬" },
120
+ KH: { name: "Cambodge", name_en: "Cambodia", flag: "🇰🇭" },
121
+ KI: { name: "Kiribati", name_en: "Kiribati", flag: "🇰🇮" },
122
+ KM: { name: "Comores", name_en: "Comoros", flag: "🇰🇲" },
123
+ KN: { name: "Saint-Kitts-et-Nevis", name_en: "Saint Kitts and Nevis", flag: "🇰🇳" },
124
+ KP: { name: "Corée du Nord", name_en: "North Korea", flag: "🇰🇵" },
125
+ KR: { name: "Corée du Sud", name_en: "South Korea", flag: "🇰🇷" },
126
+ KW: { name: "Koweït", name_en: "Kuwait", flag: "🇰🇼" },
127
+ KY: { name: "Îles Caïmans", name_en: "Cayman Islands", flag: "🇰🇾" },
128
+ KZ: { name: "Kazakhstan", name_en: "Kazakhstan", flag: "🇰🇿" },
129
+ LA: { name: "Laos", name_en: "Laos", flag: "🇱🇦" },
130
+ LB: { name: "Liban", name_en: "Lebanon", flag: "🇱🇧" },
131
+ LC: { name: "Sainte-Lucie", name_en: "Saint Lucia", flag: "🇱🇨" },
132
+ LI: { name: "Liechtenstein", name_en: "Liechtenstein", flag: "🇱🇮" },
133
+ LK: { name: "Sri Lanka", name_en: "Sri Lanka", flag: "🇱🇰" },
134
+ LR: { name: "Libéria", name_en: "Liberia", flag: "🇱🇷" },
135
+ LS: { name: "Lesotho", name_en: "Lesotho", flag: "🇱🇸" },
136
+ LT: { name: "Lituanie", name_en: "Lithuania", flag: "🇱🇹" },
137
+ LU: { name: "Luxembourg", name_en: "Luxembourg", flag: "🇱🇺" },
138
+ LV: { name: "Lettonie", name_en: "Latvia", flag: "🇱🇻" },
139
+ LY: { name: "Libye", name_en: "Libya", flag: "🇱🇾" },
140
+ MA: { name: "Maroc", name_en: "Morocco", flag: "🇲🇦" },
141
+ MC: { name: "Monaco", name_en: "Monaco", flag: "🇲🇨" },
142
+ MD: { name: "Moldavie", name_en: "Moldova", flag: "🇲🇩" },
143
+ ME: { name: "Monténégro", name_en: "Montenegro", flag: "🇲🇪" },
144
+ MF: { name: "Saint-Martin", name_en: "Saint Martin", flag: "🇲🇫" },
145
+ MG: { name: "Madagascar", name_en: "Madagascar", flag: "🇲🇬" },
146
+ MH: { name: "Îles Marshall", name_en: "Marshall Islands", flag: "🇲🇭" },
147
+ MK: { name: "Macédoine du Nord", name_en: "North Macedonia", flag: "🇲🇰" },
148
+ ML: { name: "Mali", name_en: "Mali", flag: "🇲🇱" },
149
+ MM: { name: "Myanmar", name_en: "Myanmar", flag: "🇲🇲" },
150
+ MN: { name: "Mongolie", name_en: "Mongolia", flag: "🇲🇳" },
151
+ MO: { name: "Macao", name_en: "Macau", flag: "🇲🇴" },
152
+ MP: { name: "Îles Mariannes du Nord", name_en: "Northern Mariana Islands", flag: "🇲🇵" },
153
+ MQ: { name: "Martinique", name_en: "Martinique", flag: "🇲🇶" },
154
+ MR: { name: "Mauritanie", name_en: "Mauritania", flag: "🇲🇷" },
155
+ MS: { name: "Montserrat", name_en: "Montserrat", flag: "🇲🇸" },
156
+ MT: { name: "Malte", name_en: "Malta", flag: "🇲🇹" },
157
+ MU: { name: "Maurice", name_en: "Mauritius", flag: "🇲🇺" },
158
+ MV: { name: "Maldives", name_en: "Maldives", flag: "🇲🇻" },
159
+ MW: { name: "Malawi", name_en: "Malawi", flag: "🇲🇼" },
160
+ MX: { name: "Mexique", name_en: "Mexico", flag: "🇲🇽" },
161
+ MY: { name: "Malaisie", name_en: "Malaysia", flag: "🇲🇾" },
162
+ MZ: { name: "Mozambique", name_en: "Mozambique", flag: "🇲🇿" },
163
+ NA: { name: "Namibie", name_en: "Namibia", flag: "🇳🇦" },
164
+ NC: { name: "Nouvelle-Calédonie", name_en: "New Caledonia", flag: "🇳🇨" },
165
+ NE: { name: "Niger", name_en: "Niger", flag: "🇳🇪" },
166
+ NF: { name: "Île Norfolk", name_en: "Norfolk Island", flag: "🇳🇫" },
167
+ NG: { name: "Nigeria", name_en: "Nigeria", flag: "🇳🇬" },
168
+ NI: { name: "Nicaragua", name_en: "Nicaragua", flag: "🇳🇮" },
169
+ NL: { name: "Pays-Bas", name_en: "Netherlands", flag: "🇳🇱" },
170
+ NO: { name: "Norvège", name_en: "Norway", flag: "🇳🇴" },
171
+ NP: { name: "Népal", name_en: "Nepal", flag: "🇳🇵" },
172
+ NR: { name: "Nauru", name_en: "Nauru", flag: "🇳🇷" },
173
+ NU: { name: "Niue", name_en: "Niue", flag: "🇳🇺" },
174
+ NZ: { name: "Nouvelle-Zélande", name_en: "New Zealand", flag: "🇳🇿" },
175
+ OM: { name: "Oman", name_en: "Oman", flag: "🇴🇲" },
176
+ PA: { name: "Panama", name_en: "Panama", flag: "🇵🇦" },
177
+ PE: { name: "Pérou", name_en: "Peru", flag: "🇵🇪" },
178
+ PF: { name: "Polynésie française", name_en: "French Polynesia", flag: "🇵🇫" },
179
+ PG: { name: "Papouasie-Nouvelle-Guinée", name_en: "Papua New Guinea", flag: "🇵🇬" },
180
+ PH: { name: "Philippines", name_en: "Philippines", flag: "🇵🇭" },
181
+ PK: { name: "Pakistan", name_en: "Pakistan", flag: "🇵🇰" },
182
+ PL: { name: "Pologne", name_en: "Poland", flag: "🇵🇱" },
183
+ PM: { name: "Saint-Pierre-et-Miquelon", name_en: "Saint Pierre and Miquelon", flag: "🇵🇲" },
184
+ PN: { name: "Pitcairn", name_en: "Pitcairn", flag: "🇵🇳" },
185
+ PR: { name: "Porto Rico", name_en: "Puerto Rico", flag: "🇵🇷" },
186
+ PS: { name: "Palestine", name_en: "Palestine", flag: "🇵🇸" },
187
+ PT: { name: "Portugal", name_en: "Portugal", flag: "🇵🇹" },
188
+ PW: { name: "Palaos", name_en: "Palau", flag: "🇵🇼" },
189
+ PY: { name: "Paraguay", name_en: "Paraguay", flag: "🇵🇾" },
190
+ QA: { name: "Qatar", name_en: "Qatar", flag: "🇶🇦" },
191
+ RE: { name: "La Réunion", name_en: "Réunion", flag: "🇷🇪" },
192
+ RO: { name: "Roumanie", name_en: "Romania", flag: "🇷🇴" },
193
+ RS: { name: "Serbie", name_en: "Serbia", flag: "🇷🇸" },
194
+ RU: { name: "Russie", name_en: "Russia", flag: "🇷🇺" },
195
+ RW: { name: "Rwanda", name_en: "Rwanda", flag: "🇷🇼" },
196
+ SA: { name: "Arabie Saoudite", name_en: "Saudi Arabia", flag: "🇸🇦" },
197
+ SB: { name: "Îles Salomon", name_en: "Solomon Islands", flag: "🇸🇧" },
198
+ SC: { name: "Seychelles", name_en: "Seychelles", flag: "🇸🇨" },
199
+ SD: { name: "Soudan", name_en: "Sudan", flag: "🇸🇩" },
200
+ SE: { name: "Suède", name_en: "Sweden", flag: "🇸🇪" },
201
+ SG: { name: "Singapour", name_en: "Singapore", flag: "🇸🇬" },
202
+ SH: { name: "Sainte-Hélène", name_en: "Saint Helena", flag: "🇸🇭" },
203
+ SI: { name: "Slovénie", name_en: "Slovenia", flag: "🇸🇮" },
204
+ SJ: { name: "Svalbard et Jan Mayen", name_en: "Svalbard and Jan Mayen", flag: "🇸🇯" },
205
+ SK: { name: "Slovaquie", name_en: "Slovakia", flag: "🇸🇰" },
206
+ SL: { name: "Sierra Leone", name_en: "Sierra Leone", flag: "🇸🇱" },
207
+ SM: { name: "Saint-Marin", name_en: "San Marino", flag: "🇸🇲" },
208
+ SN: { name: "Sénégal", name_en: "Senegal", flag: "🇸🇳" },
209
+ SO: { name: "Somalie", name_en: "Somalia", flag: "🇸🇴" },
210
+ SR: { name: "Suriname", name_en: "Suriname", flag: "🇸🇷" },
211
+ SS: { name: "Soudan du Sud", name_en: "South Sudan", flag: "🇸🇸" },
212
+ ST: { name: "Sao Tomé-et-Principe", name_en: "Sao Tome and Principe", flag: "🇸🇹" },
213
+ SV: { name: "Salvador", name_en: "El Salvador", flag: "🇸🇻" },
214
+ SX: { name: "Saint-Martin (partie néerlandaise)", name_en: "Sint Maarten", flag: "🇸🇽" },
215
+ SY: { name: "Syrie", name_en: "Syria", flag: "🇸🇾" },
216
+ SZ: { name: "Eswatini", name_en: "Eswatini", flag: "🇸🇿" },
217
+ TC: { name: "Îles Turques-et-Caïques", name_en: "Turks and Caicos Islands", flag: "🇹🇨" },
218
+ TD: { name: "Tchad", name_en: "Chad", flag: "🇹🇩" },
219
+ TF: { name: "Terres australes françaises", name_en: "French Southern Territories", flag: "🇹🇫" },
220
+ TG: { name: "Togo", name_en: "Togo", flag: "🇹🇬" },
221
+ TH: { name: "Thaïlande", name_en: "Thailand", flag: "🇹🇭" },
222
+ TJ: { name: "Tadjikistan", name_en: "Tajikistan", flag: "🇹🇯" },
223
+ TK: { name: "Tokelau", name_en: "Tokelau", flag: "🇹🇰" },
224
+ TL: { name: "Timor oriental", name_en: "Timor-Leste", flag: "🇹🇱" },
225
+ TM: { name: "Turkménistan", name_en: "Turkmenistan", flag: "🇹🇲" },
226
+ TN: { name: "Tunisie", name_en: "Tunisia", flag: "🇹🇳" },
227
+ TO: { name: "Tonga", name_en: "Tonga", flag: "🇹🇴" },
228
+ TR: { name: "Turquie", name_en: "Turkey", flag: "🇹🇷" },
229
+ TT: { name: "Trinité-et-Tobago", name_en: "Trinidad and Tobago", flag: "🇹🇹" },
230
+ TV: { name: "Tuvalu", name_en: "Tuvalu", flag: "🇹🇻" },
231
+ TW: { name: "Taïwan", name_en: "Taiwan", flag: "🇹🇼" },
232
+ TZ: { name: "Tanzanie", name_en: "Tanzania", flag: "🇹🇿" },
233
+ UA: { name: "Ukraine", name_en: "Ukraine", flag: "🇺🇦" },
234
+ UG: { name: "Ouganda", name_en: "Uganda", flag: "🇺🇬" },
235
+ UM: { name: "Îles mineures éloignées des États-Unis", name_en: "United States Minor Outlying Islands", flag: "🇺🇲" },
236
+ US: { name: "États-Unis", name_en: "United States of America", flag: "🇺🇸", hasRegions: true },
237
+ UY: { name: "Uruguay", name_en: "Uruguay", flag: "🇺🇾" },
238
+ UZ: { name: "Ouzbékistan", name_en: "Uzbekistan", flag: "🇺🇿" },
239
+ VA: { name: "Vatican", name_en: "Vatican City", flag: "🇻🇦" },
240
+ VC: { name: "Saint-Vincent-et-les-Grenadines", name_en: "Saint Vincent and the Grenadines", flag: "🇻🇨" },
241
+ VE: { name: "Venezuela", name_en: "Venezuela", flag: "🇻🇪" },
242
+ VG: { name: "Îles Vierges britanniques", name_en: "British Virgin Islands", flag: "🇻🇬" },
243
+ VI: { name: "Îles Vierges des États-Unis", name_en: "United States Virgin Islands", flag: "🇻🇮" },
244
+ VN: { name: "Vietnam", name_en: "Vietnam", flag: "🇻🇳" },
245
+ VU: { name: "Vanuatu", name_en: "Vanuatu", flag: "🇻🇺" },
246
+ WF: { name: "Wallis-et-Futuna", name_en: "Wallis and Futuna", flag: "🇼🇫" },
247
+ WS: { name: "Samoa", name_en: "Samoa", flag: "🇼🇸" },
248
+ YE: { name: "Yémen", name_en: "Yemen", flag: "🇾🇪" },
249
+ YT: { name: "Mayotte", name_en: "Mayotte", flag: "🇾🇹" },
250
+ ZA: { name: "Afrique du Sud", name_en: "South Africa", flag: "🇿🇦" },
251
+ ZM: { name: "Zambie", name_en: "Zambia", flag: "🇿🇲" },
252
+ ZW: { name: "Zimbabwe", name_en: "Zimbabwe", flag: "🇿🇼" }
253
+ };