diff --git a/CovidSafe.xcodeproj/project.pbxproj b/CovidSafe.xcodeproj/project.pbxproj index 399def6..90faf0c 100644 --- a/CovidSafe.xcodeproj/project.pbxproj +++ b/CovidSafe.xcodeproj/project.pbxproj @@ -20,8 +20,6 @@ 0BA617CE242E09B200E6C631 /* FeedbackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BA617CD242E09B200E6C631 /* FeedbackViewController.swift */; }; 0BC141AC24305D9C00399FA8 /* NSMutableString + Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC141AB24305D9C00399FA8 /* NSMutableString + Extensions.swift */; }; 0BC141AE2430685800399FA8 /* UIColor + Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC141AD2430685800399FA8 /* UIColor + Extensions.swift */; }; - 0BDE12302431DCE6003BC44C /* Questions.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1B86118D24303E7D00EA4B6B /* Questions.storyboard */; }; - 1B86118E24303E7D00EA4B6B /* Questions.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1B86118D24303E7D00EA4B6B /* Questions.storyboard */; }; 1B86119124303EF200EA4B6B /* Question1ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B86119024303EF200EA4B6B /* Question1ViewController.swift */; }; 1B86119324303F4A00EA4B6B /* Question2ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B86119224303F4A00EA4B6B /* Question2ViewController.swift */; }; 1B86119524303F5E00EA4B6B /* Question3ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B86119424303F5E00EA4B6B /* Question3ViewController.swift */; }; @@ -98,17 +96,27 @@ 59F25D69245B917A002A7ED8 /* Spinner_home.json in Resources */ = {isa = PBXBuildFile; fileRef = 59F25D68245B917A002A7ED8 /* Spinner_home.json */; }; 59F25D6A245B917A002A7ED8 /* Spinner_home.json in Resources */ = {isa = PBXBuildFile; fileRef = 59F25D68245B917A002A7ED8 /* Spinner_home.json */; }; 59F25D6F245BED80002A7ED8 /* Debug.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 59F25D6E245BED80002A7ED8 /* Debug.storyboard */; }; + 5B110C10248F275B00B68291 /* SelectCountryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B110C0F248F275A00B68291 /* SelectCountryViewController.swift */; }; + 5B110C11248F275B00B68291 /* SelectCountryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B110C0F248F275A00B68291 /* SelectCountryViewController.swift */; }; 5B337AAB245A9BBC00537620 /* UploadDataErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B337AAA245A9BBC00537620 /* UploadDataErrorViewController.swift */; }; 5B337AAC245A9EEC00537620 /* UploadDataPrefaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B577814245A584C0088F111 /* UploadDataPrefaceViewController.swift */; }; 5B337AAD245A9EF800537620 /* UploadDataErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B337AAA245A9BBC00537620 /* UploadDataErrorViewController.swift */; }; 5B337AAF245AA26300537620 /* Spinner_upload.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B337AAE245AA26300537620 /* Spinner_upload.json */; }; 5B337AB0245AA26300537620 /* Spinner_upload.json in Resources */ = {isa = PBXBuildFile; fileRef = 5B337AAE245AA26300537620 /* Spinner_upload.json */; }; + 5B51ED502485D658008CE722 /* UILocalization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B51ED4F2485D658008CE722 /* UILocalization.swift */; }; + 5B51ED512485DF9C008CE722 /* UILocalization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B51ED4F2485D658008CE722 /* UILocalization.swift */; }; + 5B51ED55248627A8008CE722 /* UploadData.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5B51ED58248627A8008CE722 /* UploadData.storyboard */; }; + 5B51ED56248627A8008CE722 /* UploadData.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5B51ED58248627A8008CE722 /* UploadData.storyboard */; }; + 5B51ED61248715DE008CE722 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B51ED64248715DE008CE722 /* InfoPlist.strings */; }; + 5B51ED62248715DE008CE722 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B51ED64248715DE008CE722 /* InfoPlist.strings */; }; 5B577815245A584C0088F111 /* UploadDataPrefaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B577814245A584C0088F111 /* UploadDataPrefaceViewController.swift */; }; 5B7ABF25244D3BC600BB249B /* IsolationSuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7ABF24244D3BC600BB249B /* IsolationSuccessViewController.swift */; }; 5B7ABF26244D3BC600BB249B /* IsolationSuccessViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7ABF24244D3BC600BB249B /* IsolationSuccessViewController.swift */; }; 5B7ABF28244D6BE100BB249B /* UnderSixteenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B7ABF27244D6BE100BB249B /* UnderSixteenViewController.swift */; }; 5B82435E2480DC2100705CB1 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B8243612480DC2100705CB1 /* Localizable.strings */; }; 5B82435F2480DC2100705CB1 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5B8243612480DC2100705CB1 /* Localizable.strings */; }; + 5B900FC12485C4EE00CAA419 /* String+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B900FC02485C4EE00CAA419 /* String+Localization.swift */; }; + 5B900FC22485C4EE00CAA419 /* String+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B900FC02485C4EE00CAA419 /* String+Localization.swift */; }; 5B92D663243011B40049877B /* CovidSafe-config.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B92D662243011B30049877B /* CovidSafe-config.plist */; }; 5B92D66B243018040049877B /* UIProgressView + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B615C5A623F8EB1700345969 /* UIProgressView + Extension.swift */; }; 5B92D66D243018040049877B /* tracer.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5DD41D7723DE141700FD4AB0 /* tracer.xcdatamodeld */; }; @@ -179,14 +187,11 @@ 5B92D6B5243018040049877B /* Encounter+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D8DD06023E319B300E097EF /* Encounter+CoreDataProperties.swift */; }; 5B92D6B6243018040049877B /* Issue.swift in Sources */ = {isa = PBXBuildFile; fileRef = A767D2FF242DF1B000DC9E2A /* Issue.swift */; }; 5B92D6BA243018040049877B /* help_center_article_style.css in Resources */ = {isa = PBXBuildFile; fileRef = D8EB201C23FBE216001C60EC /* help_center_article_style.css */; }; - 5B92D6BB243018040049877B /* UploadData.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6932CE624260E2B003D1810 /* UploadData.storyboard */; }; 5B92D6BD243018040049877B /* JMCTarget.json in Resources */ = {isa = PBXBuildFile; fileRef = A767D2DA242DF1B000DC9E2A /* JMCTarget.json */; }; 5B92D6BF243018040049877B /* NewFeedbackFlow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A767D2D0242DF1B000DC9E2A /* NewFeedbackFlow.storyboard */; }; 5B92D6C7243018040049877B /* CovidSafe-config.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5B92D666243012330049877B /* CovidSafe-config.plist */; }; - 5B92D6C8243018040049877B /* NewFeedbackFlow.strings in Resources */ = {isa = PBXBuildFile; fileRef = A767D2B2242DF1B000DC9E2A /* NewFeedbackFlow.strings */; }; 5B92D6C9243018040049877B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5DD41D4523DCB03D00FD4AB0 /* LaunchScreen.storyboard */; }; 5B92D6CB243018040049877B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5DD41D4323DCB03D00FD4AB0 /* Assets.xcassets */; }; - 5B92D6CC243018040049877B /* Feedback.strings in Resources */ = {isa = PBXBuildFile; fileRef = A767D2B0242DF1B000DC9E2A /* Feedback.strings */; }; 5B92D6CF243018040049877B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5DD41D4023DCB03B00FD4AB0 /* Main.storyboard */; }; 5B92D74F243022EF0049877B /* DataUploadS3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59ACB575242F404500E63E3C /* DataUploadS3.swift */; }; 5B92D750243022F20049877B /* InitiateUploadAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59ACB573242F195A00E63E3C /* InitiateUploadAPI.swift */; }; @@ -215,8 +220,6 @@ 7FACD53A23F25A9A0042A33A /* InitialScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FACD53923F25A9A0042A33A /* InitialScreenViewController.swift */; }; 7FEC361523F16A1E00127AFB /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FEC361423F16A1E00127AFB /* UIViewExtension.swift */; }; 7FF75C222429FEE800C11FEA /* CountriesData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FF75C212429FEE800C11FEA /* CountriesData.swift */; }; - A767D30E242DF1B000DC9E2A /* Feedback.strings in Resources */ = {isa = PBXBuildFile; fileRef = A767D2B0242DF1B000DC9E2A /* Feedback.strings */; }; - A767D30F242DF1B000DC9E2A /* NewFeedbackFlow.strings in Resources */ = {isa = PBXBuildFile; fileRef = A767D2B2242DF1B000DC9E2A /* NewFeedbackFlow.strings */; }; A767D312242DF1B000DC9E2A /* NewFeedbackFlow.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A767D2D0242DF1B000DC9E2A /* NewFeedbackFlow.storyboard */; }; A767D313242DF1B000DC9E2A /* JMCTarget.json in Resources */ = {isa = PBXBuildFile; fileRef = A767D2DA242DF1B000DC9E2A /* JMCTarget.json */; }; A767D316242DF1B000DC9E2A /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = A767D2EB242DF1B000DC9E2A /* Logging.swift */; }; @@ -247,7 +250,6 @@ B60F8BE4242659810007A641 /* UILabelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60F8BE3242659810007A641 /* UILabelExtension.swift */; }; B615C5A723F8EB1700345969 /* UIProgressView + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B615C5A623F8EB1700345969 /* UIProgressView + Extension.swift */; }; B615C5A923FA403500345969 /* UIViewController + Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B615C5A823FA403400345969 /* UIViewController + Extension.swift */; }; - B6932CE724260E2B003D1810 /* UploadData.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6932CE624260E2B003D1810 /* UploadData.storyboard */; }; C5046D5C23EF18600046E96D /* OnboardingStep1ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5046D5B23EF18600046E96D /* OnboardingStep1ViewController.swift */; }; C56CF43F23F18A15006B05B0 /* OnboardingStep4ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56CF43E23F18A15006B05B0 /* OnboardingStep4ViewController.swift */; }; C585C83B23EEB99B0061B7C6 /* GradientButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C585C83A23EEB99B0061B7C6 /* GradientButton.swift */; }; @@ -276,7 +278,6 @@ 0BC141AD2430685800399FA8 /* UIColor + Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor + Extensions.swift"; sourceTree = ""; }; 122AF4E79D17C983066C1CEB /* Pods-CovidSafe-staging.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CovidSafe-staging.release.xcconfig"; path = "Target Support Files/Pods-CovidSafe-staging/Pods-CovidSafe-staging.release.xcconfig"; sourceTree = ""; }; 1925EA5F4413AD52AC198894 /* Pods-CovidSafe.covid-production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CovidSafe.covid-production.xcconfig"; path = "Target Support Files/Pods-CovidSafe/Pods-CovidSafe.covid-production.xcconfig"; sourceTree = ""; }; - 1B86118D24303E7D00EA4B6B /* Questions.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Questions.storyboard; sourceTree = ""; }; 1B86119024303EF200EA4B6B /* Question1ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Question1ViewController.swift; sourceTree = ""; }; 1B86119224303F4A00EA4B6B /* Question2ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Question2ViewController.swift; sourceTree = ""; }; 1B86119424303F5E00EA4B6B /* Question3ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Question3ViewController.swift; sourceTree = ""; }; @@ -327,12 +328,20 @@ 59B7416F24514126006E1EEA /* RegistrationConsentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationConsentViewController.swift; sourceTree = ""; }; 59F25D68245B917A002A7ED8 /* Spinner_home.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Spinner_home.json; sourceTree = ""; }; 59F25D6E245BED80002A7ED8 /* Debug.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Debug.storyboard; sourceTree = ""; }; + 5B110C0F248F275A00B68291 /* SelectCountryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectCountryViewController.swift; sourceTree = ""; }; 5B337AAA245A9BBC00537620 /* UploadDataErrorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadDataErrorViewController.swift; sourceTree = ""; }; 5B337AAE245AA26300537620 /* Spinner_upload.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Spinner_upload.json; sourceTree = ""; }; + 5B51ED4F2485D658008CE722 /* UILocalization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILocalization.swift; sourceTree = ""; }; + 5B51ED63248715DE008CE722 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 5B51ED6D248776CA008CE722 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/NewFeedbackFlow.storyboard; sourceTree = ""; }; + 5B51ED6E248776CA008CE722 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/UploadData.storyboard; sourceTree = ""; }; + 5B51ED6F248776CB008CE722 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 5B577814245A584C0088F111 /* UploadDataPrefaceViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploadDataPrefaceViewController.swift; sourceTree = ""; }; 5B7ABF24244D3BC600BB249B /* IsolationSuccessViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsolationSuccessViewController.swift; sourceTree = ""; }; 5B7ABF27244D6BE100BB249B /* UnderSixteenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnderSixteenViewController.swift; sourceTree = ""; }; + 5B7B031D2490703500296DE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 5B8243602480DC2100705CB1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 5B900FC02485C4EE00CAA419 /* String+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Localization.swift"; sourceTree = ""; }; 5B92D662243011B30049877B /* CovidSafe-config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "CovidSafe-config.plist"; path = "Resources/PROD/CovidSafe-config.plist"; sourceTree = ""; }; 5B92D666243012330049877B /* CovidSafe-config.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "CovidSafe-config.plist"; path = "Resources/STG/CovidSafe-config.plist"; sourceTree = ""; }; 5B92D6D9243018040049877B /* COVIDSafe-staging.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "COVIDSafe-staging.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -352,9 +361,7 @@ 5DC7B8D2242B8D87008E1715 /* BluetraceUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetraceUtils.swift; sourceTree = ""; }; 5DD41D3723DCB03B00FD4AB0 /* COVIDSafe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = COVIDSafe.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5DD41D3A23DCB03B00FD4AB0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 5DD41D4123DCB03B00FD4AB0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 5DD41D4323DCB03D00FD4AB0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 5DD41D4623DCB03D00FD4AB0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 5DD41D4823DCB03D00FD4AB0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5DD41D4E23DCB05600FD4AB0 /* CentralController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CentralController.swift; sourceTree = ""; }; 5DD41D5223DD4CA400FD4AB0 /* PeripheralController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralController.swift; sourceTree = ""; }; @@ -369,9 +376,6 @@ 7FEC361423F16A1E00127AFB /* UIViewExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewExtension.swift; sourceTree = ""; }; 7FF75C212429FEE800C11FEA /* CountriesData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountriesData.swift; sourceTree = ""; }; 81B28CDCE1F29BA0F1D30CCE /* Pods-CovidSafe-staging.covid-production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CovidSafe-staging.covid-production.xcconfig"; path = "Target Support Files/Pods-CovidSafe-staging/Pods-CovidSafe-staging.covid-production.xcconfig"; sourceTree = ""; }; - A767D2B6242DF1B000DC9E2A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = ""; }; - A767D2B7242DF1B000DC9E2A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/NewFeedbackFlow.strings; sourceTree = ""; }; - A767D2D1242DF1B000DC9E2A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/NewFeedbackFlow.storyboard; sourceTree = ""; }; A767D2DA242DF1B000DC9E2A /* JMCTarget.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = JMCTarget.json; sourceTree = ""; }; A767D2E8242DF1B000DC9E2A /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; A767D2EB242DF1B000DC9E2A /* Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; @@ -402,7 +406,6 @@ B60F8BE3242659810007A641 /* UILabelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabelExtension.swift; sourceTree = ""; }; B615C5A623F8EB1700345969 /* UIProgressView + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIProgressView + Extension.swift"; sourceTree = ""; }; B615C5A823FA403400345969 /* UIViewController + Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController + Extension.swift"; sourceTree = ""; }; - B6932CE624260E2B003D1810 /* UploadData.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = UploadData.storyboard; sourceTree = ""; }; C5046D5B23EF18600046E96D /* OnboardingStep1ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStep1ViewController.swift; sourceTree = ""; }; C56CF43E23F18A15006B05B0 /* OnboardingStep4ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStep4ViewController.swift; sourceTree = ""; }; C585C83A23EEB99B0061B7C6 /* GradientButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientButton.swift; sourceTree = ""; }; @@ -487,6 +490,7 @@ 7F2F0BA123EFFF75006D7404 /* OnboardingStep2ViewController.swift */, C58D817623F169DB00345771 /* OnboardingStep2bViewController.swift */, C56CF43E23F18A15006B05B0 /* OnboardingStep4ViewController.swift */, + 5B110C0F248F275A00B68291 /* SelectCountryViewController.swift */, 5D8DD05923E2F08400E097EF /* ContactViewController.swift */, 5D8DD05B23E2F0A700E097EF /* LogViewController.swift */, 5D8DD05D23E2F0BA00E097EF /* InfoViewController.swift */, @@ -535,10 +539,12 @@ isa = PBXGroup; children = ( B605A7B02427429D008BA819 /* PlistHelper.swift */, + 5B900FC02485C4EE00CAA419 /* String+Localization.swift */, 0B1810112431EE610005D11F /* PhoneNumberParser.swift */, 596B189B24499591003E190F /* UploadHelper.swift */, 59898602245173C200966E61 /* URLHelper.swift */, 59F25D6E245BED80002A7ED8 /* Debug.storyboard */, + 5B51ED4F2485D658008CE722 /* UILocalization.swift */, ); name = Utils; sourceTree = ""; @@ -606,6 +612,7 @@ isa = PBXGroup; children = ( 5B8243612480DC2100705CB1 /* Localizable.strings */, + 5B51ED64248715DE008CE722 /* InfoPlist.strings */, ); name = Internationalization; sourceTree = ""; @@ -693,7 +700,6 @@ 30FADD6C23F520F5006C125F /* Utils */, 5DD41D7723DE141700FD4AB0 /* tracer.xcdatamodeld */, 5DD41D4023DCB03B00FD4AB0 /* Main.storyboard */, - 1B86118D24303E7D00EA4B6B /* Questions.storyboard */, D8EB201C23FBE216001C60EC /* help_center_article_style.css */, 5DD41D4323DCB03D00FD4AB0 /* Assets.xcassets */, 5DD41D4523DCB03D00FD4AB0 /* LaunchScreen.storyboard */, @@ -726,8 +732,6 @@ A767D2AF242DF1B000DC9E2A /* Resources */ = { isa = PBXGroup; children = ( - A767D2B0242DF1B000DC9E2A /* Feedback.strings */, - A767D2B2242DF1B000DC9E2A /* NewFeedbackFlow.strings */, A767D2D0242DF1B000DC9E2A /* NewFeedbackFlow.storyboard */, A767D2DA242DF1B000DC9E2A /* JMCTarget.json */, ); @@ -780,7 +784,7 @@ B6932CE8242627A9003D1810 /* Upload Data */ = { isa = PBXGroup; children = ( - B6932CE624260E2B003D1810 /* UploadData.storyboard */, + 5B51ED58248627A8008CE722 /* UploadData.storyboard */, 30E91BE823EFE514002D592A /* UploadDataVC.swift */, 5BD3EE8224330E1A0004A007 /* UploadDataStep2VC.swift */, 0B69E7E82430C22E00561DD9 /* UploadDataHomeViewController.swift */, @@ -897,30 +901,6 @@ knownRegions = ( en, Base, - de, - ja, - nb, - "en-GB", - is, - da, - et, - it, - sk, - sv, - cs, - ko, - hu, - pl, - "pt-BR", - ru, - fr, - fi, - nl, - pt, - "pt-PT", - ro, - zh, - es, ); mainGroup = 5DD41D2E23DCB03B00FD4AB0; productRefGroup = 5DD41D3823DCB03B00FD4AB0 /* Products */; @@ -939,23 +919,21 @@ buildActionMask = 2147483647; files = ( 5B92D6BA243018040049877B /* help_center_article_style.css in Resources */, - 5B92D6BB243018040049877B /* UploadData.storyboard in Resources */, + 5B51ED62248715DE008CE722 /* InfoPlist.strings in Resources */, + 5B51ED56248627A8008CE722 /* UploadData.storyboard in Resources */, 5B92D6BD243018040049877B /* JMCTarget.json in Resources */, 5B92D6BF243018040049877B /* NewFeedbackFlow.storyboard in Resources */, 59AF2EA92435801400ACCAF2 /* SFSRootCAG2.cer in Resources */, - 0BDE12302431DCE6003BC44C /* Questions.storyboard in Resources */, 59F25D6A245B917A002A7ED8 /* Spinner_home.json in Resources */, 5B82435F2480DC2100705CB1 /* Localizable.strings in Resources */, 5B92D6C7243018040049877B /* CovidSafe-config.plist in Resources */, 59AF2EA0243560FD00ACCAF2 /* AmazonRootCA1.cer in Resources */, - 5B92D6C8243018040049877B /* NewFeedbackFlow.strings in Resources */, 5961ABEE2474E464004040DF /* spinner_migrating_db.json in Resources */, 59AF2EAD2435801400ACCAF2 /* AmazonRootCA4.cer in Resources */, 59F25D6F245BED80002A7ED8 /* Debug.storyboard in Resources */, 5B92D6C9243018040049877B /* LaunchScreen.storyboard in Resources */, 59AF2EAF2435801400ACCAF2 /* AmazonRootCA2.cer in Resources */, 5B92D6CB243018040049877B /* Assets.xcassets in Resources */, - 5B92D6CC243018040049877B /* Feedback.strings in Resources */, 5B337AB0245AA26300537620 /* Spinner_upload.json in Resources */, 59AF2EAB2435801400ACCAF2 /* AmazonRootCA3.cer in Resources */, 5B92D6CF243018040049877B /* Main.storyboard in Resources */, @@ -967,21 +945,19 @@ buildActionMask = 2147483647; files = ( D8EB201D23FBE216001C60EC /* help_center_article_style.css in Resources */, - B6932CE724260E2B003D1810 /* UploadData.storyboard in Resources */, + 5B51ED55248627A8008CE722 /* UploadData.storyboard in Resources */, A767D313242DF1B000DC9E2A /* JMCTarget.json in Resources */, - 1B86118E24303E7D00EA4B6B /* Questions.storyboard in Resources */, 59AF2EA82435801400ACCAF2 /* SFSRootCAG2.cer in Resources */, A767D312242DF1B000DC9E2A /* NewFeedbackFlow.storyboard in Resources */, 59F25D69245B917A002A7ED8 /* Spinner_home.json in Resources */, 5B82435E2480DC2100705CB1 /* Localizable.strings in Resources */, 5B92D663243011B40049877B /* CovidSafe-config.plist in Resources */, 59AF2E9F243560FD00ACCAF2 /* AmazonRootCA1.cer in Resources */, - A767D30F242DF1B000DC9E2A /* NewFeedbackFlow.strings in Resources */, + 5B51ED61248715DE008CE722 /* InfoPlist.strings in Resources */, 59AF2EAC2435801400ACCAF2 /* AmazonRootCA4.cer in Resources */, 5DD41D4723DCB03D00FD4AB0 /* LaunchScreen.storyboard in Resources */, 59AF2EAE2435801400ACCAF2 /* AmazonRootCA2.cer in Resources */, 5DD41D4423DCB03D00FD4AB0 /* Assets.xcassets in Resources */, - A767D30E242DF1B000DC9E2A /* Feedback.strings in Resources */, 5B337AAF245AA26300537620 /* Spinner_upload.json in Resources */, 59AF2EAA2435801400ACCAF2 /* AmazonRootCA3.cer in Resources */, 5961ABED2474E464004040DF /* spinner_migrating_db.json in Resources */, @@ -1096,6 +1072,7 @@ 5B92D67E243018040049877B /* InfoViewController.swift in Sources */, 5B92D67F243018040049877B /* PogoInstructionsViewController.swift in Sources */, FBBBFCE82430A933002B174D /* OnboardingStep1aViewController.swift in Sources */, + 5B51ED512485DF9C008CE722 /* UILocalization.swift in Sources */, 594E77C3247387B1009B8B34 /* EncounterDB+migration.swift in Sources */, 590C99332432C1C400A5EC71 /* UploadDataHomeViewController.swift in Sources */, 59B7417124514126006E1EEA /* RegistrationConsentViewController.swift in Sources */, @@ -1110,6 +1087,7 @@ 5B92D686243018040049877B /* AppDelegate.swift in Sources */, 5B92D687243018040049877B /* PhoneNumberViewController.swift in Sources */, 5961ABEB2474E358004040DF /* MigrationViewController.swift in Sources */, + 5B110C11248F275B00B68291 /* SelectCountryViewController.swift in Sources */, 5B92D688243018040049877B /* BluetraceUtils.swift in Sources */, 5B92D689243018040049877B /* NewFeedbackFlowController.swift in Sources */, 5B92D68A243018040049877B /* Outcome.swift in Sources */, @@ -1177,6 +1155,7 @@ 59898604245173C200966E61 /* URLHelper.swift in Sources */, 590888B32431B9F2008C9B9F /* Question1ViewController.swift in Sources */, 590888B62431BA7C008C9B9F /* Question3ErrorViewController.swift in Sources */, + 5B900FC22485C4EE00CAA419 /* String+Localization.swift in Sources */, 59AF2E9D2435581600ACCAF2 /* CovidNetworking.swift in Sources */, 596B189D24499591003E190F /* UploadHelper.swift in Sources */, 590888AF2431B9E3008C9B9F /* UITextView + Extensions.swift in Sources */, @@ -1234,6 +1213,7 @@ 596B189924496D32003E190F /* Encounter+Util.swift in Sources */, 5961ABEA2474E358004040DF /* MigrationViewController.swift in Sources */, 30BE1CB523F15D47005DCE4F /* OTPViewController.swift in Sources */, + 5B900FC12485C4EE00CAA419 /* String+Localization.swift in Sources */, 5D8DD06123E319B300E097EF /* Encounter+CoreDataClass.swift in Sources */, 594E77BF24736B77009B8B34 /* EncounterDB.swift in Sources */, FB12C4C1242F0480007E893B /* RespondToAuthChallengeAPI.swift in Sources */, @@ -1260,6 +1240,7 @@ 5D5F83AD23F023F600770DEF /* EncounterMessageManager.swift in Sources */, 7FF75C222429FEE800C11FEA /* CountriesData.swift in Sources */, 0B55E1922430760600C9E798 /* UITextView + Extensions.swift in Sources */, + 5B110C10248F275B00B68291 /* SelectCountryViewController.swift in Sources */, A767D321242DF1B100DC9E2A /* AlertController.swift in Sources */, 5D5F83AD23F023F600770DEF /* EncounterMessageManager.swift in Sources */, FB12C4C3242F0FE9007E893B /* GetTempIdAPI.swift in Sources */, @@ -1289,6 +1270,7 @@ 7F36305F23F7F81400CC6E1D /* PushNotificationConstants.swift in Sources */, 59AF2E9C2435581600ACCAF2 /* CovidNetworking.swift in Sources */, 596B189C24499591003E190F /* UploadHelper.swift in Sources */, + 5B51ED502485D658008CE722 /* UILocalization.swift in Sources */, 1B86119724303F8500EA4B6B /* Question1ErrorViewController.swift in Sources */, B615C5A923FA403500345969 /* UIViewController + Extension.swift in Sources */, 1B86119324303F4A00EA4B6B /* Question2ViewController.swift in Sources */, @@ -1301,6 +1283,22 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + 5B51ED58248627A8008CE722 /* UploadData.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5B51ED6E248776CA008CE722 /* Base */, + ); + name = UploadData.storyboard; + sourceTree = ""; + }; + 5B51ED64248715DE008CE722 /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 5B51ED63248715DE008CE722 /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; 5B8243612480DC2100705CB1 /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -1312,7 +1310,7 @@ 5DD41D4023DCB03B00FD4AB0 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - 5DD41D4123DCB03B00FD4AB0 /* Base */, + 5B51ED6F248776CB008CE722 /* Base */, ); name = Main.storyboard; sourceTree = ""; @@ -1320,31 +1318,15 @@ 5DD41D4523DCB03D00FD4AB0 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 5DD41D4623DCB03D00FD4AB0 /* Base */, + 5B7B031D2490703500296DE0 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; - A767D2B0242DF1B000DC9E2A /* Feedback.strings */ = { - isa = PBXVariantGroup; - children = ( - A767D2B6242DF1B000DC9E2A /* en */, - ); - name = Feedback.strings; - sourceTree = ""; - }; - A767D2B2242DF1B000DC9E2A /* NewFeedbackFlow.strings */ = { - isa = PBXVariantGroup; - children = ( - A767D2B7242DF1B000DC9E2A /* en */, - ); - name = NewFeedbackFlow.strings; - sourceTree = ""; - }; A767D2D0242DF1B000DC9E2A /* NewFeedbackFlow.storyboard */ = { isa = PBXVariantGroup; children = ( - A767D2D1242DF1B000DC9E2A /* Base */, + 5B51ED6D248776CA008CE722 /* Base */, ); name = NewFeedbackFlow.storyboard; sourceTree = ""; @@ -1356,6 +1338,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -1421,7 +1404,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1429,7 +1412,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_NAME = COVIDSafe; @@ -1445,6 +1428,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -1504,7 +1488,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1512,7 +1496,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_NAME = COVIDSafe; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1532,7 +1516,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1540,7 +1524,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; @@ -1562,7 +1546,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1570,7 +1554,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; @@ -1592,7 +1576,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1600,7 +1584,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_MODULE_NAME = COVIDSafe; @@ -1622,7 +1606,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1630,7 +1614,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_MODULE_NAME = COVIDSafe; @@ -1648,6 +1632,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -1709,6 +1694,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; @@ -1768,7 +1754,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1776,7 +1762,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_NAME = COVIDSafe; @@ -1796,7 +1782,7 @@ CODE_SIGN_ENTITLEMENTS = "CovidSafe/Project Bluetrace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 31; + CURRENT_PROJECT_VERSION = 37; DEVELOPMENT_TEAM = 45792XH5L8; INFOPLIST_FILE = "$(SRCROOT)/CovidSafe/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 10.0; @@ -1804,7 +1790,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5; + MARKETING_VERSION = 1.6; PRODUCT_BUNDLE_IDENTIFIER = au.gov.health.covidsafe; PRODUCT_NAME = COVIDSafe; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/CovidSafe/API/PhoneValidationAPI.swift b/CovidSafe/API/PhoneValidationAPI.swift index b597fe7..6d0b376 100644 --- a/CovidSafe/API/PhoneValidationAPI.swift +++ b/CovidSafe/API/PhoneValidationAPI.swift @@ -16,7 +16,9 @@ class PhoneValidationAPI { guard let apiHost = PlistHelper.getvalueFromInfoPlist(withKey: "API_Host", plistName: "CovidSafe-config") else { return } + let params = [ + "country_code": "+\(regInfo.countryPhoneCode ?? "61")", "phone_number": regInfo.phoneNumber, "age": String(regInfo.age), "postcode": regInfo.postcode, @@ -45,6 +47,7 @@ struct RegistrationRequest { var age: Int var isMinor: Bool var phoneNumber: String + var countryPhoneCode: String? } struct AuthResponse: Decodable { diff --git a/CovidSafe/AppDelegate.swift b/CovidSafe/AppDelegate.swift index be46710..9720713 100644 --- a/CovidSafe/AppDelegate.swift +++ b/CovidSafe/AppDelegate.swift @@ -26,6 +26,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { UserDefaults.standard.set(true, forKey: "HasBeenLaunched") } + UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.covidSafeColor], for: .normal) + UINavigationBar.appearance().tintColor = UIColor.covidSafeColor + let hasUserConsent = true let hasUserCompletedOnboarding = UserDefaults.standard.bool(forKey: "turnedOnBluetooth") let bluetoothAuthorised = BluetraceManager.shared.isBluetoothAuthorized() @@ -98,13 +101,33 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if !UserDefaults.standard.bool(forKey: "sentBluetoothStatusNotif") { UserDefaults.standard.set(true, forKey: "sentBluetoothStatusNotif") self.triggerIntervalLocalPushNotifications(pnContent: PushNotificationConstants.btStatusPushNotifContents[btStatusMagicNumber], identifier: "bluetoothStatusNotifId") + return } } + switch state { + case .poweredOff, .unauthorized: + DLog("*** Setup reminders - BL OFF, UNAUTH check/set reminders") + self.checkAndScheduleReminderNotifications() + default: + // leave reminder notifications as they are, when an encounter occurs the notifications will be deferred + // or removed when app becomes active + DLog("*** Setup reminders - Default leave reminders") + } } } - fileprivate func cancelPreviouslyScheduledNotifications() { - UNUserNotificationCenter.current().removeAllPendingNotificationRequests() + fileprivate func getReminderNotificationsIdentifiers() -> [String] { + var identifiers: [String] = [] + for interval in intervals { + identifiers.append(getReminderNotificationIdentifier(interval: interval)) + } + return identifiers + } + + fileprivate func cancelScheduledReminderNotifications() { + DLog("*** Cancel reminders") + let identifiers = getReminderNotificationsIdentifiers() + UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers) } fileprivate func triggerIntervalLocalPushNotifications(pnContent: [String : String], identifier: String) { @@ -128,8 +151,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let intervals: [TimeInterval] = [TimeInterval(60 * 60 * 48)] #endif - fileprivate func scheduleReminderNotifications() { + fileprivate func getReminderNotificationIdentifier(interval: TimeInterval) -> String { + return "reminder-\(interval)" + } + + fileprivate func checkAndScheduleReminderNotifications() { + let identifiers = getReminderNotificationsIdentifiers() + DLog("*** Setup reminders - checking pending reminders") + // check all reminders are scheduled and pending + UNUserNotificationCenter.current().getPendingNotificationRequests { (notificationsRequest) in + var scheduledRemindersCount = 0 + for notification in notificationsRequest { + if identifiers.firstIndex(of: notification.identifier) != nil { + scheduledRemindersCount += 1 + } + } + // re-schedule reminders unless they are all pending + if scheduledRemindersCount != identifiers.count { + self.scheduleReminderNotifications() + } + } + } + fileprivate func scheduleReminderNotifications() { + DLog("*** Set reminders") let reminderContent = PushNotificationConstants.reminderPushNotifContents guard let title = reminderContent["contentTitle"], @@ -141,7 +186,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { for interval in intervals { let content = UNMutableNotificationContent() - + let identifier = getReminderNotificationIdentifier(interval: interval) #if DEBUG content.title = "\(title) \(interval / 60) min" #else @@ -152,14 +197,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let trigger = UNTimeIntervalNotificationTrigger(timeInterval: interval, repeats: false) - let request = UNNotificationRequest(identifier: "reminder-\(interval)", content: content, trigger: trigger) + let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) notificationCenter.add(request) } } @objc func deferReminderNotifications(_ notification: Notification) { - cancelPreviouslyScheduledNotifications() + // no need to cancel, if same ID used the notification is updated scheduleReminderNotifications() } @@ -168,13 +213,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate { startAccelerometerUpdates() clearOldDataInContext() + + // if Bluetooth is ON, remove reminders, leave otherwise. + if BluetraceManager.shared.isBluetoothOn() { + cancelScheduledReminderNotifications() + } } func applicationWillResignActive(_ application: UIApplication) { DLog("applicationWillResignActive") // Retry in case it failed on become active clearOldDataInContext() - scheduleReminderNotifications() + + // check if reminders pending and set if needed + checkAndScheduleReminderNotifications() } func applicationDidEnterBackground(_ application: UIApplication) { @@ -187,8 +239,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func applicationWillEnterForeground(_ application: UIApplication) { DLog("applicationWillEnterForeground") self.dismissBlackscreen() - - cancelPreviouslyScheduledNotifications() } func applicationWillTerminate(_ application: UIApplication) { diff --git a/CovidSafe/Base.lproj/Main.storyboard b/CovidSafe/Base.lproj/Main.storyboard index 94155eb..97d65b4 100644 --- a/CovidSafe/Base.lproj/Main.storyboard +++ b/CovidSafe/Base.lproj/Main.storyboard @@ -36,6 +36,9 @@ + + + @@ -232,6 +253,9 @@ Together we can help stop the spread and stay healthy. + + + @@ -288,7 +312,7 @@ Together we can help stop the spread and stay healthy. - @@ -840,6 +1016,9 @@ They will need to register using their own device and phone number so that COVID + + + @@ -1022,6 +1201,9 @@ They will need to register using their own device and phone number so that COVID + + + @@ -1108,16 +1290,16 @@ No further action is required. - + - + - + - + @@ -1125,17 +1307,23 @@ No further action is required. - @@ -1164,11 +1352,14 @@ No further action is required. @@ -1198,37 +1389,49 @@ No further action is required. - + - + - + + + + - + @@ -1244,21 +1447,24 @@ No further action is required. - + - + @@ -1288,29 +1494,44 @@ No further action is required. - + - + + - - + + + + + @@ -1370,16 +1591,16 @@ No further action is required. - + - + - + - + @@ -1393,6 +1614,9 @@ No further action is required. + + + @@ -1413,9 +1637,12 @@ No further action is required. - + + + + @@ -1447,7 +1674,7 @@ No further action is required. - + @@ -1465,6 +1692,9 @@ No further action is required. + + + @@ -1480,13 +1710,16 @@ No further action is required. @@ -1572,13 +1805,13 @@ No further action is required. - + - + - + @@ -1611,14 +1847,17 @@ No further action is required. @@ -1641,7 +1880,7 @@ No further action is required. - + @@ -1674,14 +1916,17 @@ No further action is required. @@ -1747,13 +1992,13 @@ No further action is required. - + - + - + @@ -1792,14 +2040,17 @@ No further action is required. @@ -1859,13 +2110,13 @@ No further action is required. - + - + - + - + @@ -2203,14 +2458,17 @@ and save lives. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Individuals who have tested positive to COVID-19 must self-isolate. This is to prevent the possible spread of the virus to other people. - -For more information, please *click here*. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - You are required to self-isolate until you receive the outcome of your test result. Self-isolation means staying at home or in your hotel room for 14 days. This is to prevent the possible spread of the virus to other people. - -For more information, please *click here*. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/CovidSafe/SelectCountryViewController.swift b/CovidSafe/SelectCountryViewController.swift new file mode 100644 index 0000000..143e3e6 --- /dev/null +++ b/CovidSafe/SelectCountryViewController.swift @@ -0,0 +1,213 @@ +// +// SelectCountryViewController.swift +// CovidSafe +// +// Copyright © 2020 Australian Government. All rights reserved. +// + +import UIKit +import FlagKit +import SafariServices + +struct Country { + var name: String! + var isoCode: String! + var phoneCode: String! + var flag: Flag? +} + +class SelectCountryViewController: UITableViewController, UISearchResultsUpdating { + + let searchController = UISearchController(searchResultsController: nil) + let AU_OPTIONS_KEY = "OptionsForAustralia" + + var countriesTableData: Dictionary = [:] + let countriesSortedByName = CountriesData.countries.sorted(by: { (country1, country2) -> Bool in + country1.name < country2.name + }) + var filteredCountriesTableData: [Country] = [] + var countrySelectionDelegate: CountrySelectionDelegate? + + var countriesSectionTitles: [String] = [] + var isSearchBarEmpty = true + var isFiltering: Bool { + return searchController.isActive && !isSearchBarEmpty + } + + override func viewDidLoad() { + super.viewDidLoad() + let label = UILabel() + label.text = "SelectCountryTitle".localizedString() + label.font = UIFont.preferredFont(forTextStyle: .headline) + self.navigationItem.titleView = label + + searchController.searchResultsUpdater = self + searchController.obscuresBackgroundDuringPresentation = false + definesPresentationContext = true + + navigationController?.navigationBar.isTranslucent = false + navigationController?.navigationBar.barTintColor = UIColor.white + //Set search bar + if #available(iOS 11.0, *) { + navigationItem.searchController = searchController + } else { + tableView.tableHeaderView = searchController.searchBar + searchController.hidesNavigationBarDuringPresentation = false + searchController.dimsBackgroundDuringPresentation = false + automaticallyAdjustsScrollViewInsets = false + } + + // Create the data source of the countries table + let norfolkIslandCountry = Country(name: "Country_AU2".localizedString(), isoCode: "AU2", phoneCode: "672", flag: Flag(countryCode: "AU")) + let australiaCountry = Country(name: "Country_AU".localizedString(), isoCode: "AU", phoneCode: "61", flag: Flag(countryCode: "AU")) + countriesTableData.updateValue([australiaCountry, norfolkIslandCountry], forKey: AU_OPTIONS_KEY) + countriesSectionTitles.append(" ") + + for country in countriesSortedByName { + let initial = String(country.name[country.name.startIndex]) + var sectionCountries: [Country] = countriesTableData[initial] ?? [] + if sectionCountries.count == 0 { + countriesSectionTitles.append(initial) + } + sectionCountries.append(country) + countriesTableData.updateValue(sectionCountries, forKey: initial) + } + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + //this is to show the search bar initially + if #available(iOS 11.0, *) { + navigationItem.hidesSearchBarWhenScrolling = false + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + if #available(iOS 11.0, *) { + if !UIAccessibility.isVoiceOverRunning { + navigationItem.hidesSearchBarWhenScrolling = true + } + } + if UIAccessibility.isVoiceOverRunning { + UIAccessibility.post(notification: .layoutChanged, argument: self.navigationItem.titleView ) + } + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + navigationController?.setNavigationBarHidden(true, animated: false) + } + + func updateSearchResults(for searchController: UISearchController) { + let searchBar = searchController.searchBar + let searchBarText = searchBar.text?.lowercased() ?? "" + if (searchBarText == "") { + isSearchBarEmpty = true + filteredCountriesTableData = [] + tableView.reloadData() + return + } + isSearchBarEmpty = false + filteredCountriesTableData = countriesSortedByName.filter({ (country) -> Bool in + let countryName = country.name.lowercased() + let searchCriteria = searchBarText.lowercased() + if countryName.contains(searchCriteria) { + return true + } + return false + }) + tableView.reloadData() + } + + override func sectionIndexTitles(for tableView: UITableView) -> [String]? { + if !isFiltering { + return countriesSectionTitles + } + return nil + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + var country: Country + if !isFiltering { + var sectionIndex = AU_OPTIONS_KEY + if indexPath.section > 0 { + sectionIndex = countriesSectionTitles[indexPath.section] + } + guard let sectionCountries = countriesTableData[sectionIndex] else { + return + } + country = sectionCountries[indexPath.row] + } else { + country = filteredCountriesTableData[indexPath.row] + } + countrySelectionDelegate?.setCountry(country: country) + navigationController?.setNavigationBarHidden(true, animated: false) + self.navigationController?.popViewController(animated: true) + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + if !isFiltering { + if section == 0 { + return "AustraliaSectionTitle".localizedString() + } + + return countriesSectionTitles[section] + } else { + return nil + } + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if !isFiltering { + var sectionIndex = AU_OPTIONS_KEY + if section > 0 { + sectionIndex = countriesSectionTitles[section] + } + return countriesTableData[sectionIndex]?.count ?? 0 + } else { + return filteredCountriesTableData.count + } + } + + override func numberOfSections(in tableView: UITableView) -> Int { + if !isFiltering { + return countriesSectionTitles.count + } else { + return 1 + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "CountryCell", for: indexPath) as! CountryCellViewCell + var country: Country + + if !isFiltering { + var sectionIndex = AU_OPTIONS_KEY + if indexPath.section > 0 { + sectionIndex = countriesSectionTitles[indexPath.section] + } + guard let sectionCountries = countriesTableData[sectionIndex] else { + return cell + } + + country = sectionCountries[indexPath.row] + } else { + country = filteredCountriesTableData[indexPath.row] + } + + cell.countryTitleLabel.text = country.name + cell.countryPhoneLabel.text = "+\(country.phoneCode ?? "")" + cell.countryFlagImageView.image = country.flag?.originalImage + + return cell + } + +} + +class CountryCellViewCell: UITableViewCell { + + @IBOutlet weak var countryTitleLabel: UILabel! + @IBOutlet weak var countryPhoneLabel: UILabel! + @IBOutlet weak var countryFlagImageView: UIImageView! +} diff --git a/CovidSafe/String+Localization.swift b/CovidSafe/String+Localization.swift new file mode 100644 index 0000000..dd68acc --- /dev/null +++ b/CovidSafe/String+Localization.swift @@ -0,0 +1,17 @@ +// +// String+Localization.swift +// CovidSafe +// +// Copyright © 2020 Australian Government. All rights reserved. +// +import Foundation + +extension String { + + func localizedString( comment: String = "") -> String { + if self == "" { + return "" + } + return NSLocalizedString(self, comment: comment) + } +} diff --git a/CovidSafe/UILocalization.swift b/CovidSafe/UILocalization.swift new file mode 100644 index 0000000..8565ae0 --- /dev/null +++ b/CovidSafe/UILocalization.swift @@ -0,0 +1,93 @@ +// +// UILocalization.swift +// CovidSafe +// +// Copyright © 2020 Australian Government. All rights reserved. +// +import UIKit +import Foundation + +extension UILabel { + + static var localizedKey:UInt8 = 0 + + @IBInspectable public var localizationKey: String? { + set { + objc_setAssociatedObject(self, &UILabel.localizedKey, newValue, .OBJC_ASSOCIATION_RETAIN) + } + get { + return objc_getAssociatedObject(self, &UILabel.localizedKey) as? String + } + } + + open override func awakeFromNib() { + super.awakeFromNib() + guard let localizationKey = self.localizationKey, localizationKey != localizationKey.localizedString() else { + return + } + self.text = localizationKey.localizedString() + } +} + +extension UITextView { + static var localizedKey:UInt8 = 0 + + @IBInspectable public var localizationKey: String? { + set { + objc_setAssociatedObject(self, &UITextView.localizedKey, newValue, .OBJC_ASSOCIATION_RETAIN) + } + get { + return objc_getAssociatedObject(self, &UITextView.localizedKey) as? String + } + } + + open override func awakeFromNib() { + super.awakeFromNib() + guard let localizationKey = self.localizationKey, localizationKey != localizationKey.localizedString() else { + return + } + self.text = localizationKey.localizedString() + } +} + +extension UITextField { + static var localizedKey:UInt8 = 0 + + @IBInspectable public var localizationKey: String? { + set { + objc_setAssociatedObject(self, &UITextView.localizedKey, newValue, .OBJC_ASSOCIATION_RETAIN) + } + get { + return objc_getAssociatedObject(self, &UITextView.localizedKey) as? String + } + } + + open override func awakeFromNib() { + super.awakeFromNib() + guard let localizationKey = self.localizationKey, localizationKey != localizationKey.localizedString() else { + return + } + self.placeholder = localizationKey.localizedString() + } +} + +extension UIButton { + static var localizedKey:UInt8 = 0 + + @IBInspectable public var localizationKey: String? { + set { + objc_setAssociatedObject(self, &UITextView.localizedKey, newValue, .OBJC_ASSOCIATION_RETAIN) + } + get { + return objc_getAssociatedObject(self, &UITextView.localizedKey) as? String + } + } + + open override func awakeFromNib() { + super.awakeFromNib() + guard let localizationKey = self.localizationKey, localizationKey != localizationKey.localizedString() else { + return + } + self.setTitle(localizationKey.localizedString(), for: .normal) + } +} diff --git a/CovidSafe/UploadDataStep2VC.swift b/CovidSafe/UploadDataStep2VC.swift index 92d825c..eae72f7 100644 --- a/CovidSafe/UploadDataStep2VC.swift +++ b/CovidSafe/UploadDataStep2VC.swift @@ -32,8 +32,8 @@ class UploadDataStep2VC: UIViewController, CodeInputViewDelegate { var currentKeyboardFrame: CGRect? var uploadAnimatedView: AnimationView? - let uploadFailErrMsg = NSLocalizedString("UploadFailed", comment: "Upload failed. Please try again later.") - let invalidPinErrMsg = NSLocalizedString("InvalidPIN", comment: "Invalid PIN, please ask health official to send another PIN.") + let uploadFailErrMsg = "UploadFailed".localizedString(comment: "Upload failed. Please try again later.") + let invalidPinErrMsg = "InvalidPIN".localizedString(comment: "Invalid PIN, please ask health official to send another PIN.") let verifyEnabledColor = UIColor.covidSafeButtonDarkerColor let verifyDisabledColor = UIColor(red: 219/255.0, green: 221/255.0, blue: 221.0/255.0, alpha: 1.0) @@ -165,10 +165,10 @@ class UploadDataStep2VC: UIViewController, CodeInputViewDelegate { } func displayUploadDataError() { - let errorAlert = UIAlertController(title: NSLocalizedString("UploadFailedErrorTitle", comment: "Upload Failed"), - message: NSLocalizedString("UploadFailedErrorMessage", comment: "Please try again later."), + let errorAlert = UIAlertController(title: "UploadFailedErrorTitle".localizedString(), + message: "UploadFailedErrorMessage".localizedString(), preferredStyle: .alert) - errorAlert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK"), style: .default, handler: nil)) + errorAlert.addAction(UIAlertAction(title: "OK".localizedString(), style: .default, handler: nil)) self.present(errorAlert, animated: true) } diff --git a/CovidSafe/en.lproj/InfoPlist.strings b/CovidSafe/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..6362727 --- /dev/null +++ b/CovidSafe/en.lproj/InfoPlist.strings @@ -0,0 +1,7 @@ +/* + InfoPlist.strings + CovidSafe + + Copyright © 2020 Australian Government. All rights reserved. +*/ +"BluetoothUsageDesc" = "COVIDSafe exchanges Bluetooth® signals with nearby phones running the same app. These signals contain an anonymised ID, which is encrypted and changes continually to ensure your privacy."; diff --git a/CovidSafe/en.lproj/Localizable.strings b/CovidSafe/en.lproj/Localizable.strings index 5acdc32..59cab37 100644 --- a/CovidSafe/en.lproj/Localizable.strings +++ b/CovidSafe/en.lproj/Localizable.strings @@ -7,6 +7,100 @@ //Global "OK" = "OK"; +// Initial Screen View Controller +"IntroLabel" = "Help stop the spread\nand save lives."; + +//Migration View Controller +"MigrationLabel" = "COVIDSafe update is in progress.\n\nPlease make sure your phone is not switched off until the update is complete."; + +// Onboarding Step 1 View Controller +"OS1_Title" = "Together we can stop the spread of COVID-19"; +"OS1_Content1" = "COVIDSafe has been developed by the Australian Government to help keep the community safe from the spread of coronavirus. + +COVIDSafe will securely note contact that you have with other users of the app. This will allow state or territory health officials to contact you, if you have been in close contact with someone who has tested positive to the virus. + +Together we can help stop the spread and stay healthy."; +"OS1_Button" = "I want to help"; + +// Onboarding Step 1b View Controller +"OS1b_Title" = "How COVIDSafe works"; +"OS1b_TopParagraph" = "Bluetooth® signals are used to determine when you're near another COVIDSafe user."; +"OS1b_Content" = "Every instance of close contact between you and other COVIDSafe users is noted to create close contact information. This information is encrypted and only stored in your phone. + +If you test positive to COVID-19 as a COVIDSafe user, a state or territory health official will contact you. They will assist with voluntary upload of your close contact information to a highly secure information storage system. + +State or territory health officials can also contact you if you came in close contact with another COVIDSafe user who tested positive. + +For more information please refer to the *Help Topics* page."; +"OS1b_Button" = "Next"; + +// Onboarding Step 1a View Controller +"OS1a_Title" = "Registration and privacy"; +"OS1a_Content" = "It is important that you read the COVIDSafe *privacy policy* before you register for COVIDSafe. + +If you are under 16 years of age, your parent/guardian must also read the *privacy policy*. + +Use of COVIDSafe is completely voluntary. You can install or delete the application at any time. If you delete COVIDsafe, *you may also ask for your information* to be deleted from the secure server. + +To register for COVIDSafe, you will need to enter a name, mobile number, age range and postcode. + +Information you submit when you register, and information about your use of COVIDSafe will be collected and stored on a highly secure server. + +COVIDSafe will not collect your location information.\n\nCOVIDSafe will note the time of contact and an anonymous ID code of other COVIDSafe users you come into contact with. + +Other COVIDSafe users you come into contact with will note an anonymous ID code and the time of contact with you on their device. + +If another user tests positive to COVID-19, they may upload their contact information and a state or territory health official may contact you for contact tracing purposes. + +Your registration details will only be used or disclosed for contact tracing and for the proper and lawful functioning of COVIDSafe. + +More information is available at the *Australian Government Department of Health website*. + +See the COVIDSafe *privacy policy* for further details about your rights about your information and how it will be handled and shared."; +"OS1a_Button" = "Next"; + +// Registration Consent View Controller +"RC_Title" = "Registration consent"; +"RC_Intro" = "I consent to the Australian Department of Health collecting:"; +"RC_Item1" = "My registration information to allow contact tracing by state or territory health officials."; +"RC_Item2" = "My contact information from other COVIDSafe users after they test positive for COVID-19."; +"RC_Closing" = "Select 'I agree' to confirm consent."; +"RC_Button" = "I agree"; + +// Personal Details Controller +"Done" = "Done"; +"Next" = "Next"; +"ValidationError" = "Validation error"; +"PostcodeValidationErrorMessage" = "Please enter a valid postcode"; +"PD_Title" = "Enter your details"; +"PD_Fullname" = "Full name"; +"PD_FullnameError" = "Please enter your full name."; +"PD_AgeRange" = "Age range (select)"; +"PD_AgeRangeError" = "Please select your age range."; +"PD_Postcode" = "Postcode in Australia"; +"PD_PostcodeError" = "Your Australian postcode number must contain 4 digits."; +"PD_Button" = "Continue"; + +// Under Sixteen View Controller +"US_Title" = "You need the consent of your parent/guardian to proceed"; +"US_Intro" = "I confirm my parent or guardian consents to the Australian Department of Health collecting:"; +"US_Item1" = "My registration information to allow contact tracing by state or territory health officials."; +"US_Item2" = "My contact information from other COVIDSafe users after they test positive for COVID-19."; +"US_Closing" = "Select 'I agree' to confirm consent."; +"US_Button" = "I agree"; + +// Phone Number View Controller +"EnterPhoneReVerify" = "Enter your mobile number to re-verify"; +"AusPhoneNumberButton" = "Use an Australian phone number"; +"EnterMobileNumber" = "Enter your mobile number"; +"SelectCountryRegion" = "Select country or region"; +"NorfolkExample" = "For Example: 351234"; +"AustralianPhoneValidationError" = "Australian mobile numbers contain a maximum of 10 digits."; +"NorfolkPhoneValidationError" = "Mobile numbers in Norfolk Island contain 5 to 6 digits."; +"PN_WillSendPIN" = "We'll send you a 6-digit pin to verify your mobile number."; +"PN_WarningContent" = "Trying to register on behalf of a friend or relative?\n\nThey will need to register using their own device and phone number so that COVIDSafe can work for them. "; +"PN_Button" = "Get PIN"; + // OTP View Controller "EnterPINSent" = "Enter the PIN sent to %@"; "PINWillExpire" = "Your PIN will expire in %@"; @@ -21,47 +115,101 @@ "PhoneVerificationErrorMessage" = "Please check your details and try again."; "PhoneNumberFormatErrorTitle" = "Wrong number format"; "PhoneNumberFormatErrorMessage" = "Please enter a mobile phone number."; +"OTP_Button" = "Verify"; +// Onboarding Step 2 View Controller (Permissions) +"OS2_Title" = "App settings"; +"OS2_Intro" = "COVIDSafe needs Bluetooth® enabled to work. By enabling Notifications, you get updates to remind you when COVIDSafe is not active.\n\nSelect 'Proceed' to enable:\n"; +"OS2_Item1" = "1. Bluetooth®"; +"OS2_Item2" = "2. Notifications\n\nCOVIDSafe does not send pairing requests."; +"OS2_Button" = "Proceed"; -//Phone Number View Controller -"EnterPhoneReVerify" = "Enter your mobile number to re-verify"; -"AusPhoneNumberButton" = "Use an Australian phone number"; - +// Onboarding Step 2b View Controller (Success) +"OS2b_Title" = "You’ve successfully registered"; +"OS2b_Item1" = "1. When you leave home, keep your phone with you and make sure COVIDSafe is active."; +"OS2b_Item2" = "2. Bluetooth® should be kept ON."; +"OS2b_Item3" = "3. COVIDSafe does not send pairing requests. Learn more."; +"OS2b_Item3Underline" = "Learn more"; +"OS2b_Button" = "Continue"; // Home View Controller +"HelpButton" = "Help"; "PairingRequestsInfo" = "COVIDSafe does not send pairing requests."; "PairingRequestsInfoUnderline" = "pairing requests"; "InformationUploaded" = "Your information was uploaded on %@"; "VersionNumber" = "Version number: %@ Build: %@"; "HomeHeaderNoAction" = "COVIDSafe is active.\nNo further action is required."; -"HomeHeaderPermissions" = "COVIDSafe is not active.\nCheck your permissions."; +"HomeHeaderPermissions" = "COVIDSafe is not active.\nCheck your settings."; +"ShareText" = "Join me in stopping the spread of COVID-19! Download COVIDSafe, an app from the Australian Government."; +"CheckPermissions" = "Check your settings"; +"CheckPermissionsMessage" = "COVIDSafe won't work without the right settings."; +"AllowBluetoothON" = "Access to Bluetooth®: ON"; +"AllowBluetoothOFF" = "Access to Bluetooth®: OFF"; +"AllowBluetoothOffDesc" = "Allow COVIDSafe to access Bluetooth®"; +"BluetoothON" = "Bluetooth®: ON"; +"BluetoothOFF" = "Bluetooth®: OFF"; +"BluetoothOffDesc" = "Turn on your phone's Bluetooth®. Select 'Allow New Connections' if displayed."; +"ShareCovidSafe" = "Share COVIDSafe"; +"ShareCovidSafeContent" = "Invite others to help. Together, we're stronger."; +"UploadData" = "Has a health official contacted you?"; +"UploadDataContent" = "You can only upload your information if you have tested positive."; +"GetCoronaVirusApp" = "Get the Coronavirus app"; +"GetCoronaVirusAppContent" = "Download the government app for the latest news and advice."; +"LatestNews" = "Latest news and updates"; +"LatestNewsContent" = "Head to aus.gov.au for the latest Coronavirus news."; +"HelpTopics" = "Help topics"; +"HelpTopicsContent" = "If you have issues or questions about the app."; "NotificationsEnabled" = "Notifications are enabled"; "NotificationsDisabled" = "Notifications are disabled"; -"NotificationsEnabledBlurb" = "You will receive a notification if COVIDSafe is not active. 
Change notification settings"; -"NotificationsDisabledBlurb" = "You will not receive a notification if COVIDSafe is not active. 
Change notification settings"; +"NotificationsEnabledBlurb" = "You will receive a notification if COVIDSafe is not active.\n\nChange notification settings"; +"NotificationsDisabledBlurb" = "You will not receive a notification if COVIDSafe is not active.\n\nChange notification settings"; "NotificationsBlurbLink" = "Change notification settings"; "ShareText" = "Join me in stopping the spread of COVID-19! Download COVIDSafe, an app from the Australian Government."; -//Successful registration (OnboardingStep2B) -"PointOne" = "1. When you leave home, keep your phone with you and make sure COVIDSafe is active."; -"PointTwo" = "2. Bluetooth® should be kept ON."; -"PointThree" = "3. COVIDSafe does not send pairing requests. Learn more."; -"PointThreeUnderline" = "Learn more"; - // Help Nav Controller "ReportAnIssue" = "Report an issue"; +"FoundIssueWithApp" = "Found an issue in the COVIDSafe app?"; +"IssueDescPlaceholder" = "Please describe the issue"; +"IssueFooter" = "We may contact you for further details about your feedback. Your email address won’t be used for any other purpose."; +"IssueThankYou" = "Thank you! We have received your feedback."; -// Personal Details View Controller -"Done" = "Done"; -"Next" = "Next"; -"ValidationError" = "Validation error"; -"PostcodeValidationErrorMessage" = "Please enter a valid postcode"; +// Upload Data Preface View Controller +"UDP_Title" = "Is a health official asking you to upload your information?"; +"UDP_Content" = "Only if you test positive to COVID-19 will a state or territory health official contact you to assist with voluntary upload of your information.\n\nOnce you press 'Yes' you'll need to provide consent to upload your information. "; +"UDP_NoButton" = "No"; +"UDP_YesButton" = "Yes"; -//Upload Data Step 2 View Controller +// Upload Data Home View Controller (Consent) +"UDC_Title" = "Upload Consent"; +"UDC_Content" = "Unless you consent, your close contact information will not be uploaded.\n\nIf you consent, your close contact information will be uploaded and shared with state or territory health officials for contact tracing purposes.\n\nRead the COVIDSafe *privacy policy* for further details.\n\nSelect 'I agree' to confirm consent."; +"UDC_Button" = "I agree"; + +// Upload Data Step 2 View Controller +"UD2_Title" = "Upload your information"; +"UD2_Intro" = "A state or territory health official will send a PIN to your device via text message. Enter it below to upload your information."; "UploadFailed" = "Upload failed. Please try again later."; "InvalidPIN" = "Invalid PIN, please ask the health official to send you another PIN."; "UploadFailedErrorTitle" = "Upload Failed"; "UploadFailedErrorMessage" = "Please try again later."; +"UploadingInfo" = "Your COVIDSafe information is currently being uploaded.\n\nPlease do not close the app."; +"UD2_Button" = "Upload my information"; + +// Upload Data Error View Controller +"UDE_Message" = "An error occurred while uploading your information, please try again."; +"UDE_TryAgain" = "Try again"; +"UDE_Cancel" = "Cancel"; + +// Upload Data Thank You View Controller +"UDTY_Title" = "Thank you for helping to stop the spread of COVID-19!"; +"UDTY_Content" = "You have successfully uploaded your information to the COVIDSafe highly secure storage system.\n\nState or territory health officials will notify other COVIDSafe users that have recorded instances of close contact with you. Your identity will remain anonymous to other users."; +"UDTY_Button" = "Continue"; + +// Feedback +"EmailPlaceholder" = "Localised Enter your email address (required)"; + +// Select Country View Controller +"SelectCountryTitle" = "Select country or region"; +"AustraliaSectionTitle" = "Options for Australia"; // Unused "WrongNumber" = "Wrong number?"; @@ -69,3 +217,255 @@ "NotAValidCode" = "Not a valid code"; "DataUploaded" = "Data uploaded"; "DataNotUploaded" = "Data not uploaded"; + +// Notifications +"PN_BluetoothStatusTitle" = "COVIDSafe is not active"; +"PN_BluetoothStatusBody" = "Make sure it’s active before you leave home and when in public places by enabling Bluetooth®."; +"PN_ReminderTitle" = "No encounters detected for 48 hours"; +"PN_ReminderBody" = "Open COVIDSafe to ensure it is running."; + +// *** Feedback localised strings *** + +"global_cancel_button_title" = "Cancel"; +"global_send_button_title" = "Send"; +"global_sending_indication_title" = "Sending"; +"global_success_indication_title" = "Success"; + +// Title for prompt that user sees when opening feeback. Prompt asks user if he/she would like to send new feedback. +"entryPrompt_alert_title" = "Feedback Box"; + +// Message for prompt that user sees when opening feeback. Prompt asks user if he/she would like to send new feedback. +"entryPrompt_alert_message" = "Hello mate, how would you like to proceed?"; + +// Title for button that launches new feedback flow. +"entryPrompt_newFeedback_button_title" = "New Feedback"; + +// Navigation Bar title shown during new feedback flow. +"newFeedbackFlow_navigationTitle" = "Report an issue"; + +// Messsage shown to user asking to confirm screenshot deletion. +"newFeedback_deleteScreenshotConfirmation_message" = "This screenshot will be deleted permanently."; + +// Delete screenshot action sheet action button title. +"newFeedback_deleteScreenshot_actionTitle" = "Delete Screenshot"; + +// Error message displayed to users when feedback fails to send. +"newFeedback_send_errorMessage" = "Error Sending Feedback"; + +//Error message displayed to users when feedback has empty description +"newFeedback_noMessage_errorMessage" = "Tell us something before sending."; +"newFeedback_invalidEmail_errorMessage" = "Please enter a valid email address!"; + + +// Countries +"Country_AU2" = "Norfolk Island"; +"Country_AF" = "Afghanistan"; +"Country_AL" = "Albania"; +"Country_DZ" = "Algeria"; +"Country_AD" = "Andorra"; +"Country_AO" = "Angola"; +"Country_AI" = "Anguilla"; +"Country_AG" = "Antigua and Barbuda"; +"Country_AR" = "Argentina"; +"Country_AM" = "Armenia"; +"Country_AW" = "Aruba"; +"Country_AU" = "Australia"; +"Country_AT" = "Austria"; +"Country_AZ" = "Azerbaijan"; +"Country_BS" = "Bahamas"; +"Country_BH" = "Bahrain"; +"Country_BD" = "Bangladesh"; +"Country_BB" = "Barbados"; +"Country_BY" = "Belarus"; +"Country_BE" = "Belgium"; +"Country_BZ" = "Belize"; +"Country_BJ" = "Benin"; +"Country_BM" = "Bermuda"; +"Country_BT" = "Bhutan"; +"Country_BO" = "Bolivia"; +"Country_BA" = "Bosnia and Herzegovina"; +"Country_BW" = "Botswana"; +"Country_BR" = "Brazil"; +"Country_BN" = "Brunei"; +"Country_BG" = "Bulgaria"; +"Country_BF" = "Burkina Faso"; +"Country_BI" = "Burundi"; +"Country_KH" = "Cambodia"; +"Country_CM" = "Cameroon"; +"Country_CA" = "Canada"; +"Country_CV" = "Cape Verde"; +"Country_KY" = "Cayman Islands"; +"Country_CF" = "Central African Republic"; +"Country_TD" = "Chad"; +"Country_CL" = "Chile"; +"Country_CN" = "China"; +"Country_CO" = "Colombia"; +"Country_KM" = "Comoros"; +"Country_CK" = "Cook Islands"; +"Country_CR" = "Costa Rica"; +"Country_HR" = "Croatia"; +"Country_CU" = "Cuba"; +"Country_CW" = "Curaçao"; +"Country_CY" = "Cyprus"; +"Country_CZ" = "Czech Republic"; +"Country_CD" = "Democratic Republic of the Congo"; +"Country_DK" = "Denmark"; +"Country_DJ" = "Djibouti"; +"Country_DM" = "Dominica"; +"Country_DO" = "Dominican Republic"; +"Country_TL" = "Timor-Leste"; +"Country_EC" = "Ecuador"; +"Country_EG" = "Egypt"; +"Country_SV" = "El Salvador"; +"Country_GQ" = "Equatorial Guinea"; +"Country_EE" = "Estonia"; +"Country_ET" = "Ethiopia"; +"Country_FO" = "Faroe Islands"; +"Country_FJ" = "Fiji"; +"Country_FI" = "Finland"; +"Country_FR" = "France"; +"Country_GF" = "French Guiana"; +"Country_GA" = "Gabon"; +"Country_GM" = "Gambia"; +"Country_GE" = "Georgia"; +"Country_DE" = "Germany"; +"Country_GH" = "Ghana"; +"Country_GI" = "Gibraltar"; +"Country_GR" = "Greece"; +"Country_GL" = "Greenland"; +"Country_GD" = "Grenada"; +"Country_GP" = "Guadeloupe"; +"Country_GU" = "Guam"; +"Country_GT" = "Guatemala"; +"Country_GN" = "Guinea"; +"Country_GW" = "Guinea-Bissau"; +"Country_GY" = "Guyana"; +"Country_HT" = "Haiti"; +"Country_HN" = "Honduras"; +"Country_HK" = "Hong Kong"; +"Country_HU" = "Hungary"; +"Country_IS" = "Iceland"; +"Country_IN" = "India"; +"Country_ID" = "Indonesia"; +"Country_IQ" = "Iraq"; +"Country_IE" = "Ireland"; +"Country_IL" = "Israel"; +"Country_IR" = "Iran"; +"Country_IT" = "Italy"; +"Country_CI" = "Ivory Coast"; +"Country_JM" = "Jamaica"; +"Country_JP" = "Japan"; +"Country_JO" = "Jordan"; +"Country_KZ" = "Kazakhstan"; +"Country_KE" = "Kenya"; +"Country_KI" = "Kiribati"; +"Country_KW" = "Kuwait"; +"Country_KG" = "Kyrgyzstan"; +"Country_LA" = "Laos"; +"Country_LV" = "Latvia"; +"Country_LB" = "Lebanon"; +"Country_LS" = "Lesotho"; +"Country_LR" = "Liberia"; +"Country_LY" = "Libya"; +"Country_LI" = "Liechtenstein"; +"Country_LT" = "Lithuania"; +"Country_LU" = "Luxembourg"; +"Country_MO" = "Macau"; +"Country_MK" = "Former Yugoslav Republic of Macedonia"; +"Country_MG" = "Madagascar"; +"Country_MW" = "Malawi"; +"Country_MY" = "Malaysia"; +"Country_MV" = "Maldives"; +"Country_ML" = "Mali"; +"Country_MT" = "Malta"; +"Country_MQ" = "Martinique"; +"Country_MR" = "Mauritania"; +"Country_MU" = "Mauritius"; +"Country_MX" = "Mexico"; +"Country_MD" = "Moldova"; +"Country_MC" = "Monaco"; +"Country_MO" = "Mongolia"; +"Country_ME" = "Montenegro"; +"Country_MS" = "Montserrat"; +"Country_MA" = "Morocco"; +"Country_MZ" = "Mozambique"; +"Country_MM" = "Myanmar"; +"Country_NA" = "Namibia"; +"Country_NP" = "Nepal"; +"Country_NL" = "Netherlands"; +"Country_AN" = "Netherlands Antilles"; +"Country_NC" = "New Caledonia"; +"Country_NZ" = "New Zealand"; +"Country_NI" = "Nicaragua"; +"Country_NE" = "Niger"; +"Country_NG" = "Nigeria"; +"Country_NO" = "Norway"; +"Country_OM" = "Oman"; +"Country_PK" = "Pakistan"; +"Country_PW" = "Palau"; +"Country_PS" = "Palestinian Territories"; +"Country_PA" = "Panama"; +"Country_PG" = "Papua New Guinea"; +"Country_PY" = "Paraguay"; +"Country_PE" = "Peru"; +"Country_PH" = "Philippines"; +"Country_PL" = "Poland"; +"Country_PT" = "Portugal"; +"Country_PR" = "Puerto Rico"; +"Country_QA" = "Qatar"; +"Country_CG" = "Republic of the Congo"; +"Country_RE" = "Reunion Island"; +"Country_RO" = "Romania"; +"Country_RU" = "Russia"; +"Country_RW" = "Rwanda"; +"Country_KN" = "Saint Kitts and Nevis"; +"Country_LC" = "Saint Lucia"; +"Country_VC" = "Saint Vincent and the Grenadines"; +"Country_WS" = "Samoa"; +"Country_ST" = "Sao Tome and Principe"; +"Country_SA" = "Saudi Arabia"; +"Country_SN" = "Senegal"; +"Country_RS" = "Serbia"; +"Country_SC" = "Seychelles"; +"Country_SL" = "Sierra Leone"; +"Country_SG" = "Singapore"; +"Country_SK" = "Slovakia"; +"Country_SI" = "Slovenia"; +"Country_SB" = "Solomon Islands"; +"Country_SO" = "Somalia"; +"Country_ZA" = "South Africa"; +"Country_KR" = "South Korea"; +"Country_SS" = "South Sudan"; +"Country_ES" = "Spain"; +"Country_LK" = "Sri Lanka"; +"Country_SR" = "Suriname"; +"Country_SD" = "Sudan"; +"Country_SZ" = "Swaziland"; +"Country_SE" = "Sweden"; +"Country_CH" = "Switzerland"; +"Country_TW" = "Taiwan"; +"Country_TJ" = "Tajikistan"; +"Country_TZ" = "Tanzania"; +"Country_TH" = "Thailand"; +"Country_TG" = "Togo"; +"Country_TO" = "Tonga"; +"Country_TT" = "Trinidad and Tobago"; +"Country_TN" = "Tunisia"; +"Country_TR" = "Turkey"; +"Country_TM" = "Turkmenistan"; +"Country_TC" = "Turks and Caicos Islands"; +"Country_UG" = "Uganda"; +"Country_UA" = "Ukraine"; +"Country_AE" = "United Arab Emirates"; +"Country_GB" = "United Kingdom"; +"Country_US" = "United States"; +"Country_UY" = "Uruguay"; +"Country_UZ" = "Uzbekistan"; +"Country_VU" = "Vanuatu"; +"Country_VE" = "Venezuela"; +"Country_VN" = "Vietnam"; +"Country_VG" = "Virgin Islands, British"; +"Country_VI" = "Virgin Islands, US"; +"Country_YE" = "Yemen"; +"Country_ZM" = "Zambia"; +"Country_ZW" = "Zimbabwe"; diff --git a/Podfile b/Podfile index f68d05e..fbfd89d 100644 --- a/Podfile +++ b/Podfile @@ -15,6 +15,7 @@ target 'CovidSafe' do pod 'Alamofire' pod 'KeychainSwift' pod 'lottie-ios' + pod 'FlagKit' end @@ -26,4 +27,5 @@ target 'CovidSafe-staging' do pod 'Alamofire' pod 'KeychainSwift' pod 'lottie-ios' + pod 'FlagKit' end diff --git a/Podfile.lock b/Podfile.lock index 0c42236..f05d944 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,24 +1,28 @@ PODS: - Alamofire (5.0.5) + - FlagKit (2.2) - KeychainSwift (19.0.0) - lottie-ios (3.1.6) DEPENDENCIES: - Alamofire + - FlagKit - KeychainSwift - lottie-ios SPEC REPOS: https://github.com/CocoaPods/Specs.git: - Alamofire + - FlagKit - KeychainSwift - lottie-ios SPEC CHECKSUMS: Alamofire: df2f8f826963b08b9a870791ad48e07a10090b2e + FlagKit: eca7dc89064b0c986302ba9acefad1bf80a435b1 KeychainSwift: a06190cf933ad46b1e0abc3d77d29c06331715c7 lottie-ios: 85ce835dd8c53e02509f20729fc7d6a4e6645a0a -PODFILE CHECKSUM: 267f7fcda5f8a86683b76b362dfc6c6703e3033f +PODFILE CHECKSUM: 5da6b902184340eac7df8e3e031d4faa43a3a7d2 COCOAPODS: 1.9.1 diff --git a/security.txt b/security.txt index 8056377..10e754e 100644 --- a/security.txt +++ b/security.txt @@ -1,17 +1,20 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 -Contact: mailto:support@covidsafe.gov.au +Contact: mailto:security@covidsafe.gov.au Canonical: https://www.covidsafe.gov.au/.well-known/security.txt Encryption: https://www.covidsafe.gov.au/.well-known/pgp-key.txt -----BEGIN PGP SIGNATURE----- -iQFNBAEBCAA3FiEEbUgetBuPAas8w7zHDyQUNNekxBkFAl6xF6AZHHN1cHBvcnRA -Y292aWRzYWZlLmdvdi5hdQAKCRAPJBQ016TEGd+bCACLrYjCbKRsTsQQyZVVtGxj -wYKW2AWclnKZWX/sxnTexg6D1tlGbZbB0OJpw0gJ0NpMoOLFd0kRZXOzv8RocIdx -xd90Nwwl3NQ2ygGCDXR0Y7uRKX/P/Y1xO7XkyiYXAqVq3YWvI9M04pY/TCRvRZ/1 -qBs/WDHv/6eRh2qNy/WGXD66CmTLHBcXilTeihcTZ/27Mny5SPthdfy8odQnhUja -NfFxDm+8gQuFKUUQmr9rd8FEMPSl6BWf/kQtn0YmTeZRzD01uT1ydeHkyPSgn+nq -k9us35AlkI7aZNfNkFVWJ2v5ZVAdTHDh3pgBRZETwVg1of5DEXhc5XJV6mLsu9bM -=tik2 +iQHOBAEBCAA4FiEEUWgkqhSOHRHwGue2IZjqt5flXH4FAl7Hkw0aHHNlY3VyaXR5 +QGNvdmlkc2FmZS5nb3YuYXUACgkQIZjqt5flXH4KfQv/ZagXzgn9HspSTupO7zQQ +t7lpZsNWKJsXddUD3+JQQ8b1uB9kmHhiydIXervEc1yGti6YYZxKybehLdvv7HjV +Cps9kn3cns9ex3s+KEMMFrU7MykvZ2x+fvCoGfgzWm1UJElxn/cSbOnt38VxmSjC +wkmh+DGa1z9OB6ZMuivO2XBx+Y0GV5tsoxWKRtXMruQ41bTHZvIJ9lJctYTv2xEK +hYlHmrzkZjLM/sTwGKWj+ARCn1IA0Zp8uxkoBi3/++NonKAlQpSZ4Rk6B780H8GM +5lCZVLIRfH1VJzPr7+eSSBF8p0coEapyO7bk/ioBIQB5v4xfvpJRBEc+eI7IZeDa +TcO/TVZw7Vut89flR+34g9PCSFDCJgv5zR8vE5mB5m/vlfJ7XI99XMwvFNWgpcyL +72tFv74uH6tUPZOlbHGZTnBsQLkuj4fwUYaUPcR9TzeMlBHoe21bQ6OeDO02rIy4 +09bWSTMGe33LvTz2UMuEkZcsNT8vc7J+597GSxgDWoR6 +=6MOG -----END PGP SIGNATURE-----