From b827cf3ccef72a3d38c6fc37466a99868823540f Mon Sep 17 00:00:00 2001 From: covidsafe-support <64945427+covidsafe-support@users.noreply.github.com> Date: Fri, 8 May 2020 15:23:03 +1000 Subject: [PATCH] COVIDSafe code from version 1.0.16 --- LICENSE.md | 20 + README.md | 22 + app/.gitignore | 1 + app/build.gradle | 217 + .../2.json | 114 + .../2.json | 114 + .../2.json | 114 + app/src/debug/AndroidManifest.xml | 15 + .../debug/res/values/mp_feedback_config.xml | 9 + app/src/main/AndroidManifest.xml | 98 + app/src/main/assets/loading_upload.json | 4650 ++++++++++++++ app/src/main/assets/spinner_home.json | 5500 +++++++++++++++++ .../assets/spinner_home_upload_complete.json | 1 + app/src/main/ic_launcher-playstore.png | Bin 0 -> 40809 bytes .../gov/health/covidsafe/HasBlockingState.kt | 5 + .../au/gov/health/covidsafe/HomeActivity.kt | 15 + .../au/gov/health/covidsafe/PeekActivity.kt | 147 + .../au/gov/health/covidsafe/PlotActivity.kt | 231 + .../au/gov/health/covidsafe/Preference.kt | 162 + .../gov/health/covidsafe/RecordListAdapter.kt | 170 + .../covidsafe/SelfIsolationDoneActivity.kt | 35 + .../au/gov/health/covidsafe/SplashActivity.kt | 82 + .../java/au/gov/health/covidsafe/TracerApp.kt | 48 + .../java/au/gov/health/covidsafe/Utils.kt | 247 + .../gov/health/covidsafe/WebViewActivity.kt | 35 + .../covidsafe/bluetooth/BLEAdvertiser.kt | 128 + .../health/covidsafe/bluetooth/BLEScanner.kt | 67 + .../health/covidsafe/bluetooth/gatt/GATT.kt | 65 + .../covidsafe/bluetooth/gatt/GattServer.kt | 286 + .../covidsafe/bluetooth/gatt/GattService.kt | 34 + .../covidsafe/boot/StartOnBootReceiver.kt | 25 + .../extensions/NavigationExtensions.kt | 8 + .../covidsafe/extensions/NetworkExtensions.kt | 13 + .../extensions/PermissionExtensions.kt | 137 + .../covidsafe/extensions/ViewExtensions.kt | 30 + .../covidsafe/factory/NetworkFactory.kt | 43 + .../gov/health/covidsafe/interactor/Either.kt | 14 + .../health/covidsafe/interactor/UseCase.kt | 76 + .../interactor/usecase/GetOnboardingOtp.kt | 60 + .../interactor/usecase/GetUploadOtp.kt | 34 + ...ageAndPerformScanWithExponentialBackOff.kt | 69 + .../interactor/usecase/UploadData.kt | 86 + .../health/covidsafe/logging/CentralLog.kt | 85 + .../request/AuthChallengeRequest.kt | 6 + .../networking/request/OTPChallengeRequest.kt | 10 + .../response/AuthChallengeResponse.kt | 6 + .../response/BroadcastMessageResponse.kt | 6 + .../response/InitiateUploadResponse.kt | 9 + .../response/OTPChallengeResponse.kt | 6 + .../networking/response/UploadOTPResponse.kt | 6 + .../covidsafe/networking/service/AwsClient.kt | 33 + .../notifications/NotificationTemplates.kt | 114 + .../receivers/PrivacyCleanerReceiver.kt | 64 + .../covidsafe/receivers/UpgradeReceiver.kt | 23 + .../health/covidsafe/scheduler/Scheduler.kt | 53 + .../services/BluetoothMonitoringService.kt | 668 ++ .../covidsafe/services/CommandHandler.kt | 55 + .../services/SensorMonitoringService.kt | 96 + .../au/gov/health/covidsafe/status/Status.kt | 9 + .../status/persistence/StatusRecord.kt | 20 + .../status/persistence/StatusRecordDao.kt | 32 + .../status/persistence/StatusRecordStorage.kt | 22 + .../covidsafe/streetpass/BlacklistEntry.kt | 3 + .../streetpass/ConnectablePeripheral.kt | 40 + .../health/covidsafe/streetpass/StreetPass.kt | 5 + .../covidsafe/streetpass/StreetPassScanner.kt | 122 + .../covidsafe/streetpass/StreetPassServer.kt | 32 + .../covidsafe/streetpass/StreetPassWorker.kt | 721 +++ .../gov/health/covidsafe/streetpass/Work.kt | 71 + .../persistence/StreetPassRecord.kt | 45 + .../persistence/StreetPassRecordDao.kt | 31 + .../persistence/StreetPassRecordDatabase.kt | 76 + .../persistence/StreetPassRecordRepository.kt | 8 + .../persistence/StreetPassRecordStorage.kt | 29 + .../streetpass/view/RecordViewModel.kt | 23 + .../view/StreetPassRecordViewModel.kt | 16 + .../gov/health/covidsafe/ui/BaseFragment.kt | 34 + .../health/covidsafe/ui/PagerChildFragment.kt | 63 + .../gov/health/covidsafe/ui/PagerContainer.kt | 13 + .../health/covidsafe/ui/home/HelpFragment.kt | 79 + .../health/covidsafe/ui/home/HomeFragment.kt | 332 + .../health/covidsafe/ui/home/HomePresenter.kt | 10 + .../ui/home/view/ExternalLinkCard.kt | 34 + .../ui/home/view/PermissionStatusCard.kt | 37 + .../ui/onboarding/OnboardingActivity.kt | 104 + .../dataprivacy/DataPrivacyFragment.kt | 39 + .../enternumber/EnterNumberFragment.kt | 144 + .../enternumber/EnterNumberPresenter.kt | 91 + .../fragment/enterpin/EnterPinFragment.kt | 191 + .../fragment/enterpin/EnterPinPresenter.kt | 112 + .../fragment/howitworks/HowItWorksFragment.kt | 39 + .../introduction/IntroductionFragment.kt | 32 + .../fragment/permission/PermissionFragment.kt | 121 + .../PermissionSuccessFragment.kt | 41 + .../personal/PersonalDetailsFragment.kt | 182 + .../personal/PersonalDetailsPresenter.kt | 96 + .../RegistrationContentFragment.kt | 44 + .../undersixteen/UnderSixteenFragment.kt | 51 + .../ui/upload/UploadContainerFragment.kt | 107 + .../covidsafe/ui/upload/model/DebugData.kt | 5 + .../covidsafe/ui/upload/model/ExportData.kt | 6 + .../presentation/UploadFinishedFragment.kt | 32 + .../presentation/UploadInitialFragment.kt | 39 + .../presentation/UploadStepFourFragment.kt | 59 + .../presentation/VerifyUploadPinFragment.kt | 136 + .../presentation/VerifyUploadPinPresenter.kt | 74 + .../health/covidsafe/ui/view/PinInputView.kt | 76 + .../covidsafe/ui/view/SegmentedProgressBar.kt | 53 + .../au/gov/health/covidsafe/ui/view/UlView.kt | 30 + .../covidsafe/ui/view/UploadingDialog.kt | 24 + .../covidsafe/ui/view/UploadingErrorDialog.kt | 32 + app/src/main/res/anim/slide_in_left.xml | 7 + app/src/main/res/anim/slide_in_right.xml | 7 + app/src/main/res/anim/slide_out_left.xml | 7 + app/src/main/res/anim/slide_out_right.xml | 7 + .../res/color/default_button_text_color.xml | 5 + app/src/main/res/color/progress_segment.xml | 6 + .../ic_notification_setting.xml | 13 + .../australian_government_stacked_white.png | Bin 0 -> 35097 bytes .../main/res/drawable-hdpi/ic_home_news.png | Bin 0 -> 5102 bytes .../drawable-hdpi/ic_notification_icon.png | Bin 0 -> 923 bytes .../drawable-hdpi/ic_notification_setting.png | Bin 0 -> 450 bytes .../drawable-hdpi/ic_notification_warning.png | Bin 0 -> 567 bytes .../res/drawable-hdpi/small_green_tick.png | Bin 0 -> 910 bytes .../res/drawable-hdpi/small_red_cross.png | Bin 0 -> 838 bytes .../australian_government_stacked_white.png | Bin 0 -> 11537 bytes .../main/res/drawable-mdpi/ic_home_news.png | Bin 0 -> 1645 bytes .../drawable-mdpi/ic_notification_icon.png | Bin 0 -> 664 bytes .../drawable-mdpi/ic_notification_setting.png | Bin 0 -> 331 bytes .../drawable-mdpi/ic_notification_warning.png | Bin 0 -> 444 bytes .../res/drawable-mdpi/small_green_tick.png | Bin 0 -> 654 bytes .../res/drawable-mdpi/small_red_cross.png | Bin 0 -> 564 bytes .../australian_government_stacked_white.png | Bin 0 -> 65707 bytes .../main/res/drawable-xhdpi/ic_home_news.png | Bin 0 -> 10124 bytes .../drawable-xhdpi/ic_notification_icon.png | Bin 0 -> 1251 bytes .../ic_notification_setting.png | Bin 0 -> 598 bytes .../ic_notification_warning.png | Bin 0 -> 812 bytes .../res/drawable-xhdpi/small_green_tick.png | Bin 0 -> 1218 bytes .../res/drawable-xhdpi/small_red_cross.png | Bin 0 -> 1089 bytes .../australian_government_stacked_white.png | Bin 0 -> 89307 bytes .../main/res/drawable-xxhdpi/ic_home_news.png | Bin 0 -> 16353 bytes .../drawable-xxhdpi/ic_notification_icon.png | Bin 0 -> 1773 bytes .../ic_notification_setting.png | Bin 0 -> 873 bytes .../ic_notification_warning.png | Bin 0 -> 1104 bytes .../res/drawable-xxhdpi/small_green_tick.png | Bin 0 -> 1670 bytes .../res/drawable-xxhdpi/small_red_cross.png | Bin 0 -> 1561 bytes .../drawable-xxxhdpi/ic_notification_icon.png | Bin 0 -> 2277 bytes .../ic_notification_warning.png | Bin 0 -> 1466 bytes .../drawable/background_circular_black.xml | 5 + .../background_circular_dark_cerulean_1.xml | 5 + .../background_circular_dark_cerulean_4.xml | 5 + .../drawable/background_circular_green.xml | 5 + .../res/drawable/background_light_green.xml | 9 + .../res/drawable/default_button_selector.xml | 5 + .../drawable/edit_text_black_background.xml | 8 + .../drawable/edit_text_green_background.xml | 8 + .../res/drawable/edittext_modified_states.xml | 14 + .../res/drawable/green_button_background.xml | 6 + .../res/drawable/grey_button_background.xml | 6 + .../main/res/drawable/ic_arrow_drop_down.xml | 10 + .../drawable/ic_arrow_forward_black_24dp.xml | 9 + app/src/main/res/drawable/ic_check.xml | 17 + .../main/res/drawable/ic_chevron_right.xml | 9 + app/src/main/res/drawable/ic_close.xml | 9 + .../res/drawable/ic_delete_black_24dp.xml | 9 + .../main/res/drawable/ic_doctor_circle.xml | 108 + app/src/main/res/drawable/ic_ellipse.xml | 9 + .../res/drawable/ic_help_outline_black.xml | 30 + .../res/drawable/ic_help_outline_white.xml | 30 + .../main/res/drawable/ic_help_stop_covid.xml | 100 + app/src/main/res/drawable/ic_home_logo.xml | 33 + app/src/main/res/drawable/ic_home_share.xml | 41 + .../main/res/drawable/ic_home_unprotected.xml | 72 + app/src/main/res/drawable/ic_how_it_works.xml | 341 + .../ic_illustration_upload_inital_state.xml | 144 + .../ic_illustration_upload_step_4.xml | 130 + app/src/main/res/drawable/ic_info.xml | 23 + .../main/res/drawable/ic_intro_picture.xml | 535 ++ .../res/drawable/ic_launcher_background.xml | 16 + .../res/drawable/ic_launcher_foreground.xml | 24 + .../main/res/drawable/ic_launcher_round.xml | 85 + .../res/drawable/ic_logo_home_inactive.xml | 18 + .../res/drawable/ic_logo_home_uploaded.xml | 18 + app/src/main/res/drawable/ic_permission.xml | 126 + .../res/drawable/ic_permission_success.xml | 76 + .../main/res/drawable/ic_personal_details.xml | 165 + .../res/drawable/ic_phone_checked_circle.xml | 59 + .../res/drawable/ic_play_arrow_black_24dp.xml | 9 + app/src/main/res/drawable/ic_privacy.xml | 110 + app/src/main/res/drawable/ic_smartphone.xml | 20 + app/src/main/res/drawable/ic_smile.xml | 34 + .../res/drawable/ic_splash_screen_logo.xml | 19 + .../res/drawable/ic_splash_screen_title.xml | 33 + .../main/res/drawable/ic_stop_black_24dp.xml | 9 + .../main/res/drawable/ic_under_sixteen.xml | 97 + .../drawable/ic_unfold_less_black_24dp.xml | 9 + .../drawable/ic_unfold_more_black_24dp.xml | 9 + app/src/main/res/drawable/ic_up.xml | 9 + app/src/main/res/drawable/ic_upload_error.xml | 23 + .../main/res/drawable/ic_upload_failed.xml | 9 + app/src/main/res/drawable/ic_upload_icon.xml | 27 + app/src/main/res/drawable/icon_checkbox.xml | 27 + .../drawable/illustration_data_uploaded.xml | 17 + .../drawable/illustration_upload_finished.xml | 530 ++ .../drawable/outline_button_background.xml | 4 + .../phone_number_invalid_background.xml | 8 + .../main/res/drawable/progress_segment.xml | 4 + .../res/drawable/splash_screen_white_wave.xml | 15 + app/src/main/res/font/font_roboto_regular.xml | 16 + app/src/main/res/font/roboto_medium.ttf | Bin 0 -> 171656 bytes app/src/main/res/font/roboto_regular.ttf | 0 app/src/main/res/layout/activity_home.xml | 9 + .../main/res/layout/activity_onboarding.xml | 74 + app/src/main/res/layout/activity_plot.xml | 12 + .../res/layout/activity_self_isolation.xml | 72 + app/src/main/res/layout/activity_splash.xml | 54 + app/src/main/res/layout/database_peek.xml | 101 + .../res/layout/dialog_error_uploading.xml | 64 + app/src/main/res/layout/dialog_uploading.xml | 38 + .../main/res/layout/fragment_data_privacy.xml | 49 + .../main/res/layout/fragment_enter_number.xml | 163 + .../main/res/layout/fragment_enter_pin.xml | 118 + app/src/main/res/layout/fragment_help.xml | 70 + app/src/main/res/layout/fragment_home.xml | 80 + .../layout/fragment_home_external_links.xml | 118 + .../fragment_home_setup_complete_header.xml | 83 + ...fragment_home_setup_incomplete_content.xml | 112 + .../layout/fragment_home_uploaded_card.xml | 6 + .../main/res/layout/fragment_how_it_works.xml | 48 + app/src/main/res/layout/fragment_intro.xml | 51 + .../main/res/layout/fragment_permission.xml | 47 + .../layout/fragment_permission_success.xml | 51 + .../res/layout/fragment_personal_details.xml | 188 + .../layout/fragment_registration_consent.xml | 73 + .../res/layout/fragment_under_sixteen.xml | 73 + .../res/layout/fragment_upload_finished.xml | 58 + .../res/layout/fragment_upload_initial.xml | 46 + .../res/layout/fragment_upload_master.xml | 75 + .../res/layout/fragment_upload_page_4.xml | 48 + .../res/layout/fragment_verify_upload_pin.xml | 74 + .../main/res/layout/recycler_view_item.xml | 170 + .../layout/view_card_external_link_card.xml | 63 + .../res/layout/view_card_permission_card.xml | 42 + app/src/main/res/layout/view_pin.xml | 120 + app/src/main/res/layout/view_ul.xml | 23 + app/src/main/res/layout/webview.xml | 14 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3080 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5337 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1965 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3247 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4465 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7786 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7129 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 12502 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10153 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 17898 bytes app/src/main/res/navigation/nav_home.xml | 47 + .../main/res/navigation/nav_onboarding.xml | 124 + app/src/main/res/navigation/nav_register.xml | 58 + app/src/main/res/navigation/nav_upload.xml | 64 + app/src/main/res/values-v24/themes.xml | 16 + app/src/main/res/values/attrs.xml | 25 + app/src/main/res/values/colors.xml | 41 + app/src/main/res/values/dimens.xml | 35 + .../res/values/ic_launcher_background.xml | 4 + app/src/main/res/values/integers.xml | 4 + .../main/res/values/mp_feedback_config.xml | 9 + app/src/main/res/values/strings.xml | 196 + app/src/main/res/values/styles.xml | 35 + app/src/main/res/values/themes.xml | 73 + app/src/main/res/values/type.xml | 119 + .../main/res/xml/network_security_config.xml | 8 + app/src/main/res/xml/provider_paths.xml | 3 + build.gradle | 33 + feedback-android/build.gradle | 60 + feedback-android/lint.xml | 7 + feedback-android/proguard-rules.pro | 35 + feedback-android/src/main/AndroidManifest.xml | 17 + .../module/core/ActivityTracker.java | 108 + .../module/core/AndroidUiNotifier.java | 24 + .../mobilekit/module/core/Command.java | 7 + .../mobilekit/module/core/DeviceInfo.java | 144 + .../module/core/FeedbackBaseActivity.java | 32 + .../mobilekit/module/core/JobQueue.java | 27 + .../core/MobileKitDialogViewBuilder.java | 97 + .../mobilekit/module/core/Receiver.java | 6 + .../mobilekit/module/core/UiInfo.java | 16 + .../mobilekit/module/core/UiInfoListener.java | 10 + .../mobilekit/module/core/UiNotifier.java | 9 + .../mobilekit/module/core/UiReceiver.java | 10 + .../module/core/utils/StringUtils.java | 23 + .../module/core/utils/SystemUtils.java | 22 + .../module/feedback/FeedbackActivity.java | 239 + .../module/feedback/FeedbackClient.java | 214 + .../module/feedback/FeedbackDataProvider.java | 34 + .../module/feedback/FeedbackModule.java | 103 + .../FeedbackNotificationListener.java | 12 + .../module/feedback/FeedbackSettings.java | 20 + .../module/feedback/FinishAction.java | 6 + .../module/feedback/JiraIssueType.java | 22 + .../feedback/ProgressDialogActions.java | 8 + .../feedback/ProgressDialogFragment.java | 27 + .../module/feedback/SendFeedbackListener.java | 11 + .../module/feedback/SnackbarBuilder.java | 46 + .../module/feedback/SnackbarCallback.java | 21 + .../module/feedback/SnackbarReceiver.java | 150 + .../feedback/commands/AbstractCommand.java | 45 + .../commands/LoadFeedbackConfigCommand.java | 118 + .../module/feedback/commands/Result.java | 6 + .../commands/SendFeedbackCommand.java | 109 + .../feedback/model/CreateIssueRequest.java | 233 + .../feedback/model/CreateIssueResponse.java | 52 + .../module/feedback/model/FeedbackConfig.java | 33 + .../feedback/network/BaseApiParams.java | 8 + .../module/feedback/network/JmcApi.java | 28 + .../feedback/network/JmcRestClient.java | 34 + .../drawable/feedback_button_text_state.xml | 9 + .../src/main/res/drawable/ic_send.xml | 16 + .../main/res/drawable/ic_send_disabled.xml | 18 + .../src/main/res/drawable/send_selector.xml | 7 + .../src/main/res/layout/activity_feedback.xml | 25 + .../src/main/res/layout/content_feedback.xml | 87 + .../layout/mk_feedback_dialog_container.xml | 40 + .../res/layout/mk_feedback_dialog_content.xml | 23 + .../res/layout/mk_feedback_dialog_title.xml | 28 + .../src/main/res/menu/menu_feedback.xml | 10 + .../src/main/res/values-w820dp/dimens.xml | 6 + .../src/main/res/values/colors.xml | 6 + .../src/main/res/values/dimens.xml | 13 + .../src/main/res/values/fonts.xml | 4 + .../main/res/values/mp_feedback_config.xml | 9 + .../src/main/res/values/strings.xml | 25 + .../src/main/res/values/styles.xml | 31 + gradle.properties | 45 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 + gradlew.bat | 84 + settings.gradle | 2 + 341 files changed, 28036 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/schemas/au.gov.dta.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json create mode 100644 app/schemas/au.gov.dta.covidtrace.streetpass.persistence.StreetPassRecordDatabase/2.json create mode 100644 app/schemas/au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json create mode 100644 app/src/debug/AndroidManifest.xml create mode 100644 app/src/debug/res/values/mp_feedback_config.xml create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/assets/loading_upload.json create mode 100644 app/src/main/assets/spinner_home.json create mode 100644 app/src/main/assets/spinner_home_upload_complete.json create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/au/gov/health/covidsafe/HasBlockingState.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/PeekActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/PlotActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/Preference.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/RecordListAdapter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/SelfIsolationDoneActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/SplashActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/TracerApp.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/Utils.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/WebViewActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEAdvertiser.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEScanner.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GATT.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattServer.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattService.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/boot/StartOnBootReceiver.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/extensions/NavigationExtensions.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/extensions/NetworkExtensions.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/extensions/PermissionExtensions.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/extensions/ViewExtensions.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/factory/NetworkFactory.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/Either.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/UseCase.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetOnboardingOtp.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetUploadOtp.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UpdateBroadcastMessageAndPerformScanWithExponentialBackOff.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UploadData.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/logging/CentralLog.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/request/AuthChallengeRequest.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/request/OTPChallengeRequest.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/response/AuthChallengeResponse.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/response/BroadcastMessageResponse.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/response/InitiateUploadResponse.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/response/OTPChallengeResponse.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/response/UploadOTPResponse.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/networking/service/AwsClient.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/notifications/NotificationTemplates.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/receivers/PrivacyCleanerReceiver.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/receivers/UpgradeReceiver.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/scheduler/Scheduler.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/services/BluetoothMonitoringService.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/services/CommandHandler.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/services/SensorMonitoringService.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/status/Status.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecord.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordDao.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordStorage.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/BlacklistEntry.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/ConnectablePeripheral.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPass.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassScanner.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassServer.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassWorker.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/Work.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecord.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDao.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDatabase.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordRepository.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordStorage.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/view/RecordViewModel.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/streetpass/view/StreetPassRecordViewModel.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/BaseFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/PagerChildFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/PagerContainer.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/home/HelpFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/home/HomePresenter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/home/view/ExternalLinkCard.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/home/view/PermissionStatusCard.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/dataprivacy/DataPrivacyFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberPresenter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinPresenter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/howitworks/HowItWorksFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/introduction/IntroductionFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permission/PermissionFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsPresenter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/registrationcontent/RegistrationContentFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/undersixteen/UnderSixteenFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/UploadContainerFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/model/DebugData.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/model/ExportData.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadFinishedFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadInitialFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadStepFourFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinFragment.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinPresenter.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/view/PinInputView.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/view/SegmentedProgressBar.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/view/UlView.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingDialog.kt create mode 100644 app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingErrorDialog.kt create mode 100644 app/src/main/res/anim/slide_in_left.xml create mode 100644 app/src/main/res/anim/slide_in_right.xml create mode 100644 app/src/main/res/anim/slide_out_left.xml create mode 100644 app/src/main/res/anim/slide_out_right.xml create mode 100644 app/src/main/res/color/default_button_text_color.xml create mode 100644 app/src/main/res/color/progress_segment.xml create mode 100644 app/src/main/res/drawable-anydpi-v24/ic_notification_setting.xml create mode 100644 app/src/main/res/drawable-hdpi/australian_government_stacked_white.png create mode 100644 app/src/main/res/drawable-hdpi/ic_home_news.png create mode 100755 app/src/main/res/drawable-hdpi/ic_notification_icon.png create mode 100644 app/src/main/res/drawable-hdpi/ic_notification_setting.png create mode 100755 app/src/main/res/drawable-hdpi/ic_notification_warning.png create mode 100644 app/src/main/res/drawable-hdpi/small_green_tick.png create mode 100644 app/src/main/res/drawable-hdpi/small_red_cross.png create mode 100644 app/src/main/res/drawable-mdpi/australian_government_stacked_white.png create mode 100644 app/src/main/res/drawable-mdpi/ic_home_news.png create mode 100755 app/src/main/res/drawable-mdpi/ic_notification_icon.png create mode 100644 app/src/main/res/drawable-mdpi/ic_notification_setting.png create mode 100755 app/src/main/res/drawable-mdpi/ic_notification_warning.png create mode 100644 app/src/main/res/drawable-mdpi/small_green_tick.png create mode 100644 app/src/main/res/drawable-mdpi/small_red_cross.png create mode 100644 app/src/main/res/drawable-xhdpi/australian_government_stacked_white.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_home_news.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_notification_icon.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_notification_setting.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_notification_warning.png create mode 100644 app/src/main/res/drawable-xhdpi/small_green_tick.png create mode 100644 app/src/main/res/drawable-xhdpi/small_red_cross.png create mode 100644 app/src/main/res/drawable-xxhdpi/australian_government_stacked_white.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_home_news.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_notification_icon.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_notification_setting.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_notification_warning.png create mode 100644 app/src/main/res/drawable-xxhdpi/small_green_tick.png create mode 100644 app/src/main/res/drawable-xxhdpi/small_red_cross.png create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_notification_icon.png create mode 100755 app/src/main/res/drawable-xxxhdpi/ic_notification_warning.png create mode 100644 app/src/main/res/drawable/background_circular_black.xml create mode 100644 app/src/main/res/drawable/background_circular_dark_cerulean_1.xml create mode 100644 app/src/main/res/drawable/background_circular_dark_cerulean_4.xml create mode 100644 app/src/main/res/drawable/background_circular_green.xml create mode 100644 app/src/main/res/drawable/background_light_green.xml create mode 100644 app/src/main/res/drawable/default_button_selector.xml create mode 100644 app/src/main/res/drawable/edit_text_black_background.xml create mode 100644 app/src/main/res/drawable/edit_text_green_background.xml create mode 100644 app/src/main/res/drawable/edittext_modified_states.xml create mode 100644 app/src/main/res/drawable/green_button_background.xml create mode 100644 app/src/main/res/drawable/grey_button_background.xml create mode 100644 app/src/main/res/drawable/ic_arrow_drop_down.xml create mode 100644 app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_check.xml create mode 100644 app/src/main/res/drawable/ic_chevron_right.xml create mode 100644 app/src/main/res/drawable/ic_close.xml create mode 100644 app/src/main/res/drawable/ic_delete_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_doctor_circle.xml create mode 100644 app/src/main/res/drawable/ic_ellipse.xml create mode 100644 app/src/main/res/drawable/ic_help_outline_black.xml create mode 100644 app/src/main/res/drawable/ic_help_outline_white.xml create mode 100644 app/src/main/res/drawable/ic_help_stop_covid.xml create mode 100644 app/src/main/res/drawable/ic_home_logo.xml create mode 100644 app/src/main/res/drawable/ic_home_share.xml create mode 100644 app/src/main/res/drawable/ic_home_unprotected.xml create mode 100644 app/src/main/res/drawable/ic_how_it_works.xml create mode 100644 app/src/main/res/drawable/ic_illustration_upload_inital_state.xml create mode 100644 app/src/main/res/drawable/ic_illustration_upload_step_4.xml create mode 100644 app/src/main/res/drawable/ic_info.xml create mode 100644 app/src/main/res/drawable/ic_intro_picture.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_round.xml create mode 100644 app/src/main/res/drawable/ic_logo_home_inactive.xml create mode 100644 app/src/main/res/drawable/ic_logo_home_uploaded.xml create mode 100644 app/src/main/res/drawable/ic_permission.xml create mode 100644 app/src/main/res/drawable/ic_permission_success.xml create mode 100644 app/src/main/res/drawable/ic_personal_details.xml create mode 100644 app/src/main/res/drawable/ic_phone_checked_circle.xml create mode 100644 app/src/main/res/drawable/ic_play_arrow_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_privacy.xml create mode 100644 app/src/main/res/drawable/ic_smartphone.xml create mode 100644 app/src/main/res/drawable/ic_smile.xml create mode 100644 app/src/main/res/drawable/ic_splash_screen_logo.xml create mode 100644 app/src/main/res/drawable/ic_splash_screen_title.xml create mode 100644 app/src/main/res/drawable/ic_stop_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_under_sixteen.xml create mode 100644 app/src/main/res/drawable/ic_unfold_less_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_unfold_more_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_up.xml create mode 100644 app/src/main/res/drawable/ic_upload_error.xml create mode 100644 app/src/main/res/drawable/ic_upload_failed.xml create mode 100644 app/src/main/res/drawable/ic_upload_icon.xml create mode 100644 app/src/main/res/drawable/icon_checkbox.xml create mode 100644 app/src/main/res/drawable/illustration_data_uploaded.xml create mode 100644 app/src/main/res/drawable/illustration_upload_finished.xml create mode 100644 app/src/main/res/drawable/outline_button_background.xml create mode 100644 app/src/main/res/drawable/phone_number_invalid_background.xml create mode 100644 app/src/main/res/drawable/progress_segment.xml create mode 100644 app/src/main/res/drawable/splash_screen_white_wave.xml create mode 100644 app/src/main/res/font/font_roboto_regular.xml create mode 100644 app/src/main/res/font/roboto_medium.ttf create mode 100644 app/src/main/res/font/roboto_regular.ttf create mode 100644 app/src/main/res/layout/activity_home.xml create mode 100644 app/src/main/res/layout/activity_onboarding.xml create mode 100644 app/src/main/res/layout/activity_plot.xml create mode 100644 app/src/main/res/layout/activity_self_isolation.xml create mode 100644 app/src/main/res/layout/activity_splash.xml create mode 100644 app/src/main/res/layout/database_peek.xml create mode 100644 app/src/main/res/layout/dialog_error_uploading.xml create mode 100644 app/src/main/res/layout/dialog_uploading.xml create mode 100644 app/src/main/res/layout/fragment_data_privacy.xml create mode 100644 app/src/main/res/layout/fragment_enter_number.xml create mode 100644 app/src/main/res/layout/fragment_enter_pin.xml create mode 100644 app/src/main/res/layout/fragment_help.xml create mode 100644 app/src/main/res/layout/fragment_home.xml create mode 100644 app/src/main/res/layout/fragment_home_external_links.xml create mode 100644 app/src/main/res/layout/fragment_home_setup_complete_header.xml create mode 100644 app/src/main/res/layout/fragment_home_setup_incomplete_content.xml create mode 100644 app/src/main/res/layout/fragment_home_uploaded_card.xml create mode 100644 app/src/main/res/layout/fragment_how_it_works.xml create mode 100644 app/src/main/res/layout/fragment_intro.xml create mode 100644 app/src/main/res/layout/fragment_permission.xml create mode 100644 app/src/main/res/layout/fragment_permission_success.xml create mode 100644 app/src/main/res/layout/fragment_personal_details.xml create mode 100644 app/src/main/res/layout/fragment_registration_consent.xml create mode 100644 app/src/main/res/layout/fragment_under_sixteen.xml create mode 100644 app/src/main/res/layout/fragment_upload_finished.xml create mode 100644 app/src/main/res/layout/fragment_upload_initial.xml create mode 100644 app/src/main/res/layout/fragment_upload_master.xml create mode 100644 app/src/main/res/layout/fragment_upload_page_4.xml create mode 100644 app/src/main/res/layout/fragment_verify_upload_pin.xml create mode 100644 app/src/main/res/layout/recycler_view_item.xml create mode 100644 app/src/main/res/layout/view_card_external_link_card.xml create mode 100644 app/src/main/res/layout/view_card_permission_card.xml create mode 100644 app/src/main/res/layout/view_pin.xml create mode 100644 app/src/main/res/layout/view_ul.xml create mode 100644 app/src/main/res/layout/webview.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100755 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100755 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100755 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100755 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/navigation/nav_home.xml create mode 100644 app/src/main/res/navigation/nav_onboarding.xml create mode 100644 app/src/main/res/navigation/nav_register.xml create mode 100644 app/src/main/res/navigation/nav_upload.xml create mode 100644 app/src/main/res/values-v24/themes.xml create mode 100644 app/src/main/res/values/attrs.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/ic_launcher_background.xml create mode 100644 app/src/main/res/values/integers.xml create mode 100644 app/src/main/res/values/mp_feedback_config.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100755 app/src/main/res/values/type.xml create mode 100644 app/src/main/res/xml/network_security_config.xml create mode 100644 app/src/main/res/xml/provider_paths.xml create mode 100644 build.gradle create mode 100644 feedback-android/build.gradle create mode 100644 feedback-android/lint.xml create mode 100644 feedback-android/proguard-rules.pro create mode 100644 feedback-android/src/main/AndroidManifest.xml create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/ActivityTracker.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/AndroidUiNotifier.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/Command.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/DeviceInfo.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/FeedbackBaseActivity.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/JobQueue.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/MobileKitDialogViewBuilder.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/Receiver.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/UiInfo.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/UiInfoListener.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/UiNotifier.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/UiReceiver.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/utils/StringUtils.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/core/utils/SystemUtils.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackActivity.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackClient.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackDataProvider.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackModule.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackNotificationListener.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FeedbackSettings.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/FinishAction.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/JiraIssueType.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/ProgressDialogActions.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/ProgressDialogFragment.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/SendFeedbackListener.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/SnackbarBuilder.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/SnackbarCallback.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/SnackbarReceiver.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/commands/AbstractCommand.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/commands/LoadFeedbackConfigCommand.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/commands/Result.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/commands/SendFeedbackCommand.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/model/CreateIssueRequest.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/model/CreateIssueResponse.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/model/FeedbackConfig.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/network/BaseApiParams.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/network/JmcApi.java create mode 100644 feedback-android/src/main/java/com/atlassian/mobilekit/module/feedback/network/JmcRestClient.java create mode 100644 feedback-android/src/main/res/drawable/feedback_button_text_state.xml create mode 100644 feedback-android/src/main/res/drawable/ic_send.xml create mode 100644 feedback-android/src/main/res/drawable/ic_send_disabled.xml create mode 100644 feedback-android/src/main/res/drawable/send_selector.xml create mode 100644 feedback-android/src/main/res/layout/activity_feedback.xml create mode 100644 feedback-android/src/main/res/layout/content_feedback.xml create mode 100644 feedback-android/src/main/res/layout/mk_feedback_dialog_container.xml create mode 100644 feedback-android/src/main/res/layout/mk_feedback_dialog_content.xml create mode 100644 feedback-android/src/main/res/layout/mk_feedback_dialog_title.xml create mode 100644 feedback-android/src/main/res/menu/menu_feedback.xml create mode 100644 feedback-android/src/main/res/values-w820dp/dimens.xml create mode 100644 feedback-android/src/main/res/values/colors.xml create mode 100644 feedback-android/src/main/res/values/dimens.xml create mode 100644 feedback-android/src/main/res/values/fonts.xml create mode 100644 feedback-android/src/main/res/values/mp_feedback_config.xml create mode 100644 feedback-android/src/main/res/values/strings.xml create mode 100644 feedback-android/src/main/res/values/styles.xml create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..7fc52fa --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +# Terms and Conditions for access to COVIDSafe App code +By accessing the App Code I accept and agree to the following terms: + +1. If I distribute the App Code to anyone else, I will ensure these terms are provided to them and are not deleted. +2. I agree to access the App Code for the purpose of obtaining information about the COVIDSafe App only. +3. I understand and agree that the App Code is provided on an as is where is basis, that the App Code may be updated over time, and that the DTA and the Commonwealth have no liability whatsoever in connection with my access to or use of the App Code. + +4. I agree to stop all access and use of the App Code if requested by the DTA. +5. I will not use the App Code for any product development purposes. +6. I will promptly report to the DTA on any actual or potential security vulnerabilities I become aware of in respect of the COVIDSafe App. +7. I am responsible for any costs of third party claims associated with my access to the App Code, and must pay those claims on request. +8. I understand and agree that: + + **a.** the DTA will collect information about me and my access to the App Code, and any feedback, comments, or other information that I post on GitHub in connection with the App Code (and I understand that this information may also be seen or accessed by other users of GitHub who have been given access to the App Code); + + **b.** the DTA may use that information for the purposes of managing my access to the App Code, and to consider any feedback, comments or other information that I provide in relation to the App Code or the COVIDSafe App; + + **c.** the DTA may disclose that information to other Commonwealth agencies and their contractors for the purposes of improving the App Code or the COVIDSafe App, or as required for public accountability and reporting purposes, but DTA will de-identify personal information before disclosure wherever reasonable and practicable (GitHub, a company based in the US, may also handle your personal information in accordance with the GitHub Terms and Conditions); and + + **d.** further information about how DTA will handle personal information, and my rights to complain or access or correct my personal information, is available at DTA's Privacy Policy. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe7084e --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# COVIDSafe app + +# [Terms and Conditions for access to COVIDSafe App code](https://github.com/AU-COVIDSafe/mobile-android/blob/master/LICENSE.md) +By accessing the App Code I accept and agree to the following terms: + +1. If I distribute the App Code to anyone else, I will ensure these terms are provided to them and are not deleted. +2. I agree to access the App Code for the purpose of obtaining information about the COVIDSafe App only. +3. I understand and agree that the App Code is provided on an as is where is basis, that the App Code may be updated over time, and that the DTA and the Commonwealth have no liability whatsoever in connection with my access to or use of the App Code. + +4. I agree to stop all access and use of the App Code if requested by the DTA. +5. I will not use the App Code for any product development purposes. +6. I will promptly report to the DTA on any actual or potential security vulnerabilities I become aware of in respect of the COVIDSafe App. +7. I am responsible for any costs of third party claims associated with my access to the App Code, and must pay those claims on request. +8. I understand and agree that: + + **a.** the DTA will collect information about me and my access to the App Code, and any feedback, comments, or other information that I post on GitHub in connection with the App Code (and I understand that this information may also be seen or accessed by other users of GitHub who have been given access to the App Code); + + **b.** the DTA may use that information for the purposes of managing my access to the App Code, and to consider any feedback, comments or other information that I provide in relation to the App Code or the COVIDSafe App; + + **c.** the DTA may disclose that information to other Commonwealth agencies and their contractors for the purposes of improving the App Code or the COVIDSafe App, or as required for public accountability and reporting purposes, but DTA will de-identify personal information before disclosure wherever reasonable and practicable (GitHub, a company based in the US, may also handle your personal information in accordance with the GitHub Terms and Conditions); and + + **d.** further information about how DTA will handle personal information, and my rights to complain or access or correct my personal information, is available at DTA's Privacy Policy. diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..b783f5d --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,217 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +apply plugin: 'kotlin-kapt' + +apply plugin: "androidx.navigation.safeargs.kotlin" + +buildscript { + repositories { + google() + + } +} + +def getGitHash = { -> + def stdout = new ByteArrayOutputStream() + exec { + commandLine 'git', 'rev-parse', '--short', 'HEAD' + standardOutput = stdout + } + return stdout.toString().trim() +} + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.3" + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + defaultConfig { + applicationId "au.gov.health.covidsafe" + resValue "string", "build_config_package", "au.gov.health.covidsafe" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 16 + versionName "1.0.16" + buildConfigField "String", "GITHASH", "\"${getGitHash()}\"" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + javaCompileOptions { + annotationProcessorOptions { + arguments = ["room.schemaLocation": + "$projectDir/schemas".toString()] + } + } + + buildConfigField "String", "ORG", ORG + buildConfigField "int", "PROTOCOL_VERSION", PROTOCOL_VERSION + buildConfigField "int", "SERVICE_FOREGROUND_NOTIFICATION_ID", SERVICE_FOREGROUND_NOTIFICATION_ID + buildConfigField "String", "SERVICE_FOREGROUND_CHANNEL_ID", SERVICE_FOREGROUND_CHANNEL_ID + buildConfigField "String", "SERVICE_FOREGROUND_CHANNEL_NAME", SERVICE_FOREGROUND_CHANNEL_NAME + + buildConfigField "int", "PUSH_NOTIFICATION_ID", PUSH_NOTIFICATION_ID + buildConfigField "String", "PUSH_NOTIFICATION_CHANNEL_NAME", PUSH_NOTIFICATION_CHANNEL_NAME + + buildConfigField "long", "SCAN_DURATION", SCAN_DURATION + buildConfigField "long", "MIN_SCAN_INTERVAL", MIN_SCAN_INTERVAL + buildConfigField "long", "MAX_SCAN_INTERVAL", MAX_SCAN_INTERVAL + buildConfigField "long", "MAX_QUEUE_TIME", MAX_QUEUE_TIME + buildConfigField "long", "BM_CHECK_INTERVAL", BM_CHECK_INTERVAL + buildConfigField "long", "HEALTH_CHECK_INTERVAL", HEALTH_CHECK_INTERVAL + buildConfigField "long", "CONNECTION_TIMEOUT", CONNECTION_TIMEOUT + buildConfigField "long", "BLACKLIST_DURATION", BLACKLIST_DURATION + + buildConfigField "long", "ADVERTISING_DURATION", ADVERTISING_DURATION + buildConfigField "long", "ADVERTISING_INTERVAL", ADVERTISING_INTERVAL + + buildConfigField "boolean", "ENABLE_DEBUG_SCREEN", "false" + } + + signingConfigs { + + release { + } + + staging { + } + + debug { + } + } + + buildTypes { + debug { + buildConfigField "String", "BLE_SSID", STAGING_SERVICE_UUID + buildConfigField "boolean", "ENABLE_DEBUG_SCREEN", "true" + buildConfigField "String", "END_POINT_PREFIX", TEST_END_POINT_PREFIX + buildConfigField "String", "BASE_URL", TEST_BASE_URL + + + String ssid = STAGING_SERVICE_UUID + versionNameSuffix "-debug-${getGitHash()}-${ssid.substring(ssid.length() - 5,ssid.length() - 1 )}" + resValue "string", "app_name", "COVIDSafe Debug" + applicationIdSuffix "debug" + signingConfig signingConfigs.debug + } + + staging { + buildConfigField "String", "BLE_SSID", STAGING_SERVICE_UUID + buildConfigField "boolean", "ENABLE_DEBUG_SCREEN", "true" + buildConfigField "String", "END_POINT_PREFIX", STAGING_END_POINT_PREFIX + buildConfigField "String", "BASE_URL", STAGING_BASE_URL + + + // Retrieve bluetooth ssid from staging's strings.xml + String ssid = STAGING_SERVICE_UUID + versionNameSuffix "-beta-${getGitHash()}-${ssid.substring(ssid.length() - 5,ssid.length() - 1 )}" + debuggable false + + applicationIdSuffix "beta" + resValue "string", "app_name", "COVIDSafe beta" + + lintOptions { + // Ignore lint errors for now + abortOnError false + } + matchingFallbacks = ['release'] + signingConfig signingConfigs.staging + } + release { + + buildConfigField "String", "BLE_SSID", PRODUCTION_SERVICE_UUID + buildConfigField "String", "END_POINT_PREFIX", PRODUCTION_END_POINT_PREFIX + buildConfigField "String", "BASE_URL", PROD_BASE_URL + + debuggable false + jniDebuggable false + renderscriptDebuggable false + minifyEnabled false + shrinkResources false + multiDexEnabled false + zipAlignEnabled true + resValue "string", "app_name", "COVIDSafe" + + lintOptions { + // Ignore lint errors for now + abortOnError false + } + signingConfig signingConfigs.release + + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + } + + packagingOptions { + exclude 'META-INF/atomicfu.kotlin_module' + } + +} + +repositories { + jcenter() +} + + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) + implementation project(":feedback-android") + // kotlin + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + def kotlin_coroutines_version = "1.3.5" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" + + //androidx + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.recyclerview:recyclerview:1.1.0' + + implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0-alpha01' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'pub.devrel:easypermissions:3.0.0' + implementation 'com.google.code.gson:gson:2.8.6' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + // room + def room_version = "2.2.5" + kapt "androidx.room:room-compiler:$room_version" + implementation "androidx.room:room-runtime:$room_version" + implementation "androidx.room:room-ktx:$room_version" + + // http + implementation "com.squareup.retrofit2:retrofit:$retrofit_version" + implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" + implementation "com.squareup.okhttp3:okhttp:$okhttp_version" + implementation "com.squareup.okhttp3:logging-interceptor:$okhttp_version" + + // rx + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + + //bottom navigation + implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2' + implementation 'androidx.navigation:navigation-ui-ktx:2.2.2' + + //cardview + implementation 'androidx.cardview:cardview:1.0.0' + + //Lottie + implementation 'com.airbnb.android:lottie:3.4.0' + + implementation 'com.google.guava:guava:28.2-android' + implementation "androidx.security:security-crypto:1.0.0-beta01" + implementation "androidx.lifecycle:lifecycle-service:2.2.0" + implementation 'com.github.razir.progressbutton:progressbutton:2.0.1' +} diff --git a/app/schemas/au.gov.dta.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json b/app/schemas/au.gov.dta.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json new file mode 100644 index 0000000..3315850 --- /dev/null +++ b/app/schemas/au.gov.dta.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json @@ -0,0 +1,114 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "9a95fc8ad88c160bf76c0ba4747db316", + "entities": [ + { + "tableName": "record_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `v` INTEGER NOT NULL, `msg` TEXT NOT NULL, `org` TEXT NOT NULL, `modelP` TEXT NOT NULL, `modelC` TEXT NOT NULL, `rssi` INTEGER NOT NULL, `txPower` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "v", + "columnName": "v", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "org", + "columnName": "org", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelP", + "columnName": "modelP", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelC", + "columnName": "modelC", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rssi", + "columnName": "rssi", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "txPower", + "columnName": "txPower", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "status_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `msg` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9a95fc8ad88c160bf76c0ba4747db316')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/au.gov.dta.covidtrace.streetpass.persistence.StreetPassRecordDatabase/2.json b/app/schemas/au.gov.dta.covidtrace.streetpass.persistence.StreetPassRecordDatabase/2.json new file mode 100644 index 0000000..3315850 --- /dev/null +++ b/app/schemas/au.gov.dta.covidtrace.streetpass.persistence.StreetPassRecordDatabase/2.json @@ -0,0 +1,114 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "9a95fc8ad88c160bf76c0ba4747db316", + "entities": [ + { + "tableName": "record_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `v` INTEGER NOT NULL, `msg` TEXT NOT NULL, `org` TEXT NOT NULL, `modelP` TEXT NOT NULL, `modelC` TEXT NOT NULL, `rssi` INTEGER NOT NULL, `txPower` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "v", + "columnName": "v", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "org", + "columnName": "org", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelP", + "columnName": "modelP", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelC", + "columnName": "modelC", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rssi", + "columnName": "rssi", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "txPower", + "columnName": "txPower", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "status_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `msg` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9a95fc8ad88c160bf76c0ba4747db316')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json b/app/schemas/au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json new file mode 100644 index 0000000..3315850 --- /dev/null +++ b/app/schemas/au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase/2.json @@ -0,0 +1,114 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "9a95fc8ad88c160bf76c0ba4747db316", + "entities": [ + { + "tableName": "record_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `v` INTEGER NOT NULL, `msg` TEXT NOT NULL, `org` TEXT NOT NULL, `modelP` TEXT NOT NULL, `modelC` TEXT NOT NULL, `rssi` INTEGER NOT NULL, `txPower` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "v", + "columnName": "v", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "org", + "columnName": "org", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelP", + "columnName": "modelP", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "modelC", + "columnName": "modelC", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rssi", + "columnName": "rssi", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "txPower", + "columnName": "txPower", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "status_table", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `msg` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "msg", + "columnName": "msg", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '9a95fc8ad88c160bf76c0ba4747db316')" + ] + } +} \ No newline at end of file diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..91bf3ec --- /dev/null +++ b/app/src/debug/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/app/src/debug/res/values/mp_feedback_config.xml b/app/src/debug/res/values/mp_feedback_config.xml new file mode 100644 index 0000000..24247e1 --- /dev/null +++ b/app/src/debug/res/values/mp_feedback_config.xml @@ -0,0 +1,9 @@ + + + + + + + Android + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..32b7112 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/assets/loading_upload.json b/app/src/main/assets/loading_upload.json new file mode 100644 index 0000000..06dab39 --- /dev/null +++ b/app/src/main/assets/loading_upload.json @@ -0,0 +1,4650 @@ +{ + "v": "5.6.9", + "fr": 30, + "ip": 0, + "op": 600, + "w": 260, + "h": 260, + "nm": "Spinner_Inside2", + "ddd": 0, + "assets": [ + { + "id": "comp_0", + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Spinner_Outside Outlines 3", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.647 + ], + [ + 1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.732, + 0 + ], + [ + 0, + -1.739 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.647 + ], + [ + -1.685, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 1.737 + ], + [ + 1.733, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.732, + 0 + ], + [ + 0, + -1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.739 + ], + [ + -1.732, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + -111.574, + 8.189 + ], + [ + -108.391, + 11.299 + ], + [ + -105.207, + 8.189 + ], + [ + -105.207, + 3.11 + ], + [ + -99.871, + 3.11 + ], + [ + -96.781, + 0.09 + ], + [ + -99.871, + -2.929 + ], + [ + -105.161, + -2.929 + ], + [ + -105.161, + -8.007 + ], + [ + -108.344, + -11.118 + ], + [ + -111.574, + -8.007 + ], + [ + -111.574, + -2.929 + ], + [ + -116.91, + -2.929 + ], + [ + -120, + 0.09 + ], + [ + -116.91, + 3.11 + ], + [ + -111.574, + 3.11 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 11.076, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -108.924, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + -360 + ] + } + ], + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "Spinner_Outside Outlines 4", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.779, + 0 + ], + [ + 0, + -1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.647 + ], + [ + -1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.731, + 0 + ], + [ + 0, + 1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.647 + ], + [ + 1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.778, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.739 + ], + [ + 1.779, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.731, + 0 + ], + [ + 0, + -1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.693 + ] + ], + "v": [ + [ + 108.391, + -11.164 + ], + [ + 105.208, + -8.053 + ], + [ + 105.208, + -2.975 + ], + [ + 99.871, + -2.975 + ], + [ + 96.783, + 0.045 + ], + [ + 99.871, + 3.065 + ], + [ + 105.208, + 3.065 + ], + [ + 105.208, + 8.142 + ], + [ + 108.391, + 11.253 + ], + [ + 111.575, + 8.142 + ], + [ + 111.575, + 3.065 + ], + [ + 116.911, + 3.065 + ], + [ + 120, + 0.045 + ], + [ + 116.911, + -2.975 + ], + [ + 111.575, + -2.975 + ], + [ + 111.575, + -8.053 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 228.201, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 108.201, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + -360 + ] + } + ], + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "Spinner_Outside Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 2, + "ty": "sh", + "ix": 3, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.327, + 0.823 + ], + [ + 0, + 0 + ], + [ + 0.935, + -0.32 + ], + [ + 0, + 0 + ], + [ + -0.328, + -0.87 + ], + [ + 0, + 0 + ], + [ + -0.89, + 0.275 + ], + [ + 0.282, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.891, + 0.275 + ], + [ + 0.281, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.889, + 0.275 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.328, + -0.869 + ], + [ + 0, + 0 + ], + [ + -0.936, + 0.32 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.843, + -0.32 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.795, + -0.274 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.703, + -0.366 + ] + ], + "v": [ + [ + 119.439, + -31.705 + ], + [ + 112.652, + -49.685 + ], + [ + 110.358, + -50.691 + ], + [ + 84.143, + -41.221 + ], + [ + 83.067, + -38.979 + ], + [ + 89.948, + -20.771 + ], + [ + 92.054, + -19.811 + ], + [ + 93.037, + -21.869 + ], + [ + 86.811, + -38.385 + ], + [ + 97.157, + -42.136 + ], + [ + 102.633, + -27.679 + ], + [ + 104.741, + -26.719 + ], + [ + 105.723, + -28.777 + ], + [ + 100.246, + -43.234 + ], + [ + 110.358, + -46.894 + ], + [ + 116.537, + -30.561 + ], + [ + 118.642, + -29.601 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 3", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 3, + "ty": "sh", + "ix": 4, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.561, + -0.778 + ], + [ + -0.842, + 0.549 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.702, + 0.503 + ], + [ + 0.515, + 0.687 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.749, + 0.503 + ], + [ + 0.516, + 0.686 + ], + [ + 0, + 0 + ], + [ + 0.795, + -0.595 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0.563, + 0.778 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.732 + ], + [ + 0.749, + -0.504 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.732 + ], + [ + 0.749, + -0.504 + ], + [ + 0, + 0 + ], + [ + -0.563, + -0.732 + ], + [ + 0, + 0 + ], + [ + -0.843, + 0.458 + ] + ], + "v": [ + [ + 69.678, + -58.423 + ], + [ + 72.206, + -58.011 + ], + [ + 82.13, + -64.919 + ], + [ + 91.258, + -52.43 + ], + [ + 93.505, + -52.063 + ], + [ + 93.879, + -54.26 + ], + [ + 84.751, + -66.749 + ], + [ + 93.926, + -73.154 + ], + [ + 104.225, + -59.063 + ], + [ + 106.518, + -58.697 + ], + [ + 106.893, + -60.893 + ], + [ + 95.566, + -76.402 + ], + [ + 93.084, + -76.768 + ], + [ + 70.147, + -60.756 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 4", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 4, + "ty": "sh", + "ix": 5, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 54.606, + -85.781 + ], + [ + 66.402, + -77.5 + ], + [ + 69.959, + -94.427 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 5", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 5, + "ty": "sh", + "ix": 6, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.374, + 0.183 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.641 + ], + [ + 0, + 0 + ], + [ + 0.235, + -1.007 + ], + [ + 0, + 0 + ], + [ + 0.14, + -0.184 + ], + [ + 0.749, + 0.549 + ], + [ + -0.189, + 0.777 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.655, + 0.458 + ], + [ + -0.516, + 0.686 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0.938, + -0.549 + ], + [ + 0, + 0 + ], + [ + 0.888, + 0.641 + ], + [ + 0, + 0 + ], + [ + -0.094, + 0.321 + ], + [ + -0.562, + 0.731 + ], + [ + -0.702, + -0.504 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.702, + 0.412 + ], + [ + -0.749, + -0.503 + ], + [ + 0.093, + -0.183 + ] + ], + "v": [ + [ + 42.856, + -82.944 + ], + [ + 69.631, + -97.813 + ], + [ + 72.393, + -97.767 + ], + [ + 72.535, + -97.676 + ], + [ + 73.423, + -95.159 + ], + [ + 67.478, + -65.697 + ], + [ + 67.151, + -64.873 + ], + [ + 64.763, + -64.507 + ], + [ + 64.109, + -66.566 + ], + [ + 65.7, + -74.206 + ], + [ + 51.657, + -84.088 + ], + [ + 44.681, + -80.154 + ], + [ + 42.576, + -80.154 + ], + [ + 42.201, + -82.35 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 6", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 6, + "ty": "sh", + "ix": 7, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -4.401, + -1.327 + ], + [ + -1.637, + 5.032 + ], + [ + 0, + 0 + ], + [ + 6.227, + 3.523 + ], + [ + -0.89, + 2.791 + ], + [ + 0, + 0 + ], + [ + -3.933, + -1.19 + ], + [ + -1.967, + -2.562 + ], + [ + -0.375, + -0.137 + ], + [ + -0.281, + 0.869 + ], + [ + 0.234, + 0.366 + ], + [ + 3.978, + 1.236 + ], + [ + 1.451, + -4.621 + ], + [ + 0, + 0 + ], + [ + -6.46, + -3.568 + ], + [ + 0.889, + -2.745 + ], + [ + 0, + 0 + ], + [ + 4.074, + 1.236 + ], + [ + 2.059, + 3.202 + ], + [ + 0.421, + 0.137 + ], + [ + 0.28, + -0.915 + ], + [ + -0.28, + -0.366 + ] + ], + "o": [ + [ + 5.992, + 1.83 + ], + [ + 0, + 0 + ], + [ + 1.451, + -4.484 + ], + [ + -6.179, + -3.431 + ], + [ + 0, + 0 + ], + [ + 0.841, + -2.654 + ], + [ + 2.807, + 0.869 + ], + [ + 0.235, + 0.32 + ], + [ + 0.89, + 0.275 + ], + [ + 0.188, + -0.641 + ], + [ + -2.152, + -2.79 + ], + [ + -5.711, + -1.738 + ], + [ + 0, + 0 + ], + [ + -1.545, + 4.85 + ], + [ + 5.899, + 3.248 + ], + [ + 0, + 0 + ], + [ + -0.936, + 2.882 + ], + [ + -3.837, + -1.189 + ], + [ + -0.141, + -0.275 + ], + [ + -0.891, + -0.275 + ], + [ + -0.189, + 0.549 + ], + [ + 2.388, + 3.706 + ] + ], + "v": [ + [ + 28.532, + -84.454 + ], + [ + 41.498, + -89.623 + ], + [ + 41.545, + -89.715 + ], + [ + 34.429, + -101.061 + ], + [ + 28.111, + -109.296 + ], + [ + 28.158, + -109.387 + ], + [ + 36.116, + -112.178 + ], + [ + 43.09, + -107.237 + ], + [ + 43.979, + -106.643 + ], + [ + 46.132, + -107.74 + ], + [ + 45.851, + -109.296 + ], + [ + 37.192, + -115.152 + ], + [ + 24.741, + -110.165 + ], + [ + 24.694, + -110.074 + ], + [ + 32.089, + -98.499 + ], + [ + 38.128, + -90.493 + ], + [ + 38.081, + -90.401 + ], + [ + 29.748, + -87.474 + ], + [ + 21.37, + -93.878 + ], + [ + 20.481, + -94.564 + ], + [ + 18.328, + -93.421 + ], + [ + 18.561, + -91.957 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 7", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 7, + "ty": "sh", + "ix": 8, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.094, + 5.49 + ], + [ + 0, + 0 + ], + [ + 5.664, + -0.137 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.094, + -5.444 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 5.664, + -0.092 + ] + ], + "v": [ + [ + 6.39, + -104.675 + ], + [ + 6.39, + -104.767 + ], + [ + -3.299, + -113.871 + ], + [ + -8.683, + -113.779 + ], + [ + -8.309, + -95.205 + ], + [ + -2.925, + -95.296 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 8", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 8, + "ty": "sh", + "ix": 9, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.187, + -8.646 + ], + [ + 0, + 0 + ], + [ + 9.924, + -0.183 + ], + [ + 0, + 0 + ], + [ + 0.046, + 1.922 + ], + [ + 0, + 0 + ], + [ + -1.966, + 0.046 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0.188, + 8.693 + ], + [ + 0, + 0 + ], + [ + -1.92, + 0.046 + ], + [ + 0, + 0 + ], + [ + -0.047, + -1.876 + ], + [ + 0, + 0 + ], + [ + 9.925, + -0.183 + ] + ], + "v": [ + [ + 13.645, + -104.996 + ], + [ + 13.645, + -104.904 + ], + [ + -2.832, + -89.166 + ], + [ + -11.679, + -88.983 + ], + [ + -15.236, + -92.323 + ], + [ + -15.705, + -116.387 + ], + [ + -12.288, + -119.864 + ], + [ + -3.441, + -120.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 9", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 9, + "ty": "sh", + "ix": 10, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 1.872, + -0.549 + ], + [ + -0.561, + -1.83 + ], + [ + 0, + 0 + ], + [ + -1.872, + 0.549 + ], + [ + 0.562, + 1.83 + ] + ], + "o": [ + [ + -0.562, + -1.83 + ], + [ + -1.872, + 0.549 + ], + [ + 0, + 0 + ], + [ + 0.562, + 1.83 + ], + [ + 1.873, + -0.549 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + -29.888, + -113.185 + ], + [ + -34.195, + -115.472 + ], + [ + -36.536, + -111.263 + ], + [ + -29.467, + -87.657 + ], + [ + -25.161, + -85.369 + ], + [ + -22.82, + -89.578 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 10", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 10, + "ty": "sh", + "ix": 11, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.467, + -0.32 + ], + [ + 0, + 0 + ], + [ + -1.638, + 0.961 + ], + [ + 0, + 0 + ], + [ + 0.188, + 1.83 + ], + [ + 0, + 0 + ], + [ + 0.281, + 0.458 + ], + [ + 1.638, + -0.915 + ], + [ + -0.188, + -1.143 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.545, + -0.869 + ], + [ + -0.983, + -1.647 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 1.497, + 1.099 + ], + [ + 0, + 0 + ], + [ + 1.639, + -0.915 + ], + [ + 0, + 0 + ], + [ + -0.047, + -0.411 + ], + [ + -0.936, + -1.601 + ], + [ + -1.452, + 0.823 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.171, + -0.915 + ], + [ + -1.685, + 0.961 + ], + [ + 0.281, + 0.595 + ] + ], + "v": [ + [ + -70.521, + -93.238 + ], + [ + -49.502, + -77.409 + ], + [ + -44.728, + -76.997 + ], + [ + -44.353, + -77.226 + ], + [ + -42.294, + -81.48 + ], + [ + -45.57, + -107.466 + ], + [ + -46.038, + -108.93 + ], + [ + -50.672, + -110.119 + ], + [ + -52.451, + -106.643 + ], + [ + -49.128, + -85.232 + ], + [ + -66.12, + -98.728 + ], + [ + -70.38, + -99.094 + ], + [ + -71.691, + -94.519 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 11", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 11, + "ty": "sh", + "ix": 12, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 4.026, + 3.523 + ], + [ + 0, + 0 + ], + [ + 3.698, + -4.071 + ], + [ + -4.025, + -3.522 + ], + [ + 0, + 0 + ], + [ + -3.698, + 4.072 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -4.026, + -3.523 + ], + [ + -3.698, + 4.072 + ], + [ + 0, + 0 + ], + [ + 4.026, + 3.523 + ], + [ + 3.745, + -4.117 + ] + ], + "v": [ + [ + -73.095, + -76.448 + ], + [ + -73.142, + -76.494 + ], + [ + -86.904, + -75.991 + ], + [ + -85.875, + -62.678 + ], + [ + -85.828, + -62.632 + ], + [ + -72.065, + -63.135 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 12", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 12, + "ty": "sh", + "ix": 13, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 6.506, + -7.137 + ], + [ + 6.741, + 5.856 + ], + [ + 0, + 0 + ], + [ + -6.507, + 7.091 + ], + [ + -6.741, + -5.856 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -6.46, + 7.091 + ], + [ + 0, + 0 + ], + [ + -6.694, + -5.856 + ], + [ + 6.506, + -7.091 + ], + [ + 0, + 0 + ], + [ + 6.694, + 5.81 + ] + ], + "v": [ + [ + -67.337, + -58.926 + ], + [ + -90.602, + -57.279 + ], + [ + -90.649, + -57.325 + ], + [ + -91.632, + -80.199 + ], + [ + -68.367, + -81.846 + ], + [ + -68.32, + -81.801 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 13", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 13, + "ty": "sh", + "ix": 14, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -8.332, + -3.248 + ], + [ + 0, + 0 + ], + [ + -3.418, + 8.463 + ], + [ + 1.217, + 3.477 + ], + [ + 0.982, + 0.412 + ], + [ + 0.656, + -1.601 + ], + [ + -0.235, + -0.64 + ], + [ + 1.077, + -2.699 + ], + [ + 5.009, + 1.922 + ], + [ + 0, + 0 + ], + [ + -1.966, + 4.85 + ], + [ + -2.06, + 1.236 + ], + [ + -0.375, + 0.869 + ], + [ + 1.732, + 0.686 + ], + [ + 0.749, + -0.458 + ], + [ + 1.779, + -4.301 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 8.426, + 3.248 + ], + [ + 1.872, + -4.575 + ], + [ + -0.281, + -0.778 + ], + [ + -1.639, + -0.64 + ], + [ + -0.281, + 0.732 + ], + [ + 0.749, + 2.379 + ], + [ + -2.012, + 4.896 + ], + [ + 0, + 0 + ], + [ + -5.009, + -1.968 + ], + [ + 0.936, + -2.241 + ], + [ + 0.468, + -0.32 + ], + [ + 0.702, + -1.739 + ], + [ + -1.124, + -0.457 + ], + [ + -2.762, + 1.692 + ], + [ + -3.651, + 8.829 + ] + ], + "v": [ + [ + -104.365, + -25.575 + ], + [ + -104.271, + -25.529 + ], + [ + -83.206, + -34.404 + ], + [ + -82.738, + -46.025 + ], + [ + -84.61, + -47.992 + ], + [ + -88.777, + -46.208 + ], + [ + -88.823, + -44.058 + ], + [ + -89.058, + -36.921 + ], + [ + -101.65, + -32.163 + ], + [ + -101.743, + -32.208 + ], + [ + -107.501, + -44.058 + ], + [ + -103.007, + -49.09 + ], + [ + -101.603, + -50.737 + ], + [ + -103.475, + -55.083 + ], + [ + -106.518, + -54.854 + ], + [ + -113.399, + -46.436 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 14", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 14, + "ty": "sh", + "ix": 15, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.59, + 0.595 + ], + [ + 0.609, + -1.555 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.592, + 0.641 + ], + [ + 0.608, + -1.556 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.592, + 0.64 + ], + [ + 0.607, + -1.556 + ], + [ + 0, + 0 + ], + [ + -1.778, + -0.686 + ], + [ + 0, + 0 + ], + [ + -0.702, + 1.738 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.592, + -0.595 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.608, + -1.556 + ], + [ + -1.59, + -0.594 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.608, + -1.555 + ], + [ + -1.591, + -0.594 + ], + [ + 0, + 0 + ], + [ + -0.702, + 1.784 + ], + [ + 0, + 0 + ], + [ + 1.826, + 0.686 + ], + [ + 0, + 0 + ], + [ + 0.655, + -1.601 + ] + ], + "v": [ + [ + 116.865, + 30.651 + ], + [ + 112.838, + 32.389 + ], + [ + 107.642, + 45.428 + ], + [ + 101.463, + 43.095 + ], + [ + 105.817, + 32.115 + ], + [ + 104.084, + 28.18 + ], + [ + 100.059, + 29.919 + ], + [ + 95.705, + 40.899 + ], + [ + 89.76, + 38.611 + ], + [ + 94.863, + 25.801 + ], + [ + 93.13, + 21.867 + ], + [ + 89.106, + 23.606 + ], + [ + 82.739, + 39.526 + ], + [ + 84.704, + 43.918 + ], + [ + 107.642, + 52.656 + ], + [ + 112.136, + 50.735 + ], + [ + 118.549, + 34.585 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 15", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 15, + "ty": "sh", + "ix": 16, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.359, + 1.052 + ], + [ + 1.124, + -1.327 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.358, + 1.098 + ], + [ + 1.124, + -1.326 + ], + [ + 0, + 0 + ], + [ + -1.498, + -1.191 + ], + [ + 0, + 0 + ], + [ + -1.217, + 1.464 + ], + [ + 1.498, + 1.19 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.357, + -1.098 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.124, + -1.327 + ], + [ + -1.357, + -1.098 + ], + [ + 0, + 0 + ], + [ + -1.218, + 1.464 + ], + [ + 0, + 0 + ], + [ + 1.498, + 1.19 + ], + [ + 1.216, + -1.464 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.123, + -1.327 + ] + ], + "v": [ + [ + 91.164, + 57.506 + ], + [ + 86.717, + 57.963 + ], + [ + 79.04, + 67.204 + ], + [ + 73.798, + 63.087 + ], + [ + 82.739, + 52.29 + ], + [ + 82.27, + 47.944 + ], + [ + 77.824, + 48.401 + ], + [ + 66.777, + 61.806 + ], + [ + 67.291, + 66.565 + ], + [ + 86.624, + 81.844 + ], + [ + 91.493, + 81.341 + ], + [ + 90.977, + 76.583 + ], + [ + 83.956, + 71.047 + ], + [ + 91.633, + 61.806 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 16", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 16, + "ty": "sh", + "ix": 17, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 65.607, + 86.373 + ], + [ + 56.151, + 80.38 + ], + [ + 58.398, + 91.223 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 17", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 17, + "ty": "sh", + "ix": 18, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.233, + -0.366 + ], + [ + 1.545, + -1.007 + ], + [ + 1.358, + 0.824 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.216, + -0.823 + ], + [ + 1.031, + 1.464 + ], + [ + 0.093, + 0.503 + ], + [ + 0, + 0 + ], + [ + -1.593, + 1.007 + ], + [ + 0, + 0 + ], + [ + -1.592, + -0.961 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 1.03, + 1.51 + ], + [ + -1.357, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.28, + 1.419 + ], + [ + -1.499, + 1.007 + ], + [ + -0.281, + -0.412 + ], + [ + 0, + 0 + ], + [ + -0.329, + -1.784 + ], + [ + 0, + 0 + ], + [ + 1.546, + -1.053 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.275 + ] + ], + "v": [ + [ + 80.632, + 88.34 + ], + [ + 79.789, + 92.824 + ], + [ + 75.67, + 92.732 + ], + [ + 71.129, + 89.897 + ], + [ + 59.662, + 97.536 + ], + [ + 60.738, + 102.934 + ], + [ + 59.287, + 106.457 + ], + [ + 54.792, + 105.588 + ], + [ + 54.278, + 104.17 + ], + [ + 49.41, + 78.047 + ], + [ + 51.236, + 73.609 + ], + [ + 51.562, + 73.381 + ], + [ + 56.431, + 73.381 + ], + [ + 79.508, + 87.425 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 18", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 18, + "ty": "sh", + "ix": 19, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 6.6, + -0.321 + ], + [ + 0.608, + 1.922 + ], + [ + 0, + 0 + ], + [ + -2.527, + 0.778 + ], + [ + -2.621, + -0.595 + ], + [ + -0.657, + 0.183 + ], + [ + 0.516, + 1.693 + ], + [ + 0.891, + 0.183 + ], + [ + 3.652, + -1.144 + ], + [ + -1.686, + -5.353 + ], + [ + 0, + 0 + ], + [ + -6.554, + 0.366 + ], + [ + -0.516, + -1.601 + ], + [ + 0, + 0 + ], + [ + 2.714, + -0.823 + ], + [ + 2.81, + 0.961 + ], + [ + 0.841, + -0.275 + ], + [ + -0.514, + -1.692 + ], + [ + -0.889, + -0.275 + ], + [ + -3.978, + 1.19 + ], + [ + 1.872, + 5.856 + ] + ], + "o": [ + [ + -1.639, + -5.124 + ], + [ + -5.617, + 0.274 + ], + [ + 0, + 0 + ], + [ + -0.468, + -1.418 + ], + [ + 2.06, + -0.64 + ], + [ + 0.61, + 0.137 + ], + [ + 1.731, + -0.503 + ], + [ + -0.421, + -1.281 + ], + [ + -3.229, + -0.87 + ], + [ + -6.131, + 1.875 + ], + [ + 0, + 0 + ], + [ + 1.873, + 5.856 + ], + [ + 5.429, + -0.274 + ], + [ + 0, + 0 + ], + [ + 0.561, + 1.738 + ], + [ + -2.95, + 0.869 + ], + [ + -0.514, + -0.183 + ], + [ + -1.733, + 0.503 + ], + [ + 0.328, + 1.007 + ], + [ + 4.12, + 1.327 + ], + [ + 6.507, + -1.967 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 45.899, + 102.34 + ], + [ + 33.54, + 96.439 + ], + [ + 25.817, + 94.562 + ], + [ + 25.769, + 94.471 + ], + [ + 28.812, + 90.719 + ], + [ + 35.787, + 90.765 + ], + [ + 37.614, + 90.719 + ], + [ + 39.766, + 86.785 + ], + [ + 37.472, + 84.681 + ], + [ + 27.08, + 85.001 + ], + [ + 19.357, + 97.079 + ], + [ + 19.404, + 97.17 + ], + [ + 32.277, + 103.117 + ], + [ + 39.533, + 104.993 + ], + [ + 39.579, + 105.085 + ], + [ + 36.116, + 109.202 + ], + [ + 27.548, + 108.882 + ], + [ + 25.49, + 108.882 + ], + [ + 23.335, + 112.816 + ], + [ + 25.348, + 114.875 + ], + [ + 37.8, + 114.966 + ], + [ + 45.946, + 102.477 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 19", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 19, + "ty": "sh", + "ix": 20, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 7.959, + 0.183 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.187, + 6.817 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 7.958, + 0.183 + ], + [ + 0, + 0 + ], + [ + 0.141, + -6.817 + ] + ], + "v": [ + [ + -4.143, + 92.412 + ], + [ + -11.539, + 92.229 + ], + [ + -12.147, + 116.613 + ], + [ + -4.751, + 116.796 + ], + [ + 8.637, + 104.993 + ], + [ + 8.637, + 104.902 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 20", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 20, + "ty": "sh", + "ix": 21, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.235, + -8.647 + ], + [ + 0, + 0 + ], + [ + 9.925, + 0.229 + ], + [ + 0, + 0 + ], + [ + 0, + 0.961 + ], + [ + 0, + 0 + ], + [ + -0.983, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.234, + 8.692 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.046 + ], + [ + 0, + 0 + ], + [ + 0.048, + -0.961 + ], + [ + 0, + 0 + ], + [ + 9.924, + 0.275 + ] + ], + "v": [ + [ + 12.288, + 104.902 + ], + [ + 12.288, + 104.993 + ], + [ + -4.892, + 119.999 + ], + [ + -14.067, + 119.77 + ], + [ + -15.798, + 117.986 + ], + [ + -15.097, + 90.674 + ], + [ + -13.271, + 88.935 + ], + [ + -4.096, + 89.164 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 21", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 21, + "ty": "sh", + "ix": 22, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.936, + 0.275 + ], + [ + 0.28, + -0.961 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.229 + ], + [ + -0.281, + 0.961 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -0.89, + -0.274 + ], + [ + 0, + 0 + ], + [ + -0.281, + 0.915 + ], + [ + 0.936, + 0.275 + ], + [ + 0, + 0 + ], + [ + 0.233, + -0.869 + ] + ], + "v": [ + [ + -24.458, + 85.641 + ], + [ + -26.658, + 86.877 + ], + [ + -34.429, + 113.594 + ], + [ + -33.212, + 115.744 + ], + [ + -30.965, + 114.509 + ], + [ + -23.194, + 87.791 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 22", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 22, + "ty": "sh", + "ix": 23, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.141, + 0.229 + ], + [ + 0.843, + 0.457 + ], + [ + 0.608, + -0.412 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.796, + 0.457 + ], + [ + 0.421, + -0.732 + ], + [ + 0, + -0.274 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.503 + ], + [ + 0, + 0 + ], + [ + -0.796, + 0.549 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0.467, + -0.777 + ], + [ + -0.702, + -0.412 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.093, + -0.823 + ], + [ + -0.842, + -0.504 + ], + [ + -0.14, + 0.275 + ], + [ + 0, + 0 + ], + [ + -0.14, + 0.961 + ], + [ + 0, + 0 + ], + [ + 0.889, + 0.503 + ], + [ + 0, + 0 + ], + [ + 0.14, + -0.275 + ] + ], + "v": [ + [ + -33.071, + 85.824 + ], + [ + -33.727, + 83.537 + ], + [ + -35.88, + 83.766 + ], + [ + -58.443, + 100.693 + ], + [ + -54.885, + 73.243 + ], + [ + -55.822, + 71.185 + ], + [ + -58.256, + 71.779 + ], + [ + -58.49, + 72.557 + ], + [ + -61.907, + 102.294 + ], + [ + -60.831, + 104.581 + ], + [ + -60.69, + 104.673 + ], + [ + -58.162, + 104.444 + ], + [ + -33.493, + 86.465 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 23", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 23, + "ty": "sh", + "ix": 24, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 4.775, + 5.307 + ], + [ + 5.383, + -4.62 + ], + [ + 0, + 0 + ], + [ + -4.775, + -5.261 + ], + [ + -5.384, + 4.621 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -4.775, + -5.307 + ], + [ + 0, + 0 + ], + [ + -5.384, + 4.621 + ], + [ + 4.775, + 5.307 + ], + [ + 0, + 0 + ], + [ + 5.384, + -4.621 + ] + ], + "v": [ + [ + -70.146, + 60.754 + ], + [ + -88.028, + 60.067 + ], + [ + -88.074, + 60.113 + ], + [ + -89.619, + 77.635 + ], + [ + -71.737, + 78.321 + ], + [ + -71.691, + 78.276 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 24", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 24, + "ty": "sh", + "ix": 25, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -6.366, + -7.045 + ], + [ + 6.507, + -5.581 + ], + [ + 0, + 0 + ], + [ + 6.366, + 7.045 + ], + [ + -6.507, + 5.627 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 6.366, + 7.045 + ], + [ + 0, + 0 + ], + [ + -6.506, + 5.627 + ], + [ + -6.366, + -7.045 + ], + [ + 0, + 0 + ], + [ + 6.553, + -5.581 + ] + ], + "v": [ + [ + -67.618, + 58.695 + ], + [ + -69.163, + 80.929 + ], + [ + -69.21, + 80.975 + ], + [ + -92.147, + 79.694 + ], + [ + -90.602, + 57.414 + ], + [ + -90.555, + 57.368 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 25", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 25, + "ty": "sh", + "ix": 26, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -2.528, + -6.314 + ], + [ + -3.324, + -1.555 + ], + [ + -0.187, + -0.412 + ], + [ + 0.843, + -0.32 + ], + [ + 0.374, + 0.182 + ], + [ + 1.873, + 4.712 + ], + [ + -8.426, + 3.249 + ], + [ + 0, + 0 + ], + [ + -3.418, + -8.463 + ], + [ + 1.17, + -3.524 + ], + [ + 0.608, + -0.228 + ], + [ + 0.327, + 0.869 + ], + [ + -0.094, + 0.274 + ], + [ + 1.451, + 3.523 + ], + [ + 6.741, + -2.608 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 1.451, + 3.568 + ], + [ + 0.327, + 0.138 + ], + [ + 0.327, + 0.823 + ], + [ + -0.515, + 0.183 + ], + [ + -3.792, + -1.831 + ], + [ + -3.37, + -8.281 + ], + [ + 0, + 0 + ], + [ + 8.285, + -3.203 + ], + [ + 1.872, + 4.621 + ], + [ + -0.14, + 0.456 + ], + [ + -0.89, + 0.321 + ], + [ + -0.187, + -0.458 + ], + [ + 1.123, + -2.974 + ], + [ + -2.575, + -6.359 + ], + [ + 0, + 0 + ], + [ + -6.788, + 2.562 + ] + ], + "v": [ + [ + -110.45, + 45.291 + ], + [ + -103.428, + 52.427 + ], + [ + -102.539, + 53.297 + ], + [ + -103.522, + 55.447 + ], + [ + -104.926, + 55.356 + ], + [ + -113.54, + 46.389 + ], + [ + -104.271, + 26.167 + ], + [ + -104.177, + 26.122 + ], + [ + -83.112, + 34.768 + ], + [ + -82.785, + 46.481 + ], + [ + -83.861, + 47.669 + ], + [ + -86.155, + 46.663 + ], + [ + -86.202, + 45.474 + ], + [ + -86.202, + 35.958 + ], + [ + -102.726, + 29.507 + ], + [ + -102.82, + 29.553 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 26", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 120, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 30, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + } + ] + } + ], + "layers": [ + { + "ddd": 0, + "ind": 2, + "ty": 0, + "nm": "Spinner_Outside Outlines Comp 1", + "refId": "comp_0", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + 360 + ] + } + ], + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 130, + 130, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "w": 240, + "h": 240, + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} \ No newline at end of file diff --git a/app/src/main/assets/spinner_home.json b/app/src/main/assets/spinner_home.json new file mode 100644 index 0000000..779aef8 --- /dev/null +++ b/app/src/main/assets/spinner_home.json @@ -0,0 +1,5500 @@ +{ + "v": "5.6.9", + "fr": 30, + "ip": 0, + "op": 600, + "w": 260, + "h": 260, + "nm": "Spinner_Inside2", + "ddd": 0, + "assets": [ + { + "id": "comp_0", + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Spinner_Outside Outlines 3", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.647 + ], + [ + 1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.732, + 0 + ], + [ + 0, + -1.739 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.647 + ], + [ + -1.685, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 1.737 + ], + [ + 1.733, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.732, + 0 + ], + [ + 0, + -1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.739 + ], + [ + -1.732, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + -111.574, + 8.189 + ], + [ + -108.391, + 11.299 + ], + [ + -105.207, + 8.189 + ], + [ + -105.207, + 3.11 + ], + [ + -99.871, + 3.11 + ], + [ + -96.781, + 0.09 + ], + [ + -99.871, + -2.929 + ], + [ + -105.161, + -2.929 + ], + [ + -105.161, + -8.007 + ], + [ + -108.344, + -11.118 + ], + [ + -111.574, + -8.007 + ], + [ + -111.574, + -2.929 + ], + [ + -116.91, + -2.929 + ], + [ + -120, + 0.09 + ], + [ + -116.91, + 3.11 + ], + [ + -111.574, + 3.11 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 11.076, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + -108.924, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + -360 + ] + } + ], + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 4, + "nm": "Spinner_Outside Outlines 4", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.779, + 0 + ], + [ + 0, + -1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.647 + ], + [ + -1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.731, + 0 + ], + [ + 0, + 1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.647 + ], + [ + 1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.778, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.732, + 0 + ], + [ + 0, + 1.692 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 1.739 + ], + [ + 1.779, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.731, + 0 + ], + [ + 0, + -1.693 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + -1.693 + ] + ], + "v": [ + [ + 108.391, + -11.164 + ], + [ + 105.208, + -8.053 + ], + [ + 105.208, + -2.975 + ], + [ + 99.871, + -2.975 + ], + [ + 96.783, + 0.045 + ], + [ + 99.871, + 3.065 + ], + [ + 105.208, + 3.065 + ], + [ + 105.208, + 8.142 + ], + [ + 108.391, + 11.253 + ], + [ + 111.575, + 8.142 + ], + [ + 111.575, + 3.065 + ], + [ + 116.911, + 3.065 + ], + [ + 120, + 0.045 + ], + [ + 116.911, + -2.975 + ], + [ + 111.575, + -2.975 + ], + [ + 111.575, + -8.053 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 228.201, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 108.201, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + -360 + ] + } + ], + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 3, + "ty": 4, + "nm": "Spinner_Outside Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 2, + "ty": "sh", + "ix": 3, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.327, + 0.823 + ], + [ + 0, + 0 + ], + [ + 0.935, + -0.32 + ], + [ + 0, + 0 + ], + [ + -0.328, + -0.87 + ], + [ + 0, + 0 + ], + [ + -0.89, + 0.275 + ], + [ + 0.282, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.891, + 0.275 + ], + [ + 0.281, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.889, + 0.275 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.328, + -0.869 + ], + [ + 0, + 0 + ], + [ + -0.936, + 0.32 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.843, + -0.32 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.795, + -0.274 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.328, + 0.823 + ], + [ + 0.703, + -0.366 + ] + ], + "v": [ + [ + 119.439, + -31.705 + ], + [ + 112.652, + -49.685 + ], + [ + 110.358, + -50.691 + ], + [ + 84.143, + -41.221 + ], + [ + 83.067, + -38.979 + ], + [ + 89.948, + -20.771 + ], + [ + 92.054, + -19.811 + ], + [ + 93.037, + -21.869 + ], + [ + 86.811, + -38.385 + ], + [ + 97.157, + -42.136 + ], + [ + 102.633, + -27.679 + ], + [ + 104.741, + -26.719 + ], + [ + 105.723, + -28.777 + ], + [ + 100.246, + -43.234 + ], + [ + 110.358, + -46.894 + ], + [ + 116.537, + -30.561 + ], + [ + 118.642, + -29.601 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 3", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 3, + "ty": "sh", + "ix": 4, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.561, + -0.778 + ], + [ + -0.842, + 0.549 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.702, + 0.503 + ], + [ + 0.515, + 0.687 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.749, + 0.503 + ], + [ + 0.516, + 0.686 + ], + [ + 0, + 0 + ], + [ + 0.795, + -0.595 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0.563, + 0.778 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.732 + ], + [ + 0.749, + -0.504 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.732 + ], + [ + 0.749, + -0.504 + ], + [ + 0, + 0 + ], + [ + -0.563, + -0.732 + ], + [ + 0, + 0 + ], + [ + -0.843, + 0.458 + ] + ], + "v": [ + [ + 69.678, + -58.423 + ], + [ + 72.206, + -58.011 + ], + [ + 82.13, + -64.919 + ], + [ + 91.258, + -52.43 + ], + [ + 93.505, + -52.063 + ], + [ + 93.879, + -54.26 + ], + [ + 84.751, + -66.749 + ], + [ + 93.926, + -73.154 + ], + [ + 104.225, + -59.063 + ], + [ + 106.518, + -58.697 + ], + [ + 106.893, + -60.893 + ], + [ + 95.566, + -76.402 + ], + [ + 93.084, + -76.768 + ], + [ + 70.147, + -60.756 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 4", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 4, + "ty": "sh", + "ix": 5, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 54.606, + -85.781 + ], + [ + 66.402, + -77.5 + ], + [ + 69.959, + -94.427 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 5", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 5, + "ty": "sh", + "ix": 6, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.374, + 0.183 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.641 + ], + [ + 0, + 0 + ], + [ + 0.235, + -1.007 + ], + [ + 0, + 0 + ], + [ + 0.14, + -0.184 + ], + [ + 0.749, + 0.549 + ], + [ + -0.189, + 0.777 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.655, + 0.458 + ], + [ + -0.516, + 0.686 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0.938, + -0.549 + ], + [ + 0, + 0 + ], + [ + 0.888, + 0.641 + ], + [ + 0, + 0 + ], + [ + -0.094, + 0.321 + ], + [ + -0.562, + 0.731 + ], + [ + -0.702, + -0.504 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.702, + 0.412 + ], + [ + -0.749, + -0.503 + ], + [ + 0.093, + -0.183 + ] + ], + "v": [ + [ + 42.856, + -82.944 + ], + [ + 69.631, + -97.813 + ], + [ + 72.393, + -97.767 + ], + [ + 72.535, + -97.676 + ], + [ + 73.423, + -95.159 + ], + [ + 67.478, + -65.697 + ], + [ + 67.151, + -64.873 + ], + [ + 64.763, + -64.507 + ], + [ + 64.109, + -66.566 + ], + [ + 65.7, + -74.206 + ], + [ + 51.657, + -84.088 + ], + [ + 44.681, + -80.154 + ], + [ + 42.576, + -80.154 + ], + [ + 42.201, + -82.35 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 6", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 6, + "ty": "sh", + "ix": 7, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -4.401, + -1.327 + ], + [ + -1.637, + 5.032 + ], + [ + 0, + 0 + ], + [ + 6.227, + 3.523 + ], + [ + -0.89, + 2.791 + ], + [ + 0, + 0 + ], + [ + -3.933, + -1.19 + ], + [ + -1.967, + -2.562 + ], + [ + -0.375, + -0.137 + ], + [ + -0.281, + 0.869 + ], + [ + 0.234, + 0.366 + ], + [ + 3.978, + 1.236 + ], + [ + 1.451, + -4.621 + ], + [ + 0, + 0 + ], + [ + -6.46, + -3.568 + ], + [ + 0.889, + -2.745 + ], + [ + 0, + 0 + ], + [ + 4.074, + 1.236 + ], + [ + 2.059, + 3.202 + ], + [ + 0.421, + 0.137 + ], + [ + 0.28, + -0.915 + ], + [ + -0.28, + -0.366 + ] + ], + "o": [ + [ + 5.992, + 1.83 + ], + [ + 0, + 0 + ], + [ + 1.451, + -4.484 + ], + [ + -6.179, + -3.431 + ], + [ + 0, + 0 + ], + [ + 0.841, + -2.654 + ], + [ + 2.807, + 0.869 + ], + [ + 0.235, + 0.32 + ], + [ + 0.89, + 0.275 + ], + [ + 0.188, + -0.641 + ], + [ + -2.152, + -2.79 + ], + [ + -5.711, + -1.738 + ], + [ + 0, + 0 + ], + [ + -1.545, + 4.85 + ], + [ + 5.899, + 3.248 + ], + [ + 0, + 0 + ], + [ + -0.936, + 2.882 + ], + [ + -3.837, + -1.189 + ], + [ + -0.141, + -0.275 + ], + [ + -0.891, + -0.275 + ], + [ + -0.189, + 0.549 + ], + [ + 2.388, + 3.706 + ] + ], + "v": [ + [ + 28.532, + -84.454 + ], + [ + 41.498, + -89.623 + ], + [ + 41.545, + -89.715 + ], + [ + 34.429, + -101.061 + ], + [ + 28.111, + -109.296 + ], + [ + 28.158, + -109.387 + ], + [ + 36.116, + -112.178 + ], + [ + 43.09, + -107.237 + ], + [ + 43.979, + -106.643 + ], + [ + 46.132, + -107.74 + ], + [ + 45.851, + -109.296 + ], + [ + 37.192, + -115.152 + ], + [ + 24.741, + -110.165 + ], + [ + 24.694, + -110.074 + ], + [ + 32.089, + -98.499 + ], + [ + 38.128, + -90.493 + ], + [ + 38.081, + -90.401 + ], + [ + 29.748, + -87.474 + ], + [ + 21.37, + -93.878 + ], + [ + 20.481, + -94.564 + ], + [ + 18.328, + -93.421 + ], + [ + 18.561, + -91.957 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 7", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 7, + "ty": "sh", + "ix": 8, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.094, + 5.49 + ], + [ + 0, + 0 + ], + [ + 5.664, + -0.137 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.094, + -5.444 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 5.664, + -0.092 + ] + ], + "v": [ + [ + 6.39, + -104.675 + ], + [ + 6.39, + -104.767 + ], + [ + -3.299, + -113.871 + ], + [ + -8.683, + -113.779 + ], + [ + -8.309, + -95.205 + ], + [ + -2.925, + -95.296 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 8", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 8, + "ty": "sh", + "ix": 9, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.187, + -8.646 + ], + [ + 0, + 0 + ], + [ + 9.924, + -0.183 + ], + [ + 0, + 0 + ], + [ + 0.046, + 1.922 + ], + [ + 0, + 0 + ], + [ + -1.966, + 0.046 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0.188, + 8.693 + ], + [ + 0, + 0 + ], + [ + -1.92, + 0.046 + ], + [ + 0, + 0 + ], + [ + -0.047, + -1.876 + ], + [ + 0, + 0 + ], + [ + 9.925, + -0.183 + ] + ], + "v": [ + [ + 13.645, + -104.996 + ], + [ + 13.645, + -104.904 + ], + [ + -2.832, + -89.166 + ], + [ + -11.679, + -88.983 + ], + [ + -15.236, + -92.323 + ], + [ + -15.705, + -116.387 + ], + [ + -12.288, + -119.864 + ], + [ + -3.441, + -120.001 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 9", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 9, + "ty": "sh", + "ix": 10, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 1.872, + -0.549 + ], + [ + -0.561, + -1.83 + ], + [ + 0, + 0 + ], + [ + -1.872, + 0.549 + ], + [ + 0.562, + 1.83 + ] + ], + "o": [ + [ + -0.562, + -1.83 + ], + [ + -1.872, + 0.549 + ], + [ + 0, + 0 + ], + [ + 0.562, + 1.83 + ], + [ + 1.873, + -0.549 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + -29.888, + -113.185 + ], + [ + -34.195, + -115.472 + ], + [ + -36.536, + -111.263 + ], + [ + -29.467, + -87.657 + ], + [ + -25.161, + -85.369 + ], + [ + -22.82, + -89.578 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 10", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 10, + "ty": "sh", + "ix": 11, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.467, + -0.32 + ], + [ + 0, + 0 + ], + [ + -1.638, + 0.961 + ], + [ + 0, + 0 + ], + [ + 0.188, + 1.83 + ], + [ + 0, + 0 + ], + [ + 0.281, + 0.458 + ], + [ + 1.638, + -0.915 + ], + [ + -0.188, + -1.143 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.545, + -0.869 + ], + [ + -0.983, + -1.647 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 1.497, + 1.099 + ], + [ + 0, + 0 + ], + [ + 1.639, + -0.915 + ], + [ + 0, + 0 + ], + [ + -0.047, + -0.411 + ], + [ + -0.936, + -1.601 + ], + [ + -1.452, + 0.823 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.171, + -0.915 + ], + [ + -1.685, + 0.961 + ], + [ + 0.281, + 0.595 + ] + ], + "v": [ + [ + -70.521, + -93.238 + ], + [ + -49.502, + -77.409 + ], + [ + -44.728, + -76.997 + ], + [ + -44.353, + -77.226 + ], + [ + -42.294, + -81.48 + ], + [ + -45.57, + -107.466 + ], + [ + -46.038, + -108.93 + ], + [ + -50.672, + -110.119 + ], + [ + -52.451, + -106.643 + ], + [ + -49.128, + -85.232 + ], + [ + -66.12, + -98.728 + ], + [ + -70.38, + -99.094 + ], + [ + -71.691, + -94.519 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 11", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 11, + "ty": "sh", + "ix": 12, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 4.026, + 3.523 + ], + [ + 0, + 0 + ], + [ + 3.698, + -4.071 + ], + [ + -4.025, + -3.522 + ], + [ + 0, + 0 + ], + [ + -3.698, + 4.072 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -4.026, + -3.523 + ], + [ + -3.698, + 4.072 + ], + [ + 0, + 0 + ], + [ + 4.026, + 3.523 + ], + [ + 3.745, + -4.117 + ] + ], + "v": [ + [ + -73.095, + -76.448 + ], + [ + -73.142, + -76.494 + ], + [ + -86.904, + -75.991 + ], + [ + -85.875, + -62.678 + ], + [ + -85.828, + -62.632 + ], + [ + -72.065, + -63.135 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 12", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 12, + "ty": "sh", + "ix": 13, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 6.506, + -7.137 + ], + [ + 6.741, + 5.856 + ], + [ + 0, + 0 + ], + [ + -6.507, + 7.091 + ], + [ + -6.741, + -5.856 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -6.46, + 7.091 + ], + [ + 0, + 0 + ], + [ + -6.694, + -5.856 + ], + [ + 6.506, + -7.091 + ], + [ + 0, + 0 + ], + [ + 6.694, + 5.81 + ] + ], + "v": [ + [ + -67.337, + -58.926 + ], + [ + -90.602, + -57.279 + ], + [ + -90.649, + -57.325 + ], + [ + -91.632, + -80.199 + ], + [ + -68.367, + -81.846 + ], + [ + -68.32, + -81.801 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 13", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 13, + "ty": "sh", + "ix": 14, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -8.332, + -3.248 + ], + [ + 0, + 0 + ], + [ + -3.418, + 8.463 + ], + [ + 1.217, + 3.477 + ], + [ + 0.982, + 0.412 + ], + [ + 0.656, + -1.601 + ], + [ + -0.235, + -0.64 + ], + [ + 1.077, + -2.699 + ], + [ + 5.009, + 1.922 + ], + [ + 0, + 0 + ], + [ + -1.966, + 4.85 + ], + [ + -2.06, + 1.236 + ], + [ + -0.375, + 0.869 + ], + [ + 1.732, + 0.686 + ], + [ + 0.749, + -0.458 + ], + [ + 1.779, + -4.301 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 8.426, + 3.248 + ], + [ + 1.872, + -4.575 + ], + [ + -0.281, + -0.778 + ], + [ + -1.639, + -0.64 + ], + [ + -0.281, + 0.732 + ], + [ + 0.749, + 2.379 + ], + [ + -2.012, + 4.896 + ], + [ + 0, + 0 + ], + [ + -5.009, + -1.968 + ], + [ + 0.936, + -2.241 + ], + [ + 0.468, + -0.32 + ], + [ + 0.702, + -1.739 + ], + [ + -1.124, + -0.457 + ], + [ + -2.762, + 1.692 + ], + [ + -3.651, + 8.829 + ] + ], + "v": [ + [ + -104.365, + -25.575 + ], + [ + -104.271, + -25.529 + ], + [ + -83.206, + -34.404 + ], + [ + -82.738, + -46.025 + ], + [ + -84.61, + -47.992 + ], + [ + -88.777, + -46.208 + ], + [ + -88.823, + -44.058 + ], + [ + -89.058, + -36.921 + ], + [ + -101.65, + -32.163 + ], + [ + -101.743, + -32.208 + ], + [ + -107.501, + -44.058 + ], + [ + -103.007, + -49.09 + ], + [ + -101.603, + -50.737 + ], + [ + -103.475, + -55.083 + ], + [ + -106.518, + -54.854 + ], + [ + -113.399, + -46.436 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 14", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 14, + "ty": "sh", + "ix": 15, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.59, + 0.595 + ], + [ + 0.609, + -1.555 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.592, + 0.641 + ], + [ + 0.608, + -1.556 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.592, + 0.64 + ], + [ + 0.607, + -1.556 + ], + [ + 0, + 0 + ], + [ + -1.778, + -0.686 + ], + [ + 0, + 0 + ], + [ + -0.702, + 1.738 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.592, + -0.595 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.608, + -1.556 + ], + [ + -1.59, + -0.594 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.608, + -1.555 + ], + [ + -1.591, + -0.594 + ], + [ + 0, + 0 + ], + [ + -0.702, + 1.784 + ], + [ + 0, + 0 + ], + [ + 1.826, + 0.686 + ], + [ + 0, + 0 + ], + [ + 0.655, + -1.601 + ] + ], + "v": [ + [ + 116.865, + 30.651 + ], + [ + 112.838, + 32.389 + ], + [ + 107.642, + 45.428 + ], + [ + 101.463, + 43.095 + ], + [ + 105.817, + 32.115 + ], + [ + 104.084, + 28.18 + ], + [ + 100.059, + 29.919 + ], + [ + 95.705, + 40.899 + ], + [ + 89.76, + 38.611 + ], + [ + 94.863, + 25.801 + ], + [ + 93.13, + 21.867 + ], + [ + 89.106, + 23.606 + ], + [ + 82.739, + 39.526 + ], + [ + 84.704, + 43.918 + ], + [ + 107.642, + 52.656 + ], + [ + 112.136, + 50.735 + ], + [ + 118.549, + 34.585 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 15", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 15, + "ty": "sh", + "ix": 16, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.359, + 1.052 + ], + [ + 1.124, + -1.327 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.358, + 1.098 + ], + [ + 1.124, + -1.326 + ], + [ + 0, + 0 + ], + [ + -1.498, + -1.191 + ], + [ + 0, + 0 + ], + [ + -1.217, + 1.464 + ], + [ + 1.498, + 1.19 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -1.357, + -1.098 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.124, + -1.327 + ], + [ + -1.357, + -1.098 + ], + [ + 0, + 0 + ], + [ + -1.218, + 1.464 + ], + [ + 0, + 0 + ], + [ + 1.498, + 1.19 + ], + [ + 1.216, + -1.464 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.123, + -1.327 + ] + ], + "v": [ + [ + 91.164, + 57.506 + ], + [ + 86.717, + 57.963 + ], + [ + 79.04, + 67.204 + ], + [ + 73.798, + 63.087 + ], + [ + 82.739, + 52.29 + ], + [ + 82.27, + 47.944 + ], + [ + 77.824, + 48.401 + ], + [ + 66.777, + 61.806 + ], + [ + 67.291, + 66.565 + ], + [ + 86.624, + 81.844 + ], + [ + 91.493, + 81.341 + ], + [ + 90.977, + 76.583 + ], + [ + 83.956, + 71.047 + ], + [ + 91.633, + 61.806 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 16", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 16, + "ty": "sh", + "ix": 17, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 65.607, + 86.373 + ], + [ + 56.151, + 80.38 + ], + [ + 58.398, + 91.223 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 17", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 17, + "ty": "sh", + "ix": 18, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.233, + -0.366 + ], + [ + 1.545, + -1.007 + ], + [ + 1.358, + 0.824 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 1.216, + -0.823 + ], + [ + 1.031, + 1.464 + ], + [ + 0.093, + 0.503 + ], + [ + 0, + 0 + ], + [ + -1.593, + 1.007 + ], + [ + 0, + 0 + ], + [ + -1.592, + -0.961 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 1.03, + 1.51 + ], + [ + -1.357, + 0.869 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.28, + 1.419 + ], + [ + -1.499, + 1.007 + ], + [ + -0.281, + -0.412 + ], + [ + 0, + 0 + ], + [ + -0.329, + -1.784 + ], + [ + 0, + 0 + ], + [ + 1.546, + -1.053 + ], + [ + 0, + 0 + ], + [ + 0.516, + 0.275 + ] + ], + "v": [ + [ + 80.632, + 88.34 + ], + [ + 79.789, + 92.824 + ], + [ + 75.67, + 92.732 + ], + [ + 71.129, + 89.897 + ], + [ + 59.662, + 97.536 + ], + [ + 60.738, + 102.934 + ], + [ + 59.287, + 106.457 + ], + [ + 54.792, + 105.588 + ], + [ + 54.278, + 104.17 + ], + [ + 49.41, + 78.047 + ], + [ + 51.236, + 73.609 + ], + [ + 51.562, + 73.381 + ], + [ + 56.431, + 73.381 + ], + [ + 79.508, + 87.425 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 18", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 18, + "ty": "sh", + "ix": 19, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 6.6, + -0.321 + ], + [ + 0.608, + 1.922 + ], + [ + 0, + 0 + ], + [ + -2.527, + 0.778 + ], + [ + -2.621, + -0.595 + ], + [ + -0.657, + 0.183 + ], + [ + 0.516, + 1.693 + ], + [ + 0.891, + 0.183 + ], + [ + 3.652, + -1.144 + ], + [ + -1.686, + -5.353 + ], + [ + 0, + 0 + ], + [ + -6.554, + 0.366 + ], + [ + -0.516, + -1.601 + ], + [ + 0, + 0 + ], + [ + 2.714, + -0.823 + ], + [ + 2.81, + 0.961 + ], + [ + 0.841, + -0.275 + ], + [ + -0.514, + -1.692 + ], + [ + -0.889, + -0.275 + ], + [ + -3.978, + 1.19 + ], + [ + 1.872, + 5.856 + ] + ], + "o": [ + [ + -1.639, + -5.124 + ], + [ + -5.617, + 0.274 + ], + [ + 0, + 0 + ], + [ + -0.468, + -1.418 + ], + [ + 2.06, + -0.64 + ], + [ + 0.61, + 0.137 + ], + [ + 1.731, + -0.503 + ], + [ + -0.421, + -1.281 + ], + [ + -3.229, + -0.87 + ], + [ + -6.131, + 1.875 + ], + [ + 0, + 0 + ], + [ + 1.873, + 5.856 + ], + [ + 5.429, + -0.274 + ], + [ + 0, + 0 + ], + [ + 0.561, + 1.738 + ], + [ + -2.95, + 0.869 + ], + [ + -0.514, + -0.183 + ], + [ + -1.733, + 0.503 + ], + [ + 0.328, + 1.007 + ], + [ + 4.12, + 1.327 + ], + [ + 6.507, + -1.967 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 45.899, + 102.34 + ], + [ + 33.54, + 96.439 + ], + [ + 25.817, + 94.562 + ], + [ + 25.769, + 94.471 + ], + [ + 28.812, + 90.719 + ], + [ + 35.787, + 90.765 + ], + [ + 37.614, + 90.719 + ], + [ + 39.766, + 86.785 + ], + [ + 37.472, + 84.681 + ], + [ + 27.08, + 85.001 + ], + [ + 19.357, + 97.079 + ], + [ + 19.404, + 97.17 + ], + [ + 32.277, + 103.117 + ], + [ + 39.533, + 104.993 + ], + [ + 39.579, + 105.085 + ], + [ + 36.116, + 109.202 + ], + [ + 27.548, + 108.882 + ], + [ + 25.49, + 108.882 + ], + [ + 23.335, + 112.816 + ], + [ + 25.348, + 114.875 + ], + [ + 37.8, + 114.966 + ], + [ + 45.946, + 102.477 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 19", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 19, + "ty": "sh", + "ix": 20, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 7.959, + 0.183 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -0.187, + 6.817 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 7.958, + 0.183 + ], + [ + 0, + 0 + ], + [ + 0.141, + -6.817 + ] + ], + "v": [ + [ + -4.143, + 92.412 + ], + [ + -11.539, + 92.229 + ], + [ + -12.147, + 116.613 + ], + [ + -4.751, + 116.796 + ], + [ + 8.637, + 104.993 + ], + [ + 8.637, + 104.902 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 20", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 20, + "ty": "sh", + "ix": 21, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.235, + -8.647 + ], + [ + 0, + 0 + ], + [ + 9.925, + 0.229 + ], + [ + 0, + 0 + ], + [ + 0, + 0.961 + ], + [ + 0, + 0 + ], + [ + -0.983, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -0.234, + 8.692 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.046 + ], + [ + 0, + 0 + ], + [ + 0.048, + -0.961 + ], + [ + 0, + 0 + ], + [ + 9.924, + 0.275 + ] + ], + "v": [ + [ + 12.288, + 104.902 + ], + [ + 12.288, + 104.993 + ], + [ + -4.892, + 119.999 + ], + [ + -14.067, + 119.77 + ], + [ + -15.798, + 117.986 + ], + [ + -15.097, + 90.674 + ], + [ + -13.271, + 88.935 + ], + [ + -4.096, + 89.164 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 21", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 21, + "ty": "sh", + "ix": 22, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0.936, + 0.275 + ], + [ + 0.28, + -0.961 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.229 + ], + [ + -0.281, + 0.961 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -0.89, + -0.274 + ], + [ + 0, + 0 + ], + [ + -0.281, + 0.915 + ], + [ + 0.936, + 0.275 + ], + [ + 0, + 0 + ], + [ + 0.233, + -0.869 + ] + ], + "v": [ + [ + -24.458, + 85.641 + ], + [ + -26.658, + 86.877 + ], + [ + -34.429, + 113.594 + ], + [ + -33.212, + 115.744 + ], + [ + -30.965, + 114.509 + ], + [ + -23.194, + 87.791 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 22", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 22, + "ty": "sh", + "ix": 23, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -0.141, + 0.229 + ], + [ + 0.843, + 0.457 + ], + [ + 0.608, + -0.412 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.796, + 0.457 + ], + [ + 0.421, + -0.732 + ], + [ + 0, + -0.274 + ], + [ + 0, + 0 + ], + [ + -0.936, + -0.503 + ], + [ + 0, + 0 + ], + [ + -0.796, + 0.549 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0.467, + -0.777 + ], + [ + -0.702, + -0.412 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.093, + -0.823 + ], + [ + -0.842, + -0.504 + ], + [ + -0.14, + 0.275 + ], + [ + 0, + 0 + ], + [ + -0.14, + 0.961 + ], + [ + 0, + 0 + ], + [ + 0.889, + 0.503 + ], + [ + 0, + 0 + ], + [ + 0.14, + -0.275 + ] + ], + "v": [ + [ + -33.071, + 85.824 + ], + [ + -33.727, + 83.537 + ], + [ + -35.88, + 83.766 + ], + [ + -58.443, + 100.693 + ], + [ + -54.885, + 73.243 + ], + [ + -55.822, + 71.185 + ], + [ + -58.256, + 71.779 + ], + [ + -58.49, + 72.557 + ], + [ + -61.907, + 102.294 + ], + [ + -60.831, + 104.581 + ], + [ + -60.69, + 104.673 + ], + [ + -58.162, + 104.444 + ], + [ + -33.493, + 86.465 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 23", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 23, + "ty": "sh", + "ix": 24, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 4.775, + 5.307 + ], + [ + 5.383, + -4.62 + ], + [ + 0, + 0 + ], + [ + -4.775, + -5.261 + ], + [ + -5.384, + 4.621 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -4.775, + -5.307 + ], + [ + 0, + 0 + ], + [ + -5.384, + 4.621 + ], + [ + 4.775, + 5.307 + ], + [ + 0, + 0 + ], + [ + 5.384, + -4.621 + ] + ], + "v": [ + [ + -70.146, + 60.754 + ], + [ + -88.028, + 60.067 + ], + [ + -88.074, + 60.113 + ], + [ + -89.619, + 77.635 + ], + [ + -71.737, + 78.321 + ], + [ + -71.691, + 78.276 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 24", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 24, + "ty": "sh", + "ix": 25, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -6.366, + -7.045 + ], + [ + 6.507, + -5.581 + ], + [ + 0, + 0 + ], + [ + 6.366, + 7.045 + ], + [ + -6.507, + 5.627 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 6.366, + 7.045 + ], + [ + 0, + 0 + ], + [ + -6.506, + 5.627 + ], + [ + -6.366, + -7.045 + ], + [ + 0, + 0 + ], + [ + 6.553, + -5.581 + ] + ], + "v": [ + [ + -67.618, + 58.695 + ], + [ + -69.163, + 80.929 + ], + [ + -69.21, + 80.975 + ], + [ + -92.147, + 79.694 + ], + [ + -90.602, + 57.414 + ], + [ + -90.555, + 57.368 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 25", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 25, + "ty": "sh", + "ix": 26, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -2.528, + -6.314 + ], + [ + -3.324, + -1.555 + ], + [ + -0.187, + -0.412 + ], + [ + 0.843, + -0.32 + ], + [ + 0.374, + 0.182 + ], + [ + 1.873, + 4.712 + ], + [ + -8.426, + 3.249 + ], + [ + 0, + 0 + ], + [ + -3.418, + -8.463 + ], + [ + 1.17, + -3.524 + ], + [ + 0.608, + -0.228 + ], + [ + 0.327, + 0.869 + ], + [ + -0.094, + 0.274 + ], + [ + 1.451, + 3.523 + ], + [ + 6.741, + -2.608 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 1.451, + 3.568 + ], + [ + 0.327, + 0.138 + ], + [ + 0.327, + 0.823 + ], + [ + -0.515, + 0.183 + ], + [ + -3.792, + -1.831 + ], + [ + -3.37, + -8.281 + ], + [ + 0, + 0 + ], + [ + 8.285, + -3.203 + ], + [ + 1.872, + 4.621 + ], + [ + -0.14, + 0.456 + ], + [ + -0.89, + 0.321 + ], + [ + -0.187, + -0.458 + ], + [ + 1.123, + -2.974 + ], + [ + -2.575, + -6.359 + ], + [ + 0, + 0 + ], + [ + -6.788, + 2.562 + ] + ], + "v": [ + [ + -110.45, + 45.291 + ], + [ + -103.428, + 52.427 + ], + [ + -102.539, + 53.297 + ], + [ + -103.522, + 55.447 + ], + [ + -104.926, + 55.356 + ], + [ + -113.54, + 46.389 + ], + [ + -104.271, + 26.167 + ], + [ + -104.177, + 26.122 + ], + [ + -83.112, + 34.768 + ], + [ + -82.785, + 46.481 + ], + [ + -83.861, + 47.669 + ], + [ + -86.155, + 46.663 + ], + [ + -86.202, + 45.474 + ], + [ + -86.202, + 35.958 + ], + [ + -102.726, + 29.507 + ], + [ + -102.82, + 29.553 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 26", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0.086000001197, + 0.086000001197, + 0.086000001197, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 120, + 120 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 30, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + } + ] + } + ], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Spinner_Inside2 Outlines", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 0, + "k": 0, + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 130, + 130, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 1.685, + 0 + ], + [ + 0, + 0 + ], + [ + 1.17, + 1.235 + ], + [ + 0, + 0 + ], + [ + -2.575, + 2.333 + ], + [ + -2.388, + -2.516 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -2.48, + -2.379 + ], + [ + 2.435, + -2.425 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + -1.732, + -0.046 + ], + [ + 0, + 0 + ], + [ + -2.387, + -2.47 + ], + [ + 2.528, + -2.334 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 2.433, + -2.425 + ], + [ + 2.482, + 2.379 + ], + [ + 0, + 0 + ], + [ + -1.217, + 1.143 + ] + ], + "v": [ + [ + -21.112, + 38.727 + ], + [ + -21.206, + 38.727 + ], + [ + -25.699, + 36.76 + ], + [ + -48.918, + 12.467 + ], + [ + -48.59, + 3.775 + ], + [ + -39.696, + 4.095 + ], + [ + -20.925, + 23.721 + ], + [ + 39.93, + -36.301 + ], + [ + 48.823, + -36.347 + ], + [ + 48.87, + -27.656 + ], + [ + -16.618, + 36.943 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0, + 0.501999978458, + 0.090000002992, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 138.056, + 111.632 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 1", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + }, + { + "ty": "gr", + "it": [ + { + "ind": 0, + "ty": "sh", + "ix": 1, + "ks": { + "a": 0, + "k": { + "i": [ + [ + -1.731, + 2.974 + ], + [ + 0, + 0 + ], + [ + 3.511, + 0 + ], + [ + 0, + 0 + ], + [ + -1.733, + -2.927 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0, + 0 + ], + [ + 1.732, + -2.973 + ], + [ + 0, + 0 + ], + [ + -3.464, + 0 + ], + [ + 0, + 0 + ], + [ + 1.778, + 2.974 + ] + ], + "v": [ + [ + 42.528, + 58.17 + ], + [ + 45.946, + 52.359 + ], + [ + 42.012, + 45.726 + ], + [ + 35.178, + 45.726 + ], + [ + 31.247, + 52.359 + ], + [ + 34.665, + 58.17 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 1", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 1, + "ty": "sh", + "ix": 2, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + -4.072, + 3.705 + ], + [ + -3.792, + -3.934 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0.655, + -2.607 + ], + [ + 0, + 0 + ], + [ + 1.639, + 0.412 + ], + [ + 0, + 0 + ], + [ + -0.421, + 1.601 + ], + [ + 0, + 0 + ], + [ + 1.966, + 0 + ], + [ + 0, + 0 + ], + [ + 0.562, + -0.458 + ], + [ + 0, + 0 + ], + [ + -1.03, + -2.333 + ], + [ + 0, + 0 + ], + [ + -4.727, + 2.837 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + -3.791, + -3.98 + ], + [ + 4.073, + -3.706 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + -1.31, + -2.379 + ], + [ + 0, + 0 + ], + [ + -0.421, + 1.602 + ], + [ + 0, + 0 + ], + [ + -1.638, + -0.412 + ], + [ + 0, + 0 + ], + [ + 0.468, + -1.875 + ], + [ + 0, + 0 + ], + [ + -0.702, + 0 + ], + [ + 0, + 0 + ], + [ + -2.013, + 1.693 + ], + [ + 0, + 0 + ], + [ + 2.153, + 4.986 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + -33.4, + 6.656 + ], + [ + -32.885, + -7.251 + ], + [ + -18.654, + -6.794 + ], + [ + -2.598, + 10.042 + ], + [ + 47.021, + -38.91 + ], + [ + 35.975, + -58.765 + ], + [ + 30.405, + -58.079 + ], + [ + 25.958, + -40.557 + ], + [ + 22.306, + -38.407 + ], + [ + 6.765, + -42.158 + ], + [ + 4.564, + -45.726 + ], + [ + 6.062, + -51.674 + ], + [ + 3.114, + -55.333 + ], + [ + -12.241, + -55.333 + ], + [ + -14.206, + -54.601 + ], + [ + -66.4, + -10.866 + ], + [ + -68.04, + -4.095 + ], + [ + -54.37, + 27.381 + ], + [ + -41.311, + 31.452 + ], + [ + -21.229, + 19.42 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 2", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ind": 2, + "ty": "sh", + "ix": 3, + "ks": { + "a": 0, + "k": { + "i": [ + [ + 0, + 0 + ], + [ + 0.842, + -1.693 + ], + [ + 0, + 0 + ], + [ + 2.294, + 0 + ], + [ + 0, + 0 + ], + [ + 1.123, + 1.189 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "o": [ + [ + 0.935, + 1.647 + ], + [ + 0, + 0 + ], + [ + -0.982, + 2.058 + ], + [ + 0, + 0 + ], + [ + -1.686, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ], + [ + 0, + 0 + ] + ], + "v": [ + [ + 68.088, + -0.984 + ], + [ + 68.228, + 4.369 + ], + [ + 51.516, + 38.681 + ], + [ + 46.087, + 42.066 + ], + [ + 30.546, + 42.066 + ], + [ + 26.145, + 40.191 + ], + [ + 11.166, + 24.499 + ], + [ + 57.088, + -20.793 + ] + ], + "c": true + }, + "ix": 2 + }, + "nm": "Path 3", + "mn": "ADBE Vector Shape - Group", + "hd": false + }, + { + "ty": "mm", + "mm": 1, + "nm": "Merge Paths 1", + "mn": "ADBE Vector Filter - Merge", + "hd": false + }, + { + "ty": "fl", + "c": { + "a": 0, + "k": [ + 0, + 0.635000011968, + 0.097999999102, + 1 + ], + "ix": 4 + }, + "o": { + "a": 0, + "k": 100, + "ix": 5 + }, + "r": 1, + "bm": 0, + "nm": "Fill 1", + "mn": "ADBE Vector Graphic - Fill", + "hd": false + }, + { + "ty": "tr", + "p": { + "a": 0, + "k": [ + 119.775, + 119.958 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 0, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100 + ], + "ix": 3 + }, + "r": { + "a": 0, + "k": 0, + "ix": 6 + }, + "o": { + "a": 0, + "k": 100, + "ix": 7 + }, + "sk": { + "a": 0, + "k": 0, + "ix": 4 + }, + "sa": { + "a": 0, + "k": 0, + "ix": 5 + }, + "nm": "Transform" + } + ], + "nm": "Group 2", + "np": 5, + "cix": 2, + "bm": 0, + "ix": 2, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + }, + { + "ddd": 0, + "ind": 2, + "ty": 0, + "nm": "Spinner_Outside Outlines Comp 1", + "refId": "comp_0", + "sr": 1, + "ks": { + "o": { + "a": 0, + "k": 100, + "ix": 11 + }, + "r": { + "a": 1, + "k": [ + { + "i": { + "x": [ + 0.833 + ], + "y": [ + 0.833 + ] + }, + "o": { + "x": [ + 0.167 + ], + "y": [ + 0.167 + ] + }, + "t": 0, + "s": [ + 0 + ] + }, + { + "t": 599, + "s": [ + 360 + ] + } + ], + "ix": 10 + }, + "p": { + "a": 0, + "k": [ + 130, + 130, + 0 + ], + "ix": 2 + }, + "a": { + "a": 0, + "k": [ + 120, + 120, + 0 + ], + "ix": 1 + }, + "s": { + "a": 0, + "k": [ + 100, + 100, + 100 + ], + "ix": 6 + } + }, + "ao": 0, + "w": 240, + "h": 240, + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} \ No newline at end of file diff --git a/app/src/main/assets/spinner_home_upload_complete.json b/app/src/main/assets/spinner_home_upload_complete.json new file mode 100644 index 0000000..2edead2 --- /dev/null +++ b/app/src/main/assets/spinner_home_upload_complete.json @@ -0,0 +1 @@ +{"v":"5.6.9","fr":30,"ip":0,"op":600,"w":260,"h":260,"nm":"Logo_Inside","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Logo_Outside Outlines 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":599,"s":[-360]}],"ix":10},"p":{"a":0,"k":[11.5,120,0],"ix":2},"a":{"a":0,"k":[11.5,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.732,0],[0,1.692],[0,0],[0,0],[0,1.647],[1.685,0],[0,0],[0,0],[1.732,0],[0,-1.739],[0,0],[0,0],[0,-1.647],[-1.685,0],[0,0]],"o":[[0,1.737],[1.733,0],[0,0],[0,0],[1.732,0],[0,-1.692],[0,0],[0,0],[0,-1.739],[-1.732,0],[0,0],[0,0],[-1.732,0],[0,1.693],[0,0],[0,0]],"v":[[-111.574,8.189],[-108.391,11.299],[-105.207,8.189],[-105.207,3.11],[-99.871,3.11],[-96.781,0.09],[-99.871,-2.929],[-105.161,-2.929],[-105.161,-8.007],[-108.344,-11.118],[-111.574,-8.007],[-111.574,-2.929],[-116.91,-2.929],[-120,0.09],[-116.91,3.11],[-111.574,3.11]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[120,120],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Logo_Outside Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":599,"s":[-360]}],"ix":10},"p":{"a":0,"k":[228,120,0],"ix":2},"a":{"a":0,"k":[228,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.779,0],[0,-1.693],[0,0],[0,0],[0,-1.647],[-1.685,0],[0,0],[0,0],[-1.731,0],[0,1.693],[0,0],[0,0],[0,1.647],[1.685,0],[0,0],[0,0]],"o":[[-1.778,0],[0,0],[0,0],[-1.732,0],[0,1.692],[0,0],[0,0],[0,1.739],[1.779,0],[0,0],[0,0],[1.731,0],[0,-1.693],[0,0],[0,0],[0,-1.693]],"v":[[108.391,-11.164],[105.208,-8.053],[105.208,-2.975],[99.871,-2.975],[96.783,0.045],[99.871,3.065],[105.208,3.065],[105.208,8.142],[108.391,11.253],[111.575,8.142],[111.575,3.065],[116.911,3.065],[120,0.045],[116.911,-2.975],[111.575,-2.975],[111.575,-8.053]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[120,120],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Logo_Outside Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":360,"ix":10},"p":{"a":0,"k":[120,120,0],"ix":2},"a":{"a":0,"k":[120,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.327,0.823],[0,0],[0.935,-0.32],[0,0],[-0.328,-0.87],[0,0],[-0.89,0.275],[0.282,0.869],[0,0],[0,0],[0,0],[-0.891,0.275],[0.281,0.869],[0,0],[0,0],[0,0],[-0.889,0.275]],"o":[[0,0],[-0.328,-0.869],[0,0],[-0.936,0.32],[0,0],[0.328,0.823],[0.843,-0.32],[0,0],[0,0],[0,0],[0.328,0.823],[0.795,-0.274],[0,0],[0,0],[0,0],[0.328,0.823],[0.703,-0.366]],"v":[[119.439,-31.705],[112.652,-49.685],[110.358,-50.691],[84.143,-41.221],[83.067,-38.979],[89.948,-20.771],[92.054,-19.811],[93.037,-21.869],[86.811,-38.385],[97.157,-42.136],[102.633,-27.679],[104.741,-26.719],[105.723,-28.777],[100.246,-43.234],[110.358,-46.894],[116.537,-30.561],[118.642,-29.601]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.561,-0.778],[-0.842,0.549],[0,0],[0,0],[-0.702,0.503],[0.515,0.687],[0,0],[0,0],[0,0],[-0.749,0.503],[0.516,0.686],[0,0],[0.795,-0.595],[0,0]],"o":[[0.563,0.778],[0,0],[0,0],[0.516,0.732],[0.749,-0.504],[0,0],[0,0],[0,0],[0.516,0.732],[0.749,-0.504],[0,0],[-0.563,-0.732],[0,0],[-0.843,0.458]],"v":[[69.678,-58.423],[72.206,-58.011],[82.13,-64.919],[91.258,-52.43],[93.505,-52.063],[93.879,-54.26],[84.751,-66.749],[93.926,-73.154],[104.225,-59.063],[106.518,-58.697],[106.893,-60.893],[95.566,-76.402],[93.084,-76.768],[70.147,-60.756]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[54.606,-85.781],[66.402,-77.5],[69.959,-94.427]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[-0.374,0.183],[0,0],[-0.936,-0.641],[0,0],[0.235,-1.007],[0,0],[0.14,-0.184],[0.749,0.549],[-0.189,0.777],[0,0],[0,0],[0,0],[0.655,0.458],[-0.516,0.686]],"o":[[0,0],[0.938,-0.549],[0,0],[0.888,0.641],[0,0],[-0.094,0.321],[-0.562,0.731],[-0.702,-0.504],[0,0],[0,0],[0,0],[-0.702,0.412],[-0.749,-0.503],[0.093,-0.183]],"v":[[42.856,-82.944],[69.631,-97.813],[72.393,-97.767],[72.535,-97.676],[73.423,-95.159],[67.478,-65.697],[67.151,-64.873],[64.763,-64.507],[64.109,-66.566],[65.7,-74.206],[51.657,-84.088],[44.681,-80.154],[42.576,-80.154],[42.201,-82.35]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[-4.401,-1.327],[-1.637,5.032],[0,0],[6.227,3.523],[-0.89,2.791],[0,0],[-3.933,-1.19],[-1.967,-2.562],[-0.375,-0.137],[-0.281,0.869],[0.234,0.366],[3.978,1.236],[1.451,-4.621],[0,0],[-6.46,-3.568],[0.889,-2.745],[0,0],[4.074,1.236],[2.059,3.202],[0.421,0.137],[0.28,-0.915],[-0.28,-0.366]],"o":[[5.992,1.83],[0,0],[1.451,-4.484],[-6.179,-3.431],[0,0],[0.841,-2.654],[2.807,0.869],[0.235,0.32],[0.89,0.275],[0.188,-0.641],[-2.152,-2.79],[-5.711,-1.738],[0,0],[-1.545,4.85],[5.899,3.248],[0,0],[-0.936,2.882],[-3.837,-1.189],[-0.141,-0.275],[-0.891,-0.275],[-0.189,0.549],[2.388,3.706]],"v":[[28.532,-84.454],[41.498,-89.623],[41.545,-89.715],[34.429,-101.061],[28.111,-109.296],[28.158,-109.387],[36.116,-112.178],[43.09,-107.237],[43.979,-106.643],[46.132,-107.74],[45.851,-109.296],[37.192,-115.152],[24.741,-110.165],[24.694,-110.074],[32.089,-98.499],[38.128,-90.493],[38.081,-90.401],[29.748,-87.474],[21.37,-93.878],[20.481,-94.564],[18.328,-93.421],[18.561,-91.957]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[0.094,5.49],[0,0],[5.664,-0.137],[0,0],[0,0],[0,0]],"o":[[0,0],[-0.094,-5.444],[0,0],[0,0],[0,0],[5.664,-0.092]],"v":[[6.39,-104.675],[6.39,-104.767],[-3.299,-113.871],[-8.683,-113.779],[-8.309,-95.205],[-2.925,-95.296]],"c":true},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[-0.187,-8.646],[0,0],[9.924,-0.183],[0,0],[0.046,1.922],[0,0],[-1.966,0.046],[0,0]],"o":[[0,0],[0.188,8.693],[0,0],[-1.92,0.046],[0,0],[-0.047,-1.876],[0,0],[9.925,-0.183]],"v":[[13.645,-104.996],[13.645,-104.904],[-2.832,-89.166],[-11.679,-88.983],[-15.236,-92.323],[-15.705,-116.387],[-12.288,-119.864],[-3.441,-120.001]],"c":true},"ix":2},"nm":"Path 9","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[0,0],[1.872,-0.549],[-0.561,-1.83],[0,0],[-1.872,0.549],[0.562,1.83]],"o":[[-0.562,-1.83],[-1.872,0.549],[0,0],[0.562,1.83],[1.873,-0.549],[0,0]],"v":[[-29.888,-113.185],[-34.195,-115.472],[-36.536,-111.263],[-29.467,-87.657],[-25.161,-85.369],[-22.82,-89.578]],"c":true},"ix":2},"nm":"Path 10","mn":"ADBE Vector Shape - Group","hd":false},{"ind":8,"ty":"sh","ix":9,"ks":{"a":0,"k":{"i":[[-0.467,-0.32],[0,0],[-1.638,0.961],[0,0],[0.188,1.83],[0,0],[0.281,0.458],[1.638,-0.915],[-0.188,-1.143],[0,0],[0,0],[1.545,-0.869],[-0.983,-1.647]],"o":[[0,0],[1.497,1.099],[0,0],[1.639,-0.915],[0,0],[-0.047,-0.411],[-0.936,-1.601],[-1.452,0.823],[0,0],[0,0],[-1.171,-0.915],[-1.685,0.961],[0.281,0.595]],"v":[[-70.521,-93.238],[-49.502,-77.409],[-44.728,-76.997],[-44.353,-77.226],[-42.294,-81.48],[-45.57,-107.466],[-46.038,-108.93],[-50.672,-110.119],[-52.451,-106.643],[-49.128,-85.232],[-66.12,-98.728],[-70.38,-99.094],[-71.691,-94.519]],"c":true},"ix":2},"nm":"Path 11","mn":"ADBE Vector Shape - Group","hd":false},{"ind":9,"ty":"sh","ix":10,"ks":{"a":0,"k":{"i":[[4.026,3.523],[0,0],[3.698,-4.071],[-4.025,-3.522],[0,0],[-3.698,4.072]],"o":[[0,0],[-4.026,-3.523],[-3.698,4.072],[0,0],[4.026,3.523],[3.745,-4.117]],"v":[[-73.095,-76.448],[-73.142,-76.494],[-86.904,-75.991],[-85.875,-62.678],[-85.828,-62.632],[-72.065,-63.135]],"c":true},"ix":2},"nm":"Path 12","mn":"ADBE Vector Shape - Group","hd":false},{"ind":10,"ty":"sh","ix":11,"ks":{"a":0,"k":{"i":[[6.506,-7.137],[6.741,5.856],[0,0],[-6.507,7.091],[-6.741,-5.856],[0,0]],"o":[[-6.46,7.091],[0,0],[-6.694,-5.856],[6.506,-7.091],[0,0],[6.694,5.81]],"v":[[-67.337,-58.926],[-90.602,-57.279],[-90.649,-57.325],[-91.632,-80.199],[-68.367,-81.846],[-68.32,-81.801]],"c":true},"ix":2},"nm":"Path 13","mn":"ADBE Vector Shape - Group","hd":false},{"ind":11,"ty":"sh","ix":12,"ks":{"a":0,"k":{"i":[[-8.332,-3.248],[0,0],[-3.418,8.463],[1.217,3.477],[0.982,0.412],[0.656,-1.601],[-0.235,-0.64],[1.077,-2.699],[5.009,1.922],[0,0],[-1.966,4.85],[-2.06,1.236],[-0.375,0.869],[1.732,0.686],[0.749,-0.458],[1.779,-4.301]],"o":[[0,0],[8.426,3.248],[1.872,-4.575],[-0.281,-0.778],[-1.639,-0.64],[-0.281,0.732],[0.749,2.379],[-2.012,4.896],[0,0],[-5.009,-1.968],[0.936,-2.241],[0.468,-0.32],[0.702,-1.739],[-1.124,-0.457],[-2.762,1.692],[-3.651,8.829]],"v":[[-104.365,-25.575],[-104.271,-25.529],[-83.206,-34.404],[-82.738,-46.025],[-84.61,-47.992],[-88.777,-46.208],[-88.823,-44.058],[-89.058,-36.921],[-101.65,-32.163],[-101.743,-32.208],[-107.501,-44.058],[-103.007,-49.09],[-101.603,-50.737],[-103.475,-55.083],[-106.518,-54.854],[-113.399,-46.436]],"c":true},"ix":2},"nm":"Path 14","mn":"ADBE Vector Shape - Group","hd":false},{"ind":12,"ty":"sh","ix":13,"ks":{"a":0,"k":{"i":[[1.59,0.595],[0.609,-1.555],[0,0],[0,0],[0,0],[1.592,0.641],[0.608,-1.556],[0,0],[0,0],[0,0],[1.592,0.64],[0.607,-1.556],[0,0],[-1.778,-0.686],[0,0],[-0.702,1.738],[0,0]],"o":[[-1.592,-0.595],[0,0],[0,0],[0,0],[0.608,-1.556],[-1.59,-0.594],[0,0],[0,0],[0,0],[0.608,-1.555],[-1.591,-0.594],[0,0],[-0.702,1.784],[0,0],[1.826,0.686],[0,0],[0.655,-1.601]],"v":[[116.865,30.651],[112.838,32.389],[107.642,45.428],[101.463,43.095],[105.817,32.115],[104.084,28.18],[100.059,29.919],[95.705,40.899],[89.76,38.611],[94.863,25.801],[93.13,21.867],[89.106,23.606],[82.739,39.526],[84.704,43.918],[107.642,52.656],[112.136,50.735],[118.549,34.585]],"c":true},"ix":2},"nm":"Path 15","mn":"ADBE Vector Shape - Group","hd":false},{"ind":13,"ty":"sh","ix":14,"ks":{"a":0,"k":{"i":[[1.359,1.052],[1.124,-1.327],[0,0],[0,0],[0,0],[1.358,1.098],[1.124,-1.326],[0,0],[-1.498,-1.191],[0,0],[-1.217,1.464],[1.498,1.19],[0,0],[0,0]],"o":[[-1.357,-1.098],[0,0],[0,0],[0,0],[1.124,-1.327],[-1.357,-1.098],[0,0],[-1.218,1.464],[0,0],[1.498,1.19],[1.216,-1.464],[0,0],[0,0],[1.123,-1.327]],"v":[[91.164,57.506],[86.717,57.963],[79.04,67.204],[73.798,63.087],[82.739,52.29],[82.27,47.944],[77.824,48.401],[66.777,61.806],[67.291,66.565],[86.624,81.844],[91.493,81.341],[90.977,76.583],[83.956,71.047],[91.633,61.806]],"c":true},"ix":2},"nm":"Path 16","mn":"ADBE Vector Shape - Group","hd":false},{"ind":14,"ty":"sh","ix":15,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[65.607,86.373],[56.151,80.38],[58.398,91.223]],"c":true},"ix":2},"nm":"Path 17","mn":"ADBE Vector Shape - Group","hd":false},{"ind":15,"ty":"sh","ix":16,"ks":{"a":0,"k":{"i":[[-0.233,-0.366],[1.545,-1.007],[1.358,0.824],[0,0],[0,0],[0,0],[1.216,-0.823],[1.031,1.464],[0.093,0.503],[0,0],[-1.593,1.007],[0,0],[-1.592,-0.961],[0,0]],"o":[[1.03,1.51],[-1.357,0.869],[0,0],[0,0],[0,0],[0.28,1.419],[-1.499,1.007],[-0.281,-0.412],[0,0],[-0.329,-1.784],[0,0],[1.546,-1.053],[0,0],[0.516,0.275]],"v":[[80.632,88.34],[79.789,92.824],[75.67,92.732],[71.129,89.897],[59.662,97.536],[60.738,102.934],[59.287,106.457],[54.792,105.588],[54.278,104.17],[49.41,78.047],[51.236,73.609],[51.562,73.381],[56.431,73.381],[79.508,87.425]],"c":true},"ix":2},"nm":"Path 18","mn":"ADBE Vector Shape - Group","hd":false},{"ind":16,"ty":"sh","ix":17,"ks":{"a":0,"k":{"i":[[0,0],[6.6,-0.321],[0.608,1.922],[0,0],[-2.527,0.778],[-2.621,-0.595],[-0.657,0.183],[0.516,1.693],[0.891,0.183],[3.652,-1.144],[-1.686,-5.353],[0,0],[-6.554,0.366],[-0.516,-1.601],[0,0],[2.714,-0.823],[2.81,0.961],[0.841,-0.275],[-0.514,-1.692],[-0.889,-0.275],[-3.978,1.19],[1.872,5.856]],"o":[[-1.639,-5.124],[-5.617,0.274],[0,0],[-0.468,-1.418],[2.06,-0.64],[0.61,0.137],[1.731,-0.503],[-0.421,-1.281],[-3.229,-0.87],[-6.131,1.875],[0,0],[1.873,5.856],[5.429,-0.274],[0,0],[0.561,1.738],[-2.95,0.869],[-0.514,-0.183],[-1.733,0.503],[0.328,1.007],[4.12,1.327],[6.507,-1.967],[0,0]],"v":[[45.899,102.34],[33.54,96.439],[25.817,94.562],[25.769,94.471],[28.812,90.719],[35.787,90.765],[37.614,90.719],[39.766,86.785],[37.472,84.681],[27.08,85.001],[19.357,97.079],[19.404,97.17],[32.277,103.117],[39.533,104.993],[39.579,105.085],[36.116,109.202],[27.548,108.882],[25.49,108.882],[23.335,112.816],[25.348,114.875],[37.8,114.966],[45.946,102.477]],"c":true},"ix":2},"nm":"Path 19","mn":"ADBE Vector Shape - Group","hd":false},{"ind":17,"ty":"sh","ix":18,"ks":{"a":0,"k":{"i":[[7.959,0.183],[0,0],[0,0],[0,0],[-0.187,6.817],[0,0]],"o":[[0,0],[0,0],[0,0],[7.958,0.183],[0,0],[0.141,-6.817]],"v":[[-4.143,92.412],[-11.539,92.229],[-12.147,116.613],[-4.751,116.796],[8.637,104.993],[8.637,104.902]],"c":true},"ix":2},"nm":"Path 20","mn":"ADBE Vector Shape - Group","hd":false},{"ind":18,"ty":"sh","ix":19,"ks":{"a":0,"k":{"i":[[0.235,-8.647],[0,0],[9.925,0.229],[0,0],[0,0.961],[0,0],[-0.983,0],[0,0]],"o":[[0,0],[-0.234,8.692],[0,0],[-0.936,-0.046],[0,0],[0.048,-0.961],[0,0],[9.924,0.275]],"v":[[12.288,104.902],[12.288,104.993],[-4.892,119.999],[-14.067,119.77],[-15.798,117.986],[-15.097,90.674],[-13.271,88.935],[-4.096,89.164]],"c":true},"ix":2},"nm":"Path 21","mn":"ADBE Vector Shape - Group","hd":false},{"ind":19,"ty":"sh","ix":20,"ks":{"a":0,"k":{"i":[[0.936,0.275],[0.28,-0.961],[0,0],[-0.936,-0.229],[-0.281,0.961],[0,0]],"o":[[-0.89,-0.274],[0,0],[-0.281,0.915],[0.936,0.275],[0,0],[0.233,-0.869]],"v":[[-24.458,85.641],[-26.658,86.877],[-34.429,113.594],[-33.212,115.744],[-30.965,114.509],[-23.194,87.791]],"c":true},"ix":2},"nm":"Path 22","mn":"ADBE Vector Shape - Group","hd":false},{"ind":20,"ty":"sh","ix":21,"ks":{"a":0,"k":{"i":[[-0.141,0.229],[0.843,0.457],[0.608,-0.412],[0,0],[0,0],[0.796,0.457],[0.421,-0.732],[0,-0.274],[0,0],[-0.936,-0.503],[0,0],[-0.796,0.549],[0,0]],"o":[[0.467,-0.777],[-0.702,-0.412],[0,0],[0,0],[0.093,-0.823],[-0.842,-0.504],[-0.14,0.275],[0,0],[-0.14,0.961],[0,0],[0.889,0.503],[0,0],[0.14,-0.275]],"v":[[-33.071,85.824],[-33.727,83.537],[-35.88,83.766],[-58.443,100.693],[-54.885,73.243],[-55.822,71.185],[-58.256,71.779],[-58.49,72.557],[-61.907,102.294],[-60.831,104.581],[-60.69,104.673],[-58.162,104.444],[-33.493,86.465]],"c":true},"ix":2},"nm":"Path 23","mn":"ADBE Vector Shape - Group","hd":false},{"ind":21,"ty":"sh","ix":22,"ks":{"a":0,"k":{"i":[[4.775,5.307],[5.383,-4.62],[0,0],[-4.775,-5.261],[-5.384,4.621],[0,0]],"o":[[-4.775,-5.307],[0,0],[-5.384,4.621],[4.775,5.307],[0,0],[5.384,-4.621]],"v":[[-70.146,60.754],[-88.028,60.067],[-88.074,60.113],[-89.619,77.635],[-71.737,78.321],[-71.691,78.276]],"c":true},"ix":2},"nm":"Path 24","mn":"ADBE Vector Shape - Group","hd":false},{"ind":22,"ty":"sh","ix":23,"ks":{"a":0,"k":{"i":[[-6.366,-7.045],[6.507,-5.581],[0,0],[6.366,7.045],[-6.507,5.627],[0,0]],"o":[[6.366,7.045],[0,0],[-6.506,5.627],[-6.366,-7.045],[0,0],[6.553,-5.581]],"v":[[-67.618,58.695],[-69.163,80.929],[-69.21,80.975],[-92.147,79.694],[-90.602,57.414],[-90.555,57.368]],"c":true},"ix":2},"nm":"Path 25","mn":"ADBE Vector Shape - Group","hd":false},{"ind":23,"ty":"sh","ix":24,"ks":{"a":0,"k":{"i":[[-2.528,-6.314],[-3.324,-1.555],[-0.187,-0.412],[0.843,-0.32],[0.374,0.182],[1.873,4.712],[-8.426,3.249],[0,0],[-3.418,-8.463],[1.17,-3.524],[0.608,-0.228],[0.327,0.869],[-0.094,0.274],[1.451,3.523],[6.741,-2.608],[0,0]],"o":[[1.451,3.568],[0.327,0.138],[0.327,0.823],[-0.515,0.183],[-3.792,-1.831],[-3.37,-8.281],[0,0],[8.285,-3.203],[1.872,4.621],[-0.14,0.456],[-0.89,0.321],[-0.187,-0.458],[1.123,-2.974],[-2.575,-6.359],[0,0],[-6.788,2.562]],"v":[[-110.45,45.291],[-103.428,52.427],[-102.539,53.297],[-103.522,55.447],[-104.926,55.356],[-113.54,46.389],[-104.271,26.167],[-104.177,26.122],[-83.112,34.768],[-82.785,46.481],[-83.861,47.669],[-86.155,46.663],[-86.202,45.474],[-86.202,35.958],[-102.726,29.507],[-102.82,29.553]],"c":true},"ix":2},"nm":"Path 26","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[120,120],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":28,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Logo_Inside Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[130,130,0],"ix":2},"a":{"a":0,"k":[120,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.685,0],[0,0],[1.17,1.236],[0,0],[-2.574,2.333],[-2.387,-2.516],[0,0],[0,0],[-2.481,-2.379],[2.434,-2.425],[0,0]],"o":[[0,0],[-1.732,-0.046],[0,0],[-2.387,-2.469],[2.528,-2.333],[0,0],[0,0],[2.434,-2.425],[2.481,2.379],[0,0],[-1.217,1.143]],"v":[[-21.112,38.727],[-21.205,38.727],[-25.699,36.759],[-48.918,12.466],[-48.59,3.774],[-39.696,4.095],[-20.924,23.721],[39.93,-36.302],[48.824,-36.348],[48.871,-27.655],[-16.618,36.943]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[138.055,111.631],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.732,2.974],[0,0],[3.511,0],[0,0],[-1.733,-2.928],[0,0]],"o":[[0,0],[1.731,-2.974],[0,0],[-3.463,0],[0,0],[1.779,2.974]],"v":[[42.528,58.17],[45.945,52.36],[42.012,45.726],[35.178,45.726],[31.247,52.36],[34.664,58.17]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-4.072,3.705],[-3.792,-3.934],[0,0],[0,0],[0,0],[0.654,-2.607],[0,0],[1.639,0.412],[0,0],[-0.421,1.601],[0,0],[1.966,0],[0,0],[0.562,-0.457],[0,0],[-1.03,-2.333],[0,0],[-4.728,2.837],[0,0]],"o":[[-3.791,-3.98],[4.073,-3.706],[0,0],[0,0],[0,0],[-1.31,-2.379],[0,0],[-0.421,1.602],[0,0],[-1.638,-0.412],[0,0],[0.469,-1.876],[0,0],[-0.701,0],[0,0],[-2.012,1.693],[0,0],[2.153,4.986],[0,0],[0,0]],"v":[[-33.4,6.656],[-32.885,-7.251],[-18.654,-6.794],[-2.598,10.042],[47.021,-38.91],[35.974,-58.765],[30.404,-58.079],[25.957,-40.557],[22.305,-38.407],[6.764,-42.158],[4.563,-45.726],[6.061,-51.674],[3.113,-55.334],[-12.242,-55.334],[-14.207,-54.602],[-66.402,-10.866],[-68.04,-4.095],[-54.371,27.381],[-41.311,31.452],[-21.229,19.42]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0.844,-1.693],[0,0],[2.294,0],[0,0],[1.124,1.19],[0,0],[0,0]],"o":[[0.935,1.647],[0,0],[-0.982,2.058],[0,0],[-1.686,0],[0,0],[0,0],[0,0]],"v":[[68.087,-0.984],[68.226,4.369],[51.515,38.681],[46.086,42.066],[30.545,42.066],[26.143,40.19],[11.165,24.498],[57.086,-20.793]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.776,119.958],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":5,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Logo_Outside Outlines","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":599,"s":[360]}],"ix":10},"p":{"a":0,"k":[130,130,0],"ix":2},"a":{"a":0,"k":[120,120,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":240,"h":240,"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..35da219afe706b24bf6e3afa76b2a9b9395ccace GIT binary patch literal 40809 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 KG@R6I!v70A?k)%b literal 0 HcmV?d00001 diff --git a/app/src/main/java/au/gov/health/covidsafe/HasBlockingState.kt b/app/src/main/java/au/gov/health/covidsafe/HasBlockingState.kt new file mode 100644 index 0000000..21c5fef --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/HasBlockingState.kt @@ -0,0 +1,5 @@ +package au.gov.health.covidsafe + +interface HasBlockingState { + var isUiBlocked: Boolean +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt b/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt new file mode 100644 index 0000000..04e0f08 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/HomeActivity.kt @@ -0,0 +1,15 @@ +package au.gov.health.covidsafe + +import android.os.Bundle +import androidx.fragment.app.FragmentActivity + +class HomeActivity : FragmentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_home) + + Utils.startBluetoothMonitoringService(this) + + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/PeekActivity.kt b/app/src/main/java/au/gov/health/covidsafe/PeekActivity.kt new file mode 100644 index 0000000..bf2bf8d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/PeekActivity.kt @@ -0,0 +1,147 @@ +package au.gov.health.covidsafe + +import android.content.Intent +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.floatingactionbutton.FloatingActionButton +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import au.gov.health.covidsafe.streetpass.view.RecordViewModel + + +class PeekActivity : AppCompatActivity() { + + private lateinit var viewModel: RecordViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + newPeek() + } + + private fun newPeek() { + setContentView(R.layout.database_peek) + val recyclerView = findViewById(R.id.recyclerview) + val adapter = RecordListAdapter(this) + recyclerView.adapter = adapter + val layoutManager = LinearLayoutManager(this) + recyclerView.layoutManager = layoutManager + + val dividerItemDecoration = DividerItemDecoration( + recyclerView.context, + layoutManager.orientation + ) + recyclerView.addItemDecoration(dividerItemDecoration) + + viewModel = ViewModelProvider(this).get(RecordViewModel::class.java) + viewModel.allRecords.observe(this, Observer { records -> + adapter.setSourceData(records) + }) + + findViewById(R.id.expand) + .setOnClickListener { + viewModel.allRecords.value?.let { + adapter.setMode(RecordListAdapter.MODE.ALL) + } + } + + findViewById(R.id.collapse) + .setOnClickListener { + viewModel.allRecords.value?.let { + adapter.setMode(RecordListAdapter.MODE.COLLAPSE) + } + } + + + val start = findViewById(R.id.start) + start.setOnClickListener { + startService() + } + + val stop = findViewById(R.id.stop) + stop.setOnClickListener { + stopService() + } + + val delete = findViewById(R.id.delete) + delete.setOnClickListener { view -> + view.isEnabled = false + + val builder = AlertDialog.Builder(this) + builder + .setTitle("Are you sure?") + .setCancelable(false) + .setMessage("Deleting the DB records is irreversible") + .setPositiveButton("DELETE") { dialog, which -> + Observable.create { + StreetPassRecordStorage(this).nukeDb() + it.onNext(true) + } + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribe { result -> + Toast.makeText(this, "Database nuked: $result", Toast.LENGTH_SHORT) + .show() + view.isEnabled = true + dialog.cancel() + } + } + + .setNegativeButton("DON'T DELETE") { dialog, which -> + view.isEnabled = true + dialog.cancel() + } + + val dialog: AlertDialog = builder.create() + dialog.show() + + } + + val plot = findViewById(R.id.plot) + plot.setOnClickListener { view -> + val intent = Intent(this, PlotActivity::class.java) + intent.putExtra("time_period", nextTimePeriod()) + startActivity(intent) + } + + if(!BuildConfig.DEBUG) { + start.visibility = View.GONE + stop.visibility = View.GONE + delete.visibility = View.GONE + } + + } + + private var timePeriod: Int = 0 + + private fun nextTimePeriod(): Int { + timePeriod = when (timePeriod) { + 1 -> 3 + 3 -> 6 + 6 -> 12 + 12 -> 24 + else -> 1 + } + + return timePeriod + } + + + private fun startService() { + Utils.startBluetoothMonitoringService(this) + } + + private fun stopService() { + Utils.stopBluetoothMonitoringService(this) + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/PlotActivity.kt b/app/src/main/java/au/gov/health/covidsafe/PlotActivity.kt new file mode 100644 index 0000000..a8febf1 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/PlotActivity.kt @@ -0,0 +1,231 @@ +package au.gov.health.covidsafe + +import android.os.Build +import android.os.Bundle +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AppCompatActivity +import io.reactivex.Observable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.functions.BiFunction +import io.reactivex.schedulers.Schedulers +import au.gov.health.covidsafe.status.persistence.StatusRecord +import au.gov.health.covidsafe.status.persistence.StatusRecordStorage +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import au.gov.health.covidsafe.ui.upload.model.DebugData +import java.text.SimpleDateFormat +import java.util.* +import kotlin.Comparator + +class PlotActivity : AppCompatActivity() { + private var TAG = "PlotActivity" + + @RequiresApi(Build.VERSION_CODES.O) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + setContentView(R.layout.activity_plot) + + val webView = findViewById(R.id.webView) + webView.webViewClient = WebViewClient() + webView.settings.javaScriptEnabled = true + + val displayTimePeriod = intent.getIntExtra("time_period", 1) // in hours + + val observableStreetRecords = Observable.create> { + val result = StreetPassRecordStorage(this).getAllRecords() + it.onNext(result) + } + val observableStatusRecords = Observable.create> { + val result = StatusRecordStorage(this).getAllRecords() + it.onNext(result) + } + + val zipResult = Observable.zip(observableStreetRecords, observableStatusRecords, + BiFunction, List, DebugData> { records, _ -> DebugData(records) } + ) + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.io()) + .subscribe { exportedData -> + + if(exportedData.records.isEmpty()){ + return@subscribe + } + + val dateFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + + // Use the date of the last record as the end time (Epoch time in seconds) + val endTime = + exportedData.records.sortedByDescending { it.timestamp }[0].timestamp / 1000 + 1 * 60 + val endTimeString = dateFormatter.format(Date(endTime * 1000)) + + val startTime = + endTime - displayTimePeriod * 3600 // ignore records older than X hour(s) + val startTimeString = dateFormatter.format(Date(startTime * 1000)) + + val filteredRecords = exportedData.records.filter { + it.timestamp / 1000 in startTime..endTime + } + + if (filteredRecords.isNotEmpty()) { + val dataByModelC = filteredRecords.groupBy { it.modelC } + val dataByModelP = filteredRecords.groupBy { it.modelP } + + // get all models + val allModelList = dataByModelC.keys union dataByModelP.keys.toList() + + // sort the list by the models that appear the most frequently + val sortedModelList = + allModelList.sortedWith(Comparator { a: String, b: String -> + val aSize = (dataByModelC[a]?.size ?: 0) + (dataByModelP[a]?.size ?: 0) + val bSize = (dataByModelC[b]?.size ?: 0) + (dataByModelP[b]?.size ?: 0) + + bSize - aSize + }) + + val individualData = sortedModelList.joinToString(separator = "\n") { model -> + val index = sortedModelList.indexOf(model) + 1 + + val hasC = dataByModelC.containsKey(model) + val hasP = dataByModelP.containsKey(model) + + val x1 = dataByModelC[model]?.joinToString(separator = "\", \"", prefix = "[\"", postfix = "\"]") { + dateFormatter.format(Date(it.timestamp)) + } + + val y1 = dataByModelC[model]?.map { it.rssi } + ?.joinToString(separator = ", ", prefix = "[", postfix = "]") + + val x2 = dataByModelP[model]?.joinToString(separator = "\", \"", prefix = "[\"", postfix = "\"]") { + dateFormatter.format(Date(it.timestamp)) + } + + val y2 = dataByModelP[model]?.map { it.rssi } + ?.joinToString(separator = ", ", prefix = "[", postfix = "]") + + val dataHead = "var data${index} = [];" + + val dataA = if (!hasC) "" else """ + var data${index}a = { + name: 'central', + x: ${x1}, + y: ${y1}, + xaxis: 'x${index}', + yaxis: 'y${index}', + mode: 'markers', + type: 'scatter', + line: {color: 'blue'} + }; + data${index} = data${index}.concat(data${index}a); + """.trimIndent() + + val dataB = if (!hasP) "" else """ + var data${index}b = { + name: 'peripheral', + x: ${x2}, + y: ${y2}, + xaxis: 'x${index}', + yaxis: 'y${index}', + mode: 'markers', + type: 'scatter', + line: {color: 'red'} + }; + data${index} = data${index}.concat(data${index}b); + """.trimIndent() + + val data = dataHead + dataA + dataB + + data + + } + + val top = 20 + + val combinedData = sortedModelList.joinToString(separator = "\n") { model -> + val index = sortedModelList.indexOf(model) + 1 + if (index < top) """ + data = data.concat(data${index}); + """.trimIndent() else "" + } + + val xAxis = sortedModelList.joinToString(separator = ",\n") { model -> + val index = sortedModelList.indexOf(model) + 1 + if (index < top) """ + xaxis${index}: { + type: 'date', + tickformat: '%H:%M:%S', + range: ['${startTimeString}', '${endTimeString}'], + dtick: ${displayTimePeriod * 5} * 60 * 1000 + } + """.trimIndent() else "" + } + + val yAxis = sortedModelList.joinToString(separator = ",\n") { model -> + val index = sortedModelList.indexOf(model) + 1 + if (index < top) """ + yaxis${index}: { + range: [-100, -30], + ticks: 'outside', + dtick: 10, + title: { + text: "$model" + } + } + """.trimIndent() else "" + } + + // Form the complete HTML + val customHtml = """ + + + + +
+ + + """.trimIndent() + + webView.loadData(customHtml, "text/html", "UTF-8") + } else { + webView.loadData( + "No data received in the last $displayTimePeriod hour(s) or more.", + "text/html", + "UTF-8" + ) + } + } + webView.loadData("Loading...", "text/html", "UTF-8") + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/Preference.kt b/app/src/main/java/au/gov/health/covidsafe/Preference.kt new file mode 100644 index 0000000..b5e4587 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/Preference.kt @@ -0,0 +1,162 @@ +package au.gov.health.covidsafe + +import android.content.Context +import androidx.security.crypto.EncryptedSharedPreferences +import androidx.security.crypto.MasterKeys + +object Preference { + private const val PREF_ID = "Tracer_pref" + private const val IS_ONBOARDED = "IS_ONBOARDED" + private const val PHONE_NUMBER = "PHONE_NUMBER" + private const val HANDSHAKE_PIN = "HANDSHAKE_PIN" + private const val DEVICE_ID = "DEVICE_ID" + private const val JWT_TOKEN = "JWT_TOKEN" + private const val IS_DATA_UPLOADED = "IS_DATA_UPLOADED" + private const val DATA_UPLOADED_DATE_MS = "DATA_UPLOADED_DATE_MS" + private const val UPLOADED_MORE_THAN_24_HRS = "UPLOADED_MORE_THAN_24_HRS" + + private const val NEXT_FETCH_TIME = "NEXT_FETCH_TIME" + private const val EXPIRY_TIME = "EXPIRY_TIME" + private const val NAME = "NAME" + private const val IS_MINOR = "IS_MINOR" + private const val POST_CODE = "POST_CODE" + private const val AGE = "AGE" + + fun putDeviceID(context: Context, value: String) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putString(DEVICE_ID, value)?.apply() + } + + fun getDeviceID(context: Context?): String { + return context?.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + ?.getString(DEVICE_ID, "") ?: "" + } + + fun putEncrypterJWTToken(context: Context?, jwtToken: String?) { + context?.let { + val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) + EncryptedSharedPreferences.create( + PREF_ID, + masterKeyAlias, + context, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ).edit()?.putString(JWT_TOKEN, jwtToken)?.apply() + } + } + + fun getEncrypterJWTToken(context: Context?): String? { + return context?.let { + val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) + EncryptedSharedPreferences.create( + PREF_ID, + masterKeyAlias, + context, + EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, + EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM + ).getString(JWT_TOKEN, null) + } + } + + fun putHandShakePin(context: Context?, value: String?) { + context?.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + ?.edit()?.putString(HANDSHAKE_PIN, value)?.apply() + } + + fun putIsOnBoarded(context: Context, value: Boolean) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putBoolean(IS_ONBOARDED, value).apply() + } + + fun isOnBoarded(context: Context): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getBoolean(IS_ONBOARDED, false) + } + + fun putPhoneNumber(context: Context, value: String) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putString(PHONE_NUMBER, value).apply() + } + + fun putNextFetchTimeInMillis(context: Context, time: Long) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putLong(NEXT_FETCH_TIME, time).apply() + } + + fun getNextFetchTimeInMillis(context: Context): Long { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getLong( + NEXT_FETCH_TIME, 0 + ) + } + + fun putExpiryTimeInMillis(context: Context, time: Long) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putLong(EXPIRY_TIME, time).apply() + } + + fun getExpiryTimeInMillis(context: Context): Long { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getLong( + EXPIRY_TIME, 0 + ) + } + + fun isDataUploaded(context: Context): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE).getBoolean(IS_DATA_UPLOADED, false) + } + + fun setDataIsUploaded(context: Context, value: Boolean) { + context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE).edit().also { editor -> + editor.putBoolean(IS_DATA_UPLOADED, value) + if (value) { + editor.putLong(DATA_UPLOADED_DATE_MS, System.currentTimeMillis()) + } else { + editor.remove(DATA_UPLOADED_DATE_MS) + } + }.apply() + } + + fun getDataUploadedDateMs(context: Context): Long { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE).getLong(DATA_UPLOADED_DATE_MS, System.currentTimeMillis()) + } + + fun putName(context: Context, name: String): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putString(NAME, name).commit() + } + + fun getName(context: Context): String? { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE).getString(NAME, null) + } + + fun putIsMinor(context: Context, minor: Boolean): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putBoolean(IS_MINOR, minor).commit() + } + + fun isMinor(context: Context): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE).getBoolean(IS_MINOR, false) + } + + fun putPostCode(context: Context, state: String): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putString(POST_CODE, state).commit() + } + + fun getPostCode(context: Context): String? { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getString(POST_CODE, null) + } + + fun putAge(context: Context, age: String): Boolean { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .edit().putString(AGE, age).commit() + } + + fun getAge(context: Context): String? { + return context.getSharedPreferences(PREF_ID, Context.MODE_PRIVATE) + .getString(AGE, null) + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/RecordListAdapter.kt b/app/src/main/java/au/gov/health/covidsafe/RecordListAdapter.kt new file mode 100644 index 0000000..616c331 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/RecordListAdapter.kt @@ -0,0 +1,170 @@ +package au.gov.health.covidsafe + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord +import au.gov.health.covidsafe.streetpass.view.StreetPassRecordViewModel + + +class RecordListAdapter internal constructor(context: Context) : + RecyclerView.Adapter() { + private val inflater: LayoutInflater = LayoutInflater.from(context) + private var records = emptyList() // Cached copy of records + private var sourceData = emptyList() + + enum class MODE { + ALL, COLLAPSE, MODEL_P, MODEL_C + } + + private var mode = MODE.ALL + + inner class RecordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val modelCView: TextView = itemView.findViewById(R.id.modelc) + val modelPView: TextView = itemView.findViewById(R.id.modelp) + val timestampView: TextView = itemView.findViewById(R.id.timestamp) + val findsView: TextView = itemView.findViewById(R.id.finds) + val txpowerView: TextView = itemView.findViewById(R.id.txpower) + val signalStrengthView: TextView = itemView.findViewById(R.id.signal_strength) + val filterModelP: View = itemView.findViewById(R.id.filter_by_modelp) + val filterModelC: View = itemView.findViewById(R.id.filter_by_modelc) + val msgView: TextView = itemView.findViewById(R.id.msg) + val version: TextView = itemView.findViewById(R.id.version) + val org: TextView = itemView.findViewById(R.id.org) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordViewHolder { + val itemView = inflater.inflate(R.layout.recycler_view_item, parent, false) + return RecordViewHolder(itemView) + } + + override fun onBindViewHolder(holder: RecordViewHolder, position: Int) { + val current = records[position] + holder.msgView.text = current.msg + holder.modelCView.text = current.modelC + holder.modelPView.text = current.modelP + holder.findsView.text = "Detections: ${current.number}" + val readableDate = Utils.getDate(current.timeStamp) + holder.timestampView.text = readableDate + holder.version.text = "v: ${current.version}" + holder.org.text = "ORG: ${current.org}" + + holder.filterModelP.tag = current + holder.filterModelC.tag = current + + holder.signalStrengthView.text = "Signal Strength: ${current.rssi}" + + holder.txpowerView.text = "Tx Power: ${current.transmissionPower}" + + holder.filterModelP.setOnClickListener { + val model = it.tag as StreetPassRecordViewModel + setMode(MODE.MODEL_P, model) + } + + holder.filterModelC.setOnClickListener { + val model = it.tag as StreetPassRecordViewModel + setMode(MODE.MODEL_C, model) + } + } + + private fun filter(sample: StreetPassRecordViewModel?): List { + return when (mode) { + MODE.COLLAPSE -> prepareCollapsedData(sourceData) + + MODE.ALL -> prepareViewData(sourceData) + + MODE.MODEL_P -> filterByModelP(sample, sourceData) + + MODE.MODEL_C -> filterByModelC(sample, sourceData) + + else -> { + prepareViewData(sourceData) + } + } + } + + private fun filterByModelC( + model: StreetPassRecordViewModel?, + words: List + ): List { + if (model != null) { + return prepareViewData(words.filter { it.modelC == model.modelC }) + } + return prepareViewData(words) + } + + private fun filterByModelP( + model: StreetPassRecordViewModel?, + words: List + ): List { + + if (model != null) { + return prepareViewData(words.filter { it.modelP == model.modelP }) + } + return prepareViewData(words) + } + + + private fun prepareCollapsedData(words: List): List { + //we'll need to count the number of unique device IDs + val countMap = words.groupBy { + it.modelC + } + + val distinctAddresses = words.distinctBy { it.modelC } + + return distinctAddresses.map { record -> + val count = countMap[record.modelC]?.size + + count?.let { count -> + val mostRecentRecord = countMap[record.modelC]?.maxBy { it.timestamp } + + if (mostRecentRecord != null) { + return@map StreetPassRecordViewModel(mostRecentRecord, count) + } + + return@map StreetPassRecordViewModel(record, count) + } + //fallback - unintended + return@map StreetPassRecordViewModel(record) + } + } + + private fun prepareViewData(words: List): List { + + words.let { + + val reversed = it.reversed() + return reversed.map { streetPassRecord -> + return@map StreetPassRecordViewModel(streetPassRecord) + } + } + } + + fun setMode(mode: MODE) { + setMode(mode, null) + } + + private fun setMode(mode: MODE, model: StreetPassRecordViewModel?) { + this.mode = mode + + val list = filter(model) + setRecords(list) + } + + private fun setRecords(records: List) { + this.records = records + notifyDataSetChanged() + } + + internal fun setSourceData(records: List) { + this.sourceData = records + setMode(mode) + } + + override fun getItemCount() = records.size + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/SelfIsolationDoneActivity.kt b/app/src/main/java/au/gov/health/covidsafe/SelfIsolationDoneActivity.kt new file mode 100644 index 0000000..d3cf99e --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/SelfIsolationDoneActivity.kt @@ -0,0 +1,35 @@ +package au.gov.health.covidsafe + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.FragmentActivity +import kotlinx.android.synthetic.main.activity_self_isolation.* + +class SelfIsolationDoneActivity : FragmentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_self_isolation) + } + + override fun onResume() { + super.onResume() + activity_self_isolation_next.setOnClickListener { + Preference.setDataIsUploaded(this, false) + val intent = Intent(this, HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + startActivity(intent) + finish() + } + } + + override fun onPause() { + super.onPause() + activity_self_isolation_next.setOnClickListener(null) + } + + override fun onDestroy() { + super.onDestroy() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/SplashActivity.kt b/app/src/main/java/au/gov/health/covidsafe/SplashActivity.kt new file mode 100644 index 0000000..db781bc --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/SplashActivity.kt @@ -0,0 +1,82 @@ +package au.gov.health.covidsafe + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.provider.Settings +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import au.gov.health.covidsafe.ui.onboarding.OnboardingActivity +import java.util.* + +class SplashActivity : AppCompatActivity() { + + private val SPLASH_TIME: Long = 2000 + + private var retryProviderInstall: Boolean = false + private val ERROR_DIALOG_REQUEST_CODE = 1 + + private var updateFlag = false + + private lateinit var mHandler: Handler + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_splash) + hideSystemUI() + mHandler = Handler() + + Preference.putDeviceID(this, Settings.Secure.getString(this.contentResolver, + Settings.Secure.ANDROID_ID)) + + } + + override fun onPause() { + super.onPause() + mHandler.removeCallbacksAndMessages(null) + } + + override fun onResume() { + super.onResume() + if (!updateFlag) { + mHandler.postDelayed({ + goToNextScreen() + finish() + }, SPLASH_TIME) + } + } + + private fun goToNextScreen() { + val dateUploaded = Calendar.getInstance().also { + it.timeInMillis = Preference.getDataUploadedDateMs(this) + } + val fourteenDaysAgo = Calendar.getInstance().also { + it.add(Calendar.DATE, -14) + } + startActivity(Intent(this, if (!Preference.isOnBoarded(this)) { + OnboardingActivity::class.java + } else if (dateUploaded.before(fourteenDaysAgo)) { + SelfIsolationDoneActivity::class.java + } else { + HomeActivity::class.java + })) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == ERROR_DIALOG_REQUEST_CODE) { + retryProviderInstall = true + } + } + + // This snippet hides the system bars. + private fun hideSystemUI() { + window.decorView.systemUiVisibility = ( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + or View.SYSTEM_UI_FLAG_FULLSCREEN) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/TracerApp.kt b/app/src/main/java/au/gov/health/covidsafe/TracerApp.kt new file mode 100644 index 0000000..e7e1cb1 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/TracerApp.kt @@ -0,0 +1,48 @@ +package au.gov.health.covidsafe + +import android.app.Application +import android.content.Context +import android.os.Build +import com.atlassian.mobilekit.module.feedback.FeedbackModule + +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.services.BluetoothMonitoringService +import au.gov.health.covidsafe.streetpass.CentralDevice +import au.gov.health.covidsafe.streetpass.PeripheralDevice + +class TracerApp : Application() { + + override fun onCreate() { + super.onCreate() + AppContext = applicationContext + FeedbackModule.init(this) + } + + companion object { + + private const val TAG = "TracerApp" + const val ORG = BuildConfig.ORG + const val protocolVersion = BuildConfig.PROTOCOL_VERSION + + lateinit var AppContext: Context + + fun thisDeviceMsg(): String { + BluetoothMonitoringService.broadcastMessage?.let { + CentralLog.i(TAG, "Retrieved BM for storage: $it") + return it + } + + CentralLog.e(TAG, "No local Broadcast Message") + return BluetoothMonitoringService.broadcastMessage!! + } + + fun asPeripheralDevice(): PeripheralDevice { + return PeripheralDevice(Build.MODEL, "SELF") + } + + fun asCentralDevice(): CentralDevice { + return CentralDevice(Build.MODEL, "SELF") + } + + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/Utils.kt b/app/src/main/java/au/gov/health/covidsafe/Utils.kt new file mode 100644 index 0000000..62939c1 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/Utils.kt @@ -0,0 +1,247 @@ +package au.gov.health.covidsafe + +import android.Manifest +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import android.provider.Settings +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import au.gov.health.covidsafe.bluetooth.gatt.* +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.scheduler.Scheduler +import au.gov.health.covidsafe.services.BluetoothMonitoringService +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_ADVERTISE_REQ_CODE +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_BM_UPDATE +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_HEALTH_CHECK_CODE +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_SCAN_REQ_CODE +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_START +import au.gov.health.covidsafe.status.Status +import au.gov.health.covidsafe.streetpass.ACTION_DEVICE_SCANNED +import au.gov.health.covidsafe.streetpass.ConnectablePeripheral +import au.gov.health.covidsafe.streetpass.ConnectionRecord +import java.io.File +import java.text.SimpleDateFormat +import java.util.* + +object Utils { + + private const val TAG = "Utils" + + fun getRequiredPermissions(): Array { + return arrayOf(Manifest.permission.ACCESS_FINE_LOCATION) + } + + fun getBatteryOptimizerExemptionIntent(packageName: String): Intent { + val intent = Intent() + intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS + intent.data = Uri.parse("package:$packageName") + return intent + } + + fun canHandleIntent(batteryExemptionIntent: Intent, packageManager: PackageManager?): Boolean { + packageManager?.let { + return batteryExemptionIntent.resolveActivity(packageManager) != null + } + return false + } + + fun getDate(milliSeconds: Long): String { + val dateFormat = "dd/MM/yyyy HH:mm:ss.SSS" + // Create a DateFormatter object for displaying date in specified format. + val formatter = SimpleDateFormat(dateFormat) + + // Create a calendar object that will convert the date and time value in milliseconds to date. + val calendar = Calendar.getInstance() + calendar.timeInMillis = milliSeconds + return formatter.format(calendar.time) + } + + fun startBluetoothMonitoringService(context: Context) { + val intent = Intent(context, BluetoothMonitoringService::class.java) + intent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_START.index + ) + + context.startService(intent) + } + + fun scheduleStartMonitoringService(context: Context, timeInMillis: Long) { + val intent = Intent(context, BluetoothMonitoringService::class.java) + intent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_START.index + ) + + Scheduler.scheduleServiceIntent( + PENDING_START, + context, + intent, + timeInMillis + ) + } + + fun scheduleBMUpdateCheck(context: Context, bmCheckInterval: Long) { + + cancelBMUpdateCheck(context) + + val intent = Intent(context, BluetoothMonitoringService::class.java) + intent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_UPDATE_BM.index + ) + + Scheduler.scheduleServiceIntent( + PENDING_BM_UPDATE, + context, + intent, + bmCheckInterval + ) + } + + fun cancelBMUpdateCheck(context: Context) { + val intent = Intent(context, BluetoothMonitoringService::class.java) + intent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_UPDATE_BM.index + ) + + Scheduler.cancelServiceIntent(PENDING_BM_UPDATE, context, intent) + } + + fun stopBluetoothMonitoringService(context: Context) { + val intent = Intent(context, BluetoothMonitoringService::class.java) + intent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_STOP.index + ) + cancelNextScan(context) + cancelNextHealthCheck(context) + context.stopService(intent) + } + + fun cancelNextScan(context: Context) { + val nextIntent = Intent(context, BluetoothMonitoringService::class.java) + nextIntent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_SCAN.index + ) + Scheduler.cancelServiceIntent(PENDING_SCAN_REQ_CODE, context, nextIntent) + } + + fun cancelNextAdvertise(context: Context) { + val nextIntent = Intent(context, BluetoothMonitoringService::class.java) + nextIntent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_ADVERTISE.index + ) + Scheduler.cancelServiceIntent(PENDING_ADVERTISE_REQ_CODE, context, nextIntent) + } + + fun scheduleNextHealthCheck(context: Context, timeInMillis: Long) { + //cancels any outstanding check schedules. + cancelNextHealthCheck(context) + + val nextIntent = Intent(context, BluetoothMonitoringService::class.java) + nextIntent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_SELF_CHECK.index + ) + Scheduler.scheduleServiceIntent( + PENDING_HEALTH_CHECK_CODE, + context, + nextIntent, + timeInMillis + ) + } + + private fun cancelNextHealthCheck(context: Context) { + val nextIntent = Intent(context, BluetoothMonitoringService::class.java) + nextIntent.putExtra( + BluetoothMonitoringService.COMMAND_KEY, + BluetoothMonitoringService.Command.ACTION_SELF_CHECK.index + ) + Scheduler.cancelServiceIntent(PENDING_HEALTH_CHECK_CODE, context, nextIntent) + } + + fun broadcastDeviceScanned( + context: Context, + device: BluetoothDevice, + connectableBleDevice: ConnectablePeripheral + ) { + val intent = Intent(ACTION_DEVICE_SCANNED) + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device) + intent.putExtra(CONNECTION_DATA, connectableBleDevice) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + + fun broadcastDeviceProcessed(context: Context, deviceAddress: String) { + val intent = Intent(ACTION_DEVICE_PROCESSED) + intent.putExtra(DEVICE_ADDRESS, deviceAddress) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + + + fun broadcastStreetPassReceived(context: Context, streetpass: ConnectionRecord) { + val intent = Intent(ACTION_RECEIVED_STREETPASS) + intent.putExtra(STREET_PASS, streetpass) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + + fun broadcastStatusReceived(context: Context, statusRecord: Status) { + val intent = Intent(ACTION_RECEIVED_STATUS) + intent.putExtra(STATUS, statusRecord) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + + fun broadcastDeviceDisconnected(context: Context, device: BluetoothDevice) { + val intent = Intent(ACTION_GATT_DISCONNECTED) + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + + fun isBluetoothAvailable(): Boolean { + val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() + return bluetoothAdapter != null && + bluetoothAdapter.isEnabled && bluetoothAdapter.state == BluetoothAdapter.STATE_ON + } + + fun storeBroadcastMessage(context: Context?, packet: String) { + CentralLog.d(TAG, "Storing packet into internal storage...") + val file = File(context?.filesDir, "packet") + file.writeText(packet) + } + + fun retrieveBroadcastMessage(context: Context): String? { + val file = File(context.filesDir, "packet") + if (file.exists()) { + val readback = file.readText() + CentralLog.d(TAG, "fetched broadcastmessage from file: $readback") + return readback + } + return null + } + + fun needToUpdate(context: Context): Boolean { + val nextFetchTime = Preference.getNextFetchTimeInMillis(context) + + val currentTime = System.currentTimeMillis() + + val update = currentTime >= nextFetchTime + CentralLog.i(TAG, "Need to update BM? $nextFetchTime vs $currentTime: $update") + return update + } + + fun bmValid(context: Context): Boolean { + val expiryTime = Preference.getExpiryTimeInMillis(context) + val currentTime = System.currentTimeMillis() + + val update = currentTime < expiryTime + CentralLog.i(TAG, "Is BM Valid? $expiryTime vs $currentTime: $update") + + return true + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/WebViewActivity.kt b/app/src/main/java/au/gov/health/covidsafe/WebViewActivity.kt new file mode 100644 index 0000000..1ae927d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/WebViewActivity.kt @@ -0,0 +1,35 @@ +package au.gov.health.covidsafe + +import android.os.Bundle +import android.webkit.WebChromeClient +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.fragment.app.FragmentActivity +import au.gov.health.covidsafe.logging.CentralLog + +class WebViewActivity : FragmentActivity() { + + companion object { + val URL_ARG = "URL_ARG" + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.webview) + val webView = findViewById(R.id.webview) + webView.webViewClient = WebViewClient() + if (intent.getStringExtra(URL_ARG).isNullOrBlank()) { + webView.loadUrl("https://www.australia.gov.au") + } else { + webView.loadUrl(intent.getStringExtra(URL_ARG)) + } + + val wbc: WebChromeClient = object : WebChromeClient() { + override fun onCloseWindow(w: WebView) { + CentralLog.d("WebViewActivity", "Window trying to close") + } + } + + webView.webChromeClient = wbc + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEAdvertiser.kt b/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEAdvertiser.kt new file mode 100644 index 0000000..5a39480 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEAdvertiser.kt @@ -0,0 +1,128 @@ +package au.gov.health.covidsafe.bluetooth + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.le.AdvertiseCallback +import android.bluetooth.le.AdvertiseData +import android.bluetooth.le.AdvertiseSettings +import android.bluetooth.le.BluetoothLeAdvertiser +import android.os.Handler +import android.os.ParcelUuid +import au.gov.health.covidsafe.logging.CentralLog +import java.util.* + + +class BLEAdvertiser constructor(serviceUUID: String) { + + private var advertiser: BluetoothLeAdvertiser? = + BluetoothAdapter.getDefaultAdapter().bluetoothLeAdvertiser + private val TAG = "BLEAdvertiser" + private var charLength = 3 + private var callback: AdvertiseCallback = object : AdvertiseCallback() { + override fun onStartSuccess(settingsInEffect: AdvertiseSettings) { + super.onStartSuccess(settingsInEffect) + CentralLog.i(TAG, "Advertising onStartSuccess") + CentralLog.i(TAG, settingsInEffect.toString()) + isAdvertising = true + } + + override fun onStartFailure(errorCode: Int) { + super.onStartFailure(errorCode) + + val reason: String + + when (errorCode) { + ADVERTISE_FAILED_ALREADY_STARTED -> { + reason = "ADVERTISE_FAILED_ALREADY_STARTED" + isAdvertising = true + } + ADVERTISE_FAILED_FEATURE_UNSUPPORTED -> { + reason = "ADVERTISE_FAILED_FEATURE_UNSUPPORTED" + isAdvertising = false + } + ADVERTISE_FAILED_INTERNAL_ERROR -> { + reason = "ADVERTISE_FAILED_INTERNAL_ERROR" + isAdvertising = false + } + ADVERTISE_FAILED_TOO_MANY_ADVERTISERS -> { + reason = "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS" + isAdvertising = false + } + ADVERTISE_FAILED_DATA_TOO_LARGE -> { + reason = "ADVERTISE_FAILED_DATA_TOO_LARGE" + isAdvertising = false + charLength-- + } + + else -> { + reason = "UNDOCUMENTED" + } + } + + CentralLog.d(TAG, "Advertising onStartFailure: $errorCode - $reason") + } + } + private val pUuid = ParcelUuid(UUID.fromString(serviceUUID)) + + private val settings: AdvertiseSettings? = AdvertiseSettings.Builder() + .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) + .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) + .setConnectable(true) + .setTimeout(0) + .build() + + var data: AdvertiseData? = null + + private var handler = Handler() + + private var stopRunnable: Runnable = Runnable { + CentralLog.i(TAG, "Advertising stopping as scheduled.") + stopAdvertising() + } + + var isAdvertising = false + var shouldBeAdvertising = false + + private fun startAdvertisingLegacy(timeoutInMillis: Long) { + + val randomUUID = UUID.randomUUID().toString() + val finalString = randomUUID.substring(randomUUID.length - charLength, randomUUID.length) + CentralLog.d(TAG, "Unique string: $finalString") + val serviceDataByteArray = finalString.toByteArray() + + if (data == null) { + data = AdvertiseData.Builder() + .setIncludeDeviceName(false) + .setIncludeTxPowerLevel(true) + .addServiceUuid(pUuid) + .addManufacturerData(1023, serviceDataByteArray) + .build() + } + + try { + CentralLog.d(TAG, "Start advertising") + advertiser = advertiser ?: BluetoothAdapter.getDefaultAdapter().bluetoothLeAdvertiser + advertiser?.startAdvertising(settings, data, callback) + } catch (e: Throwable) { + CentralLog.e(TAG, "Failed to start advertising legacy: ${e.message}") + } + + handler.removeCallbacksAndMessages(stopRunnable) + handler.postDelayed(stopRunnable, timeoutInMillis) + } + + fun startAdvertising(timeoutInMillis: Long) { + startAdvertisingLegacy(timeoutInMillis) + shouldBeAdvertising = true + } + + private fun stopAdvertising() { + try { + CentralLog.d(TAG, "stop advertising") + advertiser?.stopAdvertising(callback) + } catch (e: Throwable) { + CentralLog.e(TAG, "Failed to stop advertising: ${e.message}") + } + shouldBeAdvertising = false + handler.removeCallbacksAndMessages(null) + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEScanner.kt b/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEScanner.kt new file mode 100644 index 0000000..03061af --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/bluetooth/BLEScanner.kt @@ -0,0 +1,67 @@ +package au.gov.health.covidsafe.bluetooth + +import android.bluetooth.BluetoothAdapter +import android.bluetooth.le.BluetoothLeScanner +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanSettings +import android.content.Context +import android.os.ParcelUuid +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.logging.CentralLog +import java.util.* +import kotlin.collections.ArrayList +import kotlin.properties.Delegates + +class BLEScanner constructor(context: Context, uuid: String, reportDelay: Long) { + + private var serviceUUID: String by Delegates.notNull() + private var context: Context by Delegates.notNull() + private var scanCallback: ScanCallback? = null + private var reportDelay: Long by Delegates.notNull() + + private var scanner: BluetoothLeScanner? = + BluetoothAdapter.getDefaultAdapter().bluetoothLeScanner + + private val TAG = "BLEScanner" + + init { + this.serviceUUID = uuid + this.context = context + this.reportDelay = reportDelay + } + + fun startScan(scanCallback: ScanCallback) { + val filter = ScanFilter.Builder() + .setServiceUuid(ParcelUuid(UUID.fromString(serviceUUID))) + .build() + + val filters: ArrayList = ArrayList() + filters.add(filter) + + val settings = ScanSettings.Builder() + .setReportDelay(reportDelay) + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .build() + + this.scanCallback = scanCallback + scanner = scanner ?: BluetoothAdapter.getDefaultAdapter().bluetoothLeScanner + scanner?.startScan(filters, settings, scanCallback) + } + + fun stopScan() { + + try { + if (scanCallback != null && Utils.isBluetoothAvailable()) { //fixed crash if BT if turned off, stop scan will crash. + scanner?.stopScan(scanCallback) + CentralLog.d(TAG, "scanning stopped") + } + } catch (e: Throwable) { + CentralLog.e( + TAG, + "unable to stop scanning - callback null or bluetooth off? : ${e.localizedMessage}" + ) + } + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GATT.kt b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GATT.kt new file mode 100644 index 0000000..e6f8aa8 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GATT.kt @@ -0,0 +1,65 @@ +package au.gov.health.covidsafe.bluetooth.gatt + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.streetpass.PeripheralDevice + +const val ACTION_RECEIVED_STREETPASS = + "${BuildConfig.APPLICATION_ID}.ACTION_RECEIVED_STREETPASS" +const val ACTION_RECEIVED_STATUS = + "${BuildConfig.APPLICATION_ID}.ACTION_RECEIVED_STATUS" + +const val DEVICE_ADDRESS = "${BuildConfig.APPLICATION_ID}.DEVICE_ADDRESS" +const val CONNECTION_DATA = "${BuildConfig.APPLICATION_ID}.CONNECTION_DATA" + +const val STREET_PASS = "${BuildConfig.APPLICATION_ID}.STREET_PASS" +const val STATUS = "${BuildConfig.APPLICATION_ID}.STATUS" + +const val ACTION_DEVICE_PROCESSED = "${BuildConfig.APPLICATION_ID}.ACTION_DEVICE_PROCESSED" +const val ACTION_GATT_DISCONNECTED = "${BuildConfig.APPLICATION_ID}.ACTION_GATT_DISCONNECTED" + +class ReadRequestPayload( + val v: Int, + val msg: String, + val org: String, + peripheral: PeripheralDevice +) { + val modelP = peripheral.modelP + + fun getPayload(): ByteArray { + return gson.toJson(this).toByteArray(Charsets.UTF_8) + } + + companion object { + val gson: Gson = GsonBuilder().disableHtmlEscaping().create() + + fun createReadRequestPayload(dataBytes: ByteArray) : ReadRequestPayload { + val dataString = String(dataBytes, Charsets.UTF_8) + return gson.fromJson(dataString, ReadRequestPayload::class.java) + } + } +} + +class WriteRequestPayload( + val v: Int, + val msg: String, + val org: String, + val modelC: String, + val rssi: Int, + val txPower: Int? +) { + + fun getPayload(): ByteArray { + return gson.toJson(this).toByteArray(Charsets.UTF_8) + } + + companion object { + val gson: Gson = GsonBuilder().disableHtmlEscaping().create() + + fun createReadRequestPayload(dataBytes: ByteArray) : WriteRequestPayload { + val dataString = String(dataBytes, Charsets.UTF_8) + return gson.fromJson(dataString, WriteRequestPayload::class.java) + } + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattServer.kt b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattServer.kt new file mode 100644 index 0000000..057cf08 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattServer.kt @@ -0,0 +1,286 @@ +package au.gov.health.covidsafe.bluetooth.gatt + +import android.bluetooth.* +import android.bluetooth.BluetoothGatt.GATT_FAILURE +import android.bluetooth.BluetoothGatt.GATT_SUCCESS +import android.content.Context +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.streetpass.CentralDevice +import au.gov.health.covidsafe.streetpass.ConnectionRecord +import java.util.* +import kotlin.properties.Delegates + +class GattServer constructor(val context: Context, serviceUUIDString: String) { + + private val TAG = "GattServer" + private var bluetoothManager: BluetoothManager by Delegates.notNull() + + private var serviceUUID: UUID by Delegates.notNull() + var bluetoothGattServer: BluetoothGattServer? = null + + init { + bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + this.serviceUUID = UUID.fromString(serviceUUIDString) + } + + private val gattServerCallback = object : BluetoothGattServerCallback() { + + val writeDataPayload: MutableMap = HashMap() + val readPayloadMap: MutableMap = HashMap() + + override fun onConnectionStateChange(device: BluetoothDevice?, status: Int, newState: Int) { + when (newState) { + BluetoothProfile.STATE_CONNECTED -> { + CentralLog.i(TAG, "${device?.address} Connected to local GATT server") + device?.let { + val b = bluetoothManager.getConnectedDevices(BluetoothProfile.GATT) + .contains(device) + } + } + + BluetoothProfile.STATE_DISCONNECTED -> { + CentralLog.i(TAG, "${device?.address} Disconnected from local GATT server.") + device?.let { + Utils.broadcastDeviceDisconnected(context, device) + } + + } + + else -> { + CentralLog.i(TAG, "Connection status: $newState - ${device?.address}") + } + } + } + + override fun onCharacteristicReadRequest( + device: BluetoothDevice?, + requestId: Int, + offset: Int, + characteristic: BluetoothGattCharacteristic? + ) { + + device?.let { + + CentralLog.i(TAG, "onCharacteristicReadRequest from ${device.address}") + + if (serviceUUID == characteristic?.uuid) { + + if (Utils.bmValid(context)) { + val base = readPayloadMap.getOrPut(device.address, { + ReadRequestPayload( + v = TracerApp.protocolVersion, + msg = TracerApp.thisDeviceMsg(), + org = TracerApp.ORG, + peripheral = TracerApp.asPeripheralDevice() + ).getPayload() + }) + + val value = base.copyOfRange(offset, base.size) + + CentralLog.i( + TAG, + "onCharacteristicReadRequest from ${device.address} - $requestId- $offset - ${String( + value, + Charsets.UTF_8 + )}" + ) + + bluetoothGattServer?.sendResponse(device, requestId, GATT_SUCCESS, 0, value) + } else { + CentralLog.i( + TAG, + "onCharacteristicReadRequest from ${device.address} - $requestId- $offset - BM Expired" + ) + bluetoothGattServer?.sendResponse( + device, + requestId, + GATT_FAILURE, + 0, + ByteArray(0) + ) + } + } else { + CentralLog.i(TAG, "incorrect serviceUUID from ${device.address}") + bluetoothGattServer?.sendResponse(device, requestId, GATT_SUCCESS, 0, null) + } + } + + if (device == null) { + CentralLog.i(TAG, "No device") + } + + } + + + override fun onCharacteristicWriteRequest( + device: BluetoothDevice?, + requestId: Int, + characteristic: BluetoothGattCharacteristic, + preparedWrite: Boolean, + responseNeeded: Boolean, + offset: Int, + value: ByteArray? + ) { + + + device?.let { + CentralLog.i( + TAG, + "onCharacteristicWriteRequest - ${device.address} - preparedWrite: $preparedWrite" + ) + + CentralLog.i( + TAG, + "onCharacteristicWriteRequest from ${device.address} - $requestId - $offset" + ) + + if (serviceUUID == characteristic.uuid) { + var valuePassed = "" + value?.let { + valuePassed = String(value, Charsets.UTF_8) + } + CentralLog.i( + TAG, + "onCharacteristicWriteRequest from ${device.address} - $valuePassed" + ) + if (value != null) { + var dataBuffer = writeDataPayload[device.address] + + if (dataBuffer == null) { + dataBuffer = ByteArray(0) + } + + dataBuffer = dataBuffer.plus(value) + writeDataPayload[device.address] = dataBuffer + + CentralLog.i( + TAG, + "Accumulated characteristic: ${String( + dataBuffer, + Charsets.UTF_8 + )}" + ) + + if (responseNeeded) { + CentralLog.i(TAG, "Sending response offset: ${dataBuffer.size}") + bluetoothGattServer?.sendResponse( + device, + requestId, + GATT_SUCCESS, + dataBuffer.size, + value + ) + } + } + } else { + CentralLog.i(TAG, "no data from ${device.address}") + bluetoothGattServer?.sendResponse(device, requestId, GATT_SUCCESS, 0, null) + } + + if (!preparedWrite) { + CentralLog.i( + TAG, + "onCharacteristicWriteRequest - ${device.address} - preparedWrite: $preparedWrite" + ) + + saveDataSaved(device) + bluetoothGattServer?.sendResponse(device, requestId, GATT_SUCCESS, 0, null) + } + } + + if (device == null) { + CentralLog.e(TAG, "Write stopped - no device") + } + } + + override fun onExecuteWrite(device: BluetoothDevice, requestId: Int, execute: Boolean) { + super.onExecuteWrite(device, requestId, execute) + val data = writeDataPayload[device.address] + + data.let { dataBuffer -> + + if (dataBuffer != null) { + CentralLog.i( + TAG, + "onExecuteWrite - $requestId- ${device.address} - ${String( + dataBuffer, + Charsets.UTF_8 + )}" + ) + saveDataSaved(device) + bluetoothGattServer?.sendResponse(device, requestId, GATT_SUCCESS, 0, null) + + } else { + bluetoothGattServer?.sendResponse(device, requestId, GATT_FAILURE, 0, null) + } + } + } + + fun saveDataSaved(device: BluetoothDevice) { + val data = writeDataPayload[device.address] + + data?.let { + try { + val dataWritten = WriteRequestPayload.createReadRequestPayload(data) + device.let { + val centralDevice: CentralDevice? + + try { + centralDevice = CentralDevice(dataWritten.modelC, device.address) + val connectionRecord = ConnectionRecord( + version = dataWritten.v, + msg = dataWritten.msg, + org = dataWritten.org, + peripheral = TracerApp.asPeripheralDevice(), + central = centralDevice, + rssi = dataWritten.rssi, + txPower = dataWritten.txPower + ) + + Utils.broadcastStreetPassReceived( + context, + connectionRecord + ) + } catch (e: Throwable) { + CentralLog.e(TAG, "caught error here ${e.message}") + } + } + } catch (e: Throwable) { + CentralLog.e(TAG, "Failed to save write payload - ${e.message}") + } + + Utils.broadcastDeviceProcessed(context, device.address) + writeDataPayload.remove(device.address) + readPayloadMap.remove(device.address) + + } + } + } + + fun startServer(): Boolean { + + bluetoothGattServer = bluetoothManager.openGattServer(context, gattServerCallback) + + bluetoothGattServer?.let { + it.clearServices() + return true + } + return false + } + + fun addService(service: GattService) { + bluetoothGattServer?.addService(service.gattService) + } + + fun stop() { + try { + bluetoothGattServer?.clearServices() + bluetoothGattServer?.close() + } catch (e: Throwable) { + CentralLog.e(TAG, "GATT server can't be closed elegantly ${e.localizedMessage}") + } + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattService.kt b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattService.kt new file mode 100644 index 0000000..5787b94 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/bluetooth/gatt/GattService.kt @@ -0,0 +1,34 @@ +package au.gov.health.covidsafe.bluetooth.gatt + +import android.bluetooth.BluetoothGattCharacteristic +import android.bluetooth.BluetoothGattService +import android.content.Context +import java.util.* +import kotlin.properties.Delegates + +class GattService constructor(val context: Context, serviceUUIDString: String) { + + private var serviceUUID = UUID.fromString(serviceUUIDString) + + var gattService: BluetoothGattService by Delegates.notNull() + + private var devicePropertyCharacteristic: BluetoothGattCharacteristic by Delegates.notNull() + + init { + gattService = BluetoothGattService(serviceUUID, BluetoothGattService.SERVICE_TYPE_PRIMARY) + devicePropertyCharacteristic = BluetoothGattCharacteristic( + serviceUUID, + BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_WRITE, + BluetoothGattCharacteristic.PERMISSION_READ or BluetoothGattCharacteristic.PERMISSION_WRITE + ) + gattService.addCharacteristic(devicePropertyCharacteristic) + } + + fun setValue(value: String) { + setValue(value.toByteArray(Charsets.UTF_8)) + } + + fun setValue(value: ByteArray) { + devicePropertyCharacteristic.value = value + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/boot/StartOnBootReceiver.kt b/app/src/main/java/au/gov/health/covidsafe/boot/StartOnBootReceiver.kt new file mode 100644 index 0000000..d99bd0d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/boot/StartOnBootReceiver.kt @@ -0,0 +1,25 @@ +package au.gov.health.covidsafe.boot + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.logging.CentralLog + +class StartOnBootReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + + if (Intent.ACTION_BOOT_COMPLETED == intent.action) { + CentralLog.d("StartOnBootReceiver", "boot completed received") + + try { + CentralLog.d("StartOnBootReceiver", "Attempting to start service") + Utils.scheduleStartMonitoringService(context, 500) + } catch (e: Throwable) { + CentralLog.e("StartOnBootReceiver", e.localizedMessage) + e.printStackTrace() + } + + } + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/extensions/NavigationExtensions.kt b/app/src/main/java/au/gov/health/covidsafe/extensions/NavigationExtensions.kt new file mode 100644 index 0000000..7dccc56 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/extensions/NavigationExtensions.kt @@ -0,0 +1,8 @@ +package au.gov.health.covidsafe.extensions + +import android.os.Bundle +import androidx.fragment.app.Fragment +import androidx.navigation.Navigator +import androidx.navigation.fragment.NavHostFragment + +fun Fragment.navigateTo(actionId: Int, bundle: Bundle? = null, navigatorExtras: Navigator.Extras? = null) = NavHostFragment.findNavController(this).navigate(actionId, bundle, null, navigatorExtras) diff --git a/app/src/main/java/au/gov/health/covidsafe/extensions/NetworkExtensions.kt b/app/src/main/java/au/gov/health/covidsafe/extensions/NetworkExtensions.kt new file mode 100644 index 0000000..647f78c --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/extensions/NetworkExtensions.kt @@ -0,0 +1,13 @@ +package au.gov.health.covidsafe.extensions + +import android.content.Context +import android.net.ConnectivityManager +import android.net.NetworkCapabilities + +fun Context.isInternetAvailable(): Boolean { + val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager? + val capabilities = connectivityManager?.getNetworkCapabilities(connectivityManager.activeNetwork) + return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/extensions/PermissionExtensions.kt b/app/src/main/java/au/gov/health/covidsafe/extensions/PermissionExtensions.kt new file mode 100644 index 0000000..00173a2 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/extensions/PermissionExtensions.kt @@ -0,0 +1,137 @@ +package au.gov.health.covidsafe.extensions + +import android.Manifest.permission.ACCESS_FINE_LOCATION +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothManager +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.PowerManager +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.NotificationManagerCompat +import androidx.fragment.app.Fragment +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions +import pub.devrel.easypermissions.PermissionRequest +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.Utils + +const val REQUEST_ENABLE_BT = 123 +const val LOCATION = 345 +const val BATTERY_OPTIMISER = 789 + +fun Fragment.requestAllPermissions(onEndCallback: () -> Unit) { + if (isBlueToothEnabled() ?: true) { + requestFineLocationAndCheckBleSupportThenNextPermission(onEndCallback) + } else { + requestBlueToothPermissionThenNextPermission() + } +} + +fun Fragment.requestBlueToothPermissionThenNextPermission() { + val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) + startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT) +} + +fun Fragment.checkBLESupport() { + if (BluetoothAdapter.getDefaultAdapter()?.isMultipleAdvertisementSupported?.not() ?: false) { + activity?.let { + Utils.stopBluetoothMonitoringService(it) + } + } +} + +private fun Fragment.requestFineLocationAndCheckBleSupportThenNextPermission(onEndCallback: () -> Unit) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + activity?.let { + when { + EasyPermissions.hasPermissions(it, ACCESS_FINE_LOCATION) -> { + checkBLESupport() + excludeFromBatteryOptimization(onEndCallback) + } + else -> { + EasyPermissions.requestPermissions( + PermissionRequest.Builder(this, LOCATION, ACCESS_FINE_LOCATION) + .setRationale(R.string.permission_location_rationale) + .build()) + } + } + } + } else { + checkBLESupport() + } +} + +fun Fragment.excludeFromBatteryOptimization(onEndCallback: (() -> Unit)? = null) { + activity?.let { + val powerManager = + it.getSystemService(AppCompatActivity.POWER_SERVICE) as PowerManager + val packageName = it.packageName + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + val intent = Utils.getBatteryOptimizerExemptionIntent(packageName) + if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { + //check if there's any activity that can handle this + if (Utils.canHandleIntent(intent, it.packageManager)) { + this.startActivityForResult(intent, BATTERY_OPTIMISER) + } else { + //no way of handling battery optimizer + onEndCallback?.invoke() + } + } else { + onEndCallback?.invoke() + } + } + } + +} + +fun Fragment.isBlueToothEnabled(): Boolean? { + val bluetoothManager = activity?.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager? + return bluetoothManager?.adapter?.isEnabled +} + +fun Fragment.isPushNotificationEnabled(): Boolean? { + return activity?.let { activity -> + NotificationManagerCompat.from(activity).areNotificationsEnabled() + } +} + +fun Fragment.isFineLocationEnabled(): Boolean? { + return activity?.let { activity -> + EasyPermissions.hasPermissions(activity, ACCESS_FINE_LOCATION) + } +} + +fun Fragment.isNonBatteryOptimizationAllowed(): Boolean? { + return activity?.let { activity -> + val powerManager = activity.getSystemService(AppCompatActivity.POWER_SERVICE) as PowerManager? + val packageName = activity.packageName + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + powerManager?.isIgnoringBatteryOptimizations(packageName) ?: true + } else { + null + } + } ?: run { + null + } +} + +fun Fragment.askForLocationPermission() { + activity?.let { + when { + EasyPermissions.hasPermissions(it, ACCESS_FINE_LOCATION) -> { + + } + EasyPermissions.somePermissionPermanentlyDenied(this, listOf(ACCESS_FINE_LOCATION)) -> { + AppSettingsDialog.Builder(this).build().show() + } + else -> { + EasyPermissions.requestPermissions( + PermissionRequest.Builder(this, LOCATION, ACCESS_FINE_LOCATION) + .setRationale(R.string.permission_location_rationale) + .build()) + } + } + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/extensions/ViewExtensions.kt b/app/src/main/java/au/gov/health/covidsafe/extensions/ViewExtensions.kt new file mode 100644 index 0000000..6c67c4e --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/extensions/ViewExtensions.kt @@ -0,0 +1,30 @@ +package au.gov.health.covidsafe.extensions + +import android.text.SpannableString +import android.text.Spanned +import android.text.style.URLSpan +import android.widget.TextView +import androidx.core.content.ContextCompat +import au.gov.health.covidsafe.R + +fun TextView.toHyperlink(textToHyperLink: String? = null, onClick: () -> Unit) { + val text = this.text + val spannableString = SpannableString(text) + val startIndex = if (textToHyperLink.isNullOrEmpty()) { + 0 + } else { + text.indexOf(textToHyperLink) + } + val endIndex = if (textToHyperLink.isNullOrEmpty()) { + spannableString.length + } else { + text.indexOf(textToHyperLink) + textToHyperLink.length + } + spannableString.setSpan(URLSpan(""), startIndex, endIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + this.setText(spannableString, TextView.BufferType.SPANNABLE) + this.setLinkTextColor(ContextCompat.getColor(context, R.color.dark_green)) + this.setOnClickListener { + onClick.invoke() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/factory/NetworkFactory.kt b/app/src/main/java/au/gov/health/covidsafe/factory/NetworkFactory.kt new file mode 100644 index 0000000..17423b2 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/factory/NetworkFactory.kt @@ -0,0 +1,43 @@ +package au.gov.health.covidsafe.factory + +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.networking.service.AwsClient + +interface NetworkFactory { + companion object { + private val logging = HttpLoggingInterceptor() + .setLevel(HttpLoggingInterceptor.Level.BODY) + + val awsClient: AwsClient by lazy { + RetrofitServiceGenerator.createService(AwsClient::class.java) + } + + val okHttpClient: OkHttpClient by lazy { + val builder = OkHttpClient.Builder() + if (!builder.interceptors().contains(logging) && BuildConfig.DEBUG) { + builder.addInterceptor(logging) + } + builder.build() + } + } +} + +object RetrofitServiceGenerator { + private val builder = Retrofit.Builder() + .baseUrl(BuildConfig.BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + + private var retrofit = builder.build() + + fun createService( + serviceClass: Class): S { + builder.client(NetworkFactory.okHttpClient) + retrofit = builder.build() + + return retrofit.create(serviceClass) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/Either.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/Either.kt new file mode 100644 index 0000000..56c602e --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/Either.kt @@ -0,0 +1,14 @@ +package au.gov.health.covidsafe.interactor + +sealed class Either { + + inline fun fold(failed: (F) -> T, succeeded: (S) -> T): T = + when (this) { + is Failure -> failed(failure) + is Success -> succeeded(success) + } +} + +data class Failure(val failure: F) : Either() + +data class Success(val success: S) : Either() \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/UseCase.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/UseCase.kt new file mode 100644 index 0000000..4cefddb --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/UseCase.kt @@ -0,0 +1,76 @@ +package au.gov.health.covidsafe.interactor + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import kotlinx.coroutines.* +import retrofit2.Response +import kotlin.math.pow + +private val RETRIES_LIMIT = 3 + +abstract class UseCase(lifecycle: Lifecycle) : CoroutineScope by MainScope(), LifecycleObserver where Type : Any? { + + private var job: Job = Job() + + init { + lifecycle.addObserver(this) + } + + abstract suspend fun run(params: Params): Either + + operator fun invoke(params: Params, onSuccess: (Type) -> Unit, onFailure: (Exception) -> Unit) { + job.cancel() + job = launch(context = coroutineContext) { + val result = async(context = Dispatchers.IO) { + run(params) + } + result.await().fold( + failed = { onFailure(it) }, + succeeded = { onSuccess(it) } + ) + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + fun onStop() { + job.cancel() + } + + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun onDestroy() { + cancel() + } + + protected suspend fun retryRetrofitCall(call: () -> Response?): Response? { + var response = call.invoke() + var retryCount = 0 + while ((response == null || (!response.isSuccessful && response.code() != 403) || response.body() == null) && retryCount < RETRIES_LIMIT) { + val interval = 2.toDouble().pow(retryCount.toDouble()).toLong() * 1000 + delay(interval) + response = call.invoke() + retryCount++ + } + return response + } + + protected suspend fun retryOkhttpCall(call: () -> okhttp3.Response?): okhttp3.Response? { + var response = call.invoke() + var retryCount = 0 + while ((response == null || !response.isSuccessful || response.body == null) && retryCount < RETRIES_LIMIT) { + val interval = 2.toDouble().pow(retryCount.toDouble()).toLong() * 1000 + delay(interval) + response = call.invoke() + retryCount++ + } + return if (response != null && response.isSuccessful) { + response + } else { + null + + } + } + + object None + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetOnboardingOtp.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetOnboardingOtp.kt new file mode 100644 index 0000000..911c169 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetOnboardingOtp.kt @@ -0,0 +1,60 @@ +package au.gov.health.covidsafe.interactor.usecase + +import androidx.lifecycle.Lifecycle +import au.gov.health.covidsafe.interactor.Either +import au.gov.health.covidsafe.interactor.Failure +import au.gov.health.covidsafe.interactor.Success +import au.gov.health.covidsafe.interactor.UseCase +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.networking.request.OTPChallengeRequest +import au.gov.health.covidsafe.networking.response.OTPChallengeResponse +import au.gov.health.covidsafe.networking.service.AwsClient + +class GetOnboardingOtp(private val awsClient: AwsClient, lifecycle: Lifecycle) : UseCase(lifecycle) { + + private val TAG = this.javaClass.simpleName + + override suspend fun run(params: GetOtpParams): Either { + return try { + val response = awsClient.initiateAuth( + OTPChallengeRequest(params.phoneNumber, + params.deviceId, + params.postCode, + params.age, + params.name)).execute() + when { + response.code() == 200 -> { + response.body()?.let { body -> + CentralLog.d(TAG, "onCodeSent: ${response.body()?.challengeName}") + Success(body) + } ?: run { + CentralLog.d(TAG, "AWSAuthInvalidBody") + Failure(GetOnboardingOtpException.GetOtpServiceException(response.code())) + } + } + response.code() == 400 -> { + CentralLog.d(TAG, "AWSAuthInvalidNumber") + Failure(GetOnboardingOtpException.GetOtpInvalidNumberException) + } + else -> { + CentralLog.d(TAG, "AWSAuthServiceError") + Failure(GetOnboardingOtpException.GetOtpServiceException(response.code())) + } + } + } catch (e: Exception) { + CentralLog.d(TAG, "AWSAuthInvalidChallengeRequest", e) + Failure(GetOnboardingOtpException.GetOtpServiceException()) + } + } +} + +data class GetOtpParams(internal val phoneNumber: String, + internal val deviceId: String, + internal val postCode: String?, + internal val age: String?, + internal val name: String?) + +sealed class GetOnboardingOtpException : Exception() { + class GetOtpServiceException(val code: Int? = null) : GetOnboardingOtpException() + object GetOtpInvalidNumberException : GetOnboardingOtpException() +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetUploadOtp.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetUploadOtp.kt new file mode 100644 index 0000000..fab7186 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/GetUploadOtp.kt @@ -0,0 +1,34 @@ +package au.gov.health.covidsafe.interactor.usecase + +import androidx.lifecycle.Lifecycle +import au.gov.health.covidsafe.interactor.Either +import au.gov.health.covidsafe.interactor.Failure +import au.gov.health.covidsafe.interactor.Success +import au.gov.health.covidsafe.interactor.UseCase +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.networking.response.UploadOTPResponse +import au.gov.health.covidsafe.networking.service.AwsClient + +class GetUploadOtp(private val awsClient: AwsClient, lifecycle: Lifecycle) + : UseCase(lifecycle) { + + private val TAG = this.javaClass.simpleName + + override suspend fun run(params: String): Either { + return try { + val response = awsClient.requestUploadOtp("Bearer $params").execute() + return if (response.code() == 200) { + CentralLog.d(TAG, "onCodeUpload") + Success(response.body()) + } else { + Failure(GetUploadOtpException.GetUploadOtpServiceException(response.code())) + } + } catch (e: Exception) { + Failure(e) + } + } +} + +sealed class GetUploadOtpException : Exception() { + class GetUploadOtpServiceException(val code: Int?) : GetUploadOtpException() +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UpdateBroadcastMessageAndPerformScanWithExponentialBackOff.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UpdateBroadcastMessageAndPerformScanWithExponentialBackOff.kt new file mode 100644 index 0000000..7fba051 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UpdateBroadcastMessageAndPerformScanWithExponentialBackOff.kt @@ -0,0 +1,69 @@ +package au.gov.health.covidsafe.interactor.usecase + +import android.content.Context +import androidx.lifecycle.Lifecycle +import kotlinx.coroutines.delay +import retrofit2.Response +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.interactor.Either +import au.gov.health.covidsafe.interactor.Failure +import au.gov.health.covidsafe.interactor.Success +import au.gov.health.covidsafe.interactor.UseCase +import au.gov.health.covidsafe.networking.response.BroadcastMessageResponse +import au.gov.health.covidsafe.networking.service.AwsClient +import kotlin.math.pow + +class UpdateBroadcastMessageAndPerformScanWithExponentialBackOff(private val awsClient: AwsClient, + private val context: Context, + lifecycle: Lifecycle) : UseCase(lifecycle) { + + private val TAG = this.javaClass.simpleName + private val RETRIES_LIMIT = 3 + + override suspend fun run(params: Void?): Either { + val jwtToken = Preference.getEncrypterJWTToken(context) + return jwtToken?.let { jwtToken -> + var response = call(jwtToken) + var retryCount = 0 + while ((response == null || !response.isSuccessful || response.body() == null) && retryCount < RETRIES_LIMIT) { + val interval = 2.toDouble().pow(retryCount.toDouble()).toLong() * 1000 + delay(interval) + response = call(jwtToken) + retryCount++ + } + + if (response != null && response.isSuccessful) { + response.body()?.let { broadcastMessageResponse -> + if (broadcastMessageResponse.tempId.isNullOrEmpty()) { + Failure(Exception()) + } else { + val expiryTime = broadcastMessageResponse.expiryTime + val expiry = expiryTime?.toLongOrNull() ?: 0 + Preference.putExpiryTimeInMillis(context, expiry * 1000) + val refreshTime = broadcastMessageResponse.refreshTime + val refresh = refreshTime?.toLongOrNull() ?: 0 + Preference.putNextFetchTimeInMillis(context, refresh * 1000) + Utils.storeBroadcastMessage(context, broadcastMessageResponse.tempId) + Success(broadcastMessageResponse) + } + } ?: run { + Failure(Exception()) + } + } else { + Failure(Exception()) + } + } ?: run { + return Failure(Exception()) + } + } + + private fun call(jwtToken: String): Response? { + return try { + awsClient.getTempId("Bearer $jwtToken").execute() + } catch (e: Exception) { + null + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UploadData.kt b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UploadData.kt new file mode 100644 index 0000000..2f766b2 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/interactor/usecase/UploadData.kt @@ -0,0 +1,86 @@ +package au.gov.health.covidsafe.interactor.usecase + +import android.content.Context +import androidx.lifecycle.Lifecycle +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.interactor.Either +import au.gov.health.covidsafe.interactor.Failure +import au.gov.health.covidsafe.interactor.Success +import au.gov.health.covidsafe.interactor.UseCase +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.networking.service.AwsClient +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import au.gov.health.covidsafe.ui.upload.model.ExportData +import com.google.gson.Gson +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody + +class UploadData(private val awsClient: AwsClient, + private val okHttpClient: OkHttpClient, + private val context: Context?, + lifecycle: Lifecycle) + : UseCase(lifecycle) { + + private val TAG = this.javaClass.simpleName + + override suspend fun run(params: String): Either { + val jwtToken = Preference.getEncrypterJWTToken(context) + return jwtToken?.let { jwtToken -> + try { + val initialUploadResponse = retryRetrofitCall { + awsClient.initiateUpload("Bearer $jwtToken", params).execute() + } + if (initialUploadResponse == null) { + Failure(UploadDataException.UploadDataIncorrectPinException) + } else if (initialUploadResponse.isSuccessful) { + val uploadLink = initialUploadResponse.body()?.uploadLink + if (uploadLink.isNullOrEmpty()) { + Failure(Exception()) + } else { + zipAndUploadData(uploadLink) + } + } else if (initialUploadResponse.code() == 400) { + Failure(UploadDataException.UploadDataIncorrectPinException) + } else if (initialUploadResponse.code() == 403) { + Failure(UploadDataException.UploadDataJwtExpiredException) + } else { + Failure(Exception()) + } + } catch (e: Exception) { + Failure(e) + } + } ?: run { + return Failure(Exception()) + } + } + + private suspend fun zipAndUploadData(uploadLink: String): Either { + val exportedData = ExportData(StreetPassRecordStorage(TracerApp.AppContext).getAllRecords()) + CentralLog.d(TAG, "records: ${exportedData.records}") + + val jsonData = Gson().toJson(exportedData) + + val request = Request.Builder() + .url(uploadLink) + .put(jsonData.toRequestBody(null)) + .build() + return try { + val response = retryOkhttpCall { okHttpClient.newCall(request).execute() } + return if (response == null) { + Failure(Exception()) + } else { + Success(None) + } + } catch (e: Exception) { + Failure(Exception()) + } + } + +} + +sealed class UploadDataException : Exception() { + object UploadDataIncorrectPinException : UploadDataException() + object UploadDataJwtExpiredException : UploadDataException() +} diff --git a/app/src/main/java/au/gov/health/covidsafe/logging/CentralLog.kt b/app/src/main/java/au/gov/health/covidsafe/logging/CentralLog.kt new file mode 100644 index 0000000..be27312 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/logging/CentralLog.kt @@ -0,0 +1,85 @@ +package au.gov.health.covidsafe.logging + +import android.os.Build +import android.os.PowerManager +import android.util.Log +import au.gov.health.covidsafe.BuildConfig + +class CentralLog { + + companion object { + + private var pm: PowerManager? = null + + fun setPowerManager(powerManager: PowerManager) { + pm = powerManager + } + + private fun shouldLog(): Boolean { + return BuildConfig.DEBUG + } + + private fun getIdleStatus(): String { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return if (true == pm?.isDeviceIdleMode) { + " IDLE " + } else { + " NOT-IDLE " + } + } + return " NO-DOZE-FEATURE " + } + + fun d(tag: String, message: String) { + if (!shouldLog()) { + return + } + + Log.d(tag, getIdleStatus() + message) + } + + fun d(tag: String, message: String, e: Throwable?) { + if (!shouldLog()) { + return + } + + Log.d(tag, getIdleStatus() + message, e) + } + + + fun w(tag: String, message: String) { + if (!shouldLog()) { + return + } + + Log.w(tag, getIdleStatus() + message) + } + + fun i(tag: String, message: String) { + if (!shouldLog()) { + return + } + + Log.i(tag, getIdleStatus() + message) + } + + fun e(tag: String, message: String) { + if (!shouldLog()) { + return + } + + Log.e(tag, getIdleStatus() + message) + } + + fun e(tag: String, message: String, exception: Exception) { + if (!shouldLog()) { + return + } + + Log.e(tag, getIdleStatus() + message, exception) + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/request/AuthChallengeRequest.kt b/app/src/main/java/au/gov/health/covidsafe/networking/request/AuthChallengeRequest.kt new file mode 100644 index 0000000..ab0b0e0 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/request/AuthChallengeRequest.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.networking.request + +import androidx.annotation.Keep + +@Keep +data class AuthChallengeRequest(val session: String?, val code: String?) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/request/OTPChallengeRequest.kt b/app/src/main/java/au/gov/health/covidsafe/networking/request/OTPChallengeRequest.kt new file mode 100644 index 0000000..81c4c1b --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/request/OTPChallengeRequest.kt @@ -0,0 +1,10 @@ +package au.gov.health.covidsafe.networking.request + +import androidx.annotation.Keep + +@Keep +data class OTPChallengeRequest(val phone_number: String, + val device_id: String, + val postcode: String?, + val age: String?, + val name: String?) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/AuthChallengeResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/AuthChallengeResponse.kt new file mode 100644 index 0000000..c09d56c --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/AuthChallengeResponse.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.networking.response + +import androidx.annotation.Keep + +@Keep +data class AuthChallengeResponse(val token: String, val uuid: String, val token_expiry: String, val pin: String) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/BroadcastMessageResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/BroadcastMessageResponse.kt new file mode 100644 index 0000000..62772f5 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/BroadcastMessageResponse.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.networking.response + +import androidx.annotation.Keep + +@Keep +data class BroadcastMessageResponse(val tempId: String?, val expiryTime: String?, val refreshTime: String?) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/InitiateUploadResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/InitiateUploadResponse.kt new file mode 100644 index 0000000..0fcf7e8 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/InitiateUploadResponse.kt @@ -0,0 +1,9 @@ +package au.gov.health.covidsafe.networking.response + +import androidx.annotation.Keep +import com.google.gson.annotations.SerializedName + +@Keep +data class InitiateUploadResponse(@SerializedName("UploadLink") val uploadLink: String, + @SerializedName("ExpiresIn") val expiresIn: String, + @SerializedName("UploadPrefix") val uploadPrefix: String) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/OTPChallengeResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/OTPChallengeResponse.kt new file mode 100644 index 0000000..48ea669 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/OTPChallengeResponse.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.networking.response + +import androidx.annotation.Keep + +@Keep +data class OTPChallengeResponse(val session: String, val challengeName: String) diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/response/UploadOTPResponse.kt b/app/src/main/java/au/gov/health/covidsafe/networking/response/UploadOTPResponse.kt new file mode 100644 index 0000000..d9c6bba --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/response/UploadOTPResponse.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.networking.response + +import androidx.annotation.Keep + +@Keep +class UploadOTPResponse \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/networking/service/AwsClient.kt b/app/src/main/java/au/gov/health/covidsafe/networking/service/AwsClient.kt new file mode 100644 index 0000000..1514347 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/networking/service/AwsClient.kt @@ -0,0 +1,33 @@ +package au.gov.health.covidsafe.networking.service + +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.networking.request.AuthChallengeRequest +import au.gov.health.covidsafe.networking.request.OTPChallengeRequest +import au.gov.health.covidsafe.networking.response.* +import retrofit2.Call +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.Header +import retrofit2.http.POST + +interface AwsClient { + + @POST(BuildConfig.END_POINT_PREFIX + "/initiateAuth") + fun initiateAuth(@Body body : OTPChallengeRequest) : Call + + @POST(BuildConfig.END_POINT_PREFIX + "/respondToAuthChallenge") + fun respondToAuthChallenge(@Body body : AuthChallengeRequest) : Call + + @GET(BuildConfig.END_POINT_PREFIX + "/getTempId") + fun getTempId(@Header("Authorization") jwtToken: String?) : Call + + @GET(BuildConfig.END_POINT_PREFIX + "/initiateDataUpload") + fun initiateUpload(@Header("Authorization") jwtToken: String?,@Header("pin") pin : String) : Call + + @GET(BuildConfig.END_POINT_PREFIX + "/initiateDataUpload") + fun initiateReUpload(@Header("Authorization") jwtToken: String?): Call + + @GET(BuildConfig.END_POINT_PREFIX + "/requestUploadOtp") + fun requestUploadOtp(@Header("Authorization") jwtToken : String?) : Call + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/notifications/NotificationTemplates.kt b/app/src/main/java/au/gov/health/covidsafe/notifications/NotificationTemplates.kt new file mode 100644 index 0000000..e3596d1 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/notifications/NotificationTemplates.kt @@ -0,0 +1,114 @@ +package au.gov.health.covidsafe.notifications + +import android.app.Notification +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat +import au.gov.health.covidsafe.HomeActivity +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.DAILY_UPLOAD_NOTIFICATION_CODE +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_ACTIVITY +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_WIZARD_REQ_CODE + +class NotificationTemplates { + + companion object { + + fun getRunningNotification(context: Context, channel: String): Notification { + + val intent = Intent(context, HomeActivity::class.java) + + val activityPendingIntent = PendingIntent.getActivity( + context, PENDING_ACTIVITY, + intent, 0 + ) + + val builder = NotificationCompat.Builder(context, channel) + .setContentTitle(context.getText(R.string.service_ok_title)) + .setContentText(context.getText(R.string.service_ok_body)) + .setOngoing(true) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setSmallIcon(R.drawable.ic_notification_icon) + .setContentIntent(activityPendingIntent) + .setTicker(context.getText(R.string.service_ok_body)) + .setStyle(NotificationCompat.BigTextStyle().bigText(context.getText(R.string.service_ok_body))) + .setWhen(System.currentTimeMillis()) + .setSound(null) + .setVibrate(null) + .setColor(ContextCompat.getColor(context, R.color.notification_tint)) + + return builder.build() + } + + fun lackingThingsNotification(context: Context, channel: String): Notification { + + + val intent = Intent(context, HomeActivity::class.java) + intent.putExtra("page", 3) + + val activityPendingIntent = PendingIntent.getActivity( + context, PENDING_WIZARD_REQ_CODE, + intent, 0 + ) + + val builder = NotificationCompat.Builder(context, channel) + .setContentTitle(context.getText(R.string.service_not_ok_title)) + .setContentText(context.getText(R.string.service_not_ok_body)) + .setStyle(NotificationCompat.BigTextStyle().bigText(context.getText(R.string.service_not_ok_body))) + + .setOngoing(true) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setSmallIcon(R.drawable.ic_notification_warning) + .setTicker(context.getText(R.string.service_not_ok_body)) + .addAction( + R.drawable.ic_notification_setting, + context.getText(R.string.service_not_ok_action), + activityPendingIntent + ) + .setContentIntent(activityPendingIntent) + .setWhen(System.currentTimeMillis()) + .setSound(null) + .setVibrate(null) + .setColor(ContextCompat.getColor(context, R.color.notification_tint)) + + return builder.build() + } + + fun getUploadReminder(context: Context, channel: String): Notification { + val intent = Intent(context, HomeActivity::class.java) + intent.putExtra("uploadNotification", true) + + val activityPendingIntent = PendingIntent.getActivity( + context, DAILY_UPLOAD_NOTIFICATION_CODE, + intent, PendingIntent.FLAG_UPDATE_CURRENT + ) + + val builder = NotificationCompat.Builder(context, channel) + .setContentTitle(context.getText(R.string.upload_your_data_title)) + .setContentText(context.getText(R.string.upload_your_data_description)) + .setOngoing(false) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setSmallIcon(R.drawable.ic_notification_icon) + .setTicker(context.getText(R.string.upload_your_data_description)) + .setStyle(NotificationCompat.BigTextStyle().bigText(context.getText(R.string.upload_your_data_description))) + .setAutoCancel(true) + + .addAction( + R.drawable.ic_notification_setting, + context.getText(R.string.upload_data_action), + activityPendingIntent + ) + .setContentIntent(activityPendingIntent) + .setWhen(System.currentTimeMillis()) + .setSound(null) + .setVibrate(null) + .setColor(ContextCompat.getColor(context, R.color.notification_tint)) + + return builder.build() + } + + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/receivers/PrivacyCleanerReceiver.kt b/app/src/main/java/au/gov/health/covidsafe/receivers/PrivacyCleanerReceiver.kt new file mode 100644 index 0000000..4cbdfff --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/receivers/PrivacyCleanerReceiver.kt @@ -0,0 +1,64 @@ +package au.gov.health.covidsafe.receivers + +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.PENDING_PRIVACY_CLEANER_CODE +import au.gov.health.covidsafe.services.SensorMonitoringService.Companion.TAG +import au.gov.health.covidsafe.status.persistence.StatusRecordStorage +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import java.util.* +import kotlin.coroutines.CoroutineContext + +class PrivacyCleanerReceiver : BroadcastReceiver(), CoroutineScope { + + private val TAG = this.javaClass.simpleName + + private var job: Job = Job() + + override val coroutineContext: CoroutineContext + get() = Dispatchers.Default + job + + companion object { + + private fun getIntent(context: Context, requestCode: Int): PendingIntent? { + val intent = Intent(context, PrivacyCleanerReceiver::class.java) + return PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT) + } + + fun startAlarm(context: Context) { + val pendingIntent = getIntent(context, PENDING_PRIVACY_CLEANER_CODE) + val alarm = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + + alarm.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), AlarmManager.INTERVAL_DAY, pendingIntent) + } + + suspend fun cleanDb(context: Context) { + val twentyOneDaysAgo = Calendar.getInstance() + twentyOneDaysAgo.set(Calendar.HOUR_OF_DAY, 23) + twentyOneDaysAgo.set(Calendar.MINUTE, 59) + twentyOneDaysAgo.set(Calendar.SECOND, 59) + twentyOneDaysAgo.add(Calendar.DATE, -21) + + val countStreetDeleted = StreetPassRecordStorage(context).deleteDataOlderThan(twentyOneDaysAgo.timeInMillis) + val countStatusDeleted = StatusRecordStorage(context).deleteDataOlderThan(twentyOneDaysAgo.timeInMillis) + + CentralLog.i(TAG, "Street info deleted count : $countStreetDeleted") + CentralLog.i(TAG, "Status info deleted count : $countStatusDeleted") + } + } + + override fun onReceive(context: Context, intent: Intent) { + launch { + cleanDb(context) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/receivers/UpgradeReceiver.kt b/app/src/main/java/au/gov/health/covidsafe/receivers/UpgradeReceiver.kt new file mode 100644 index 0000000..3502ff6 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/receivers/UpgradeReceiver.kt @@ -0,0 +1,23 @@ +package au.gov.health.covidsafe.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.logging.CentralLog + +class UpgradeReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context?, intent: Intent?) { + + try { + if (Intent.ACTION_MY_PACKAGE_REPLACED != intent!!.action) return + context?.let { + CentralLog.i("UpgradeReceiver", "Starting service from upgrade receiver") + Utils.startBluetoothMonitoringService(context) + } + } catch (e: Exception) { + CentralLog.e("UpgradeReceiver", "Unable to handle upgrade: ${e.localizedMessage}") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/scheduler/Scheduler.kt b/app/src/main/java/au/gov/health/covidsafe/scheduler/Scheduler.kt new file mode 100644 index 0000000..381163d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/scheduler/Scheduler.kt @@ -0,0 +1,53 @@ +package au.gov.health.covidsafe.scheduler + +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.SystemClock + +object Scheduler { + + fun scheduleServiceIntent( + requestCode: Int, + context: Context, + intent: Intent, + timeFromNowInMillis: Long + ) { + val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager + val alarmIntent = PendingIntent.getService( + context, + requestCode, + intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + alarmMgr.setExactAndAllowWhileIdle( + AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + timeFromNowInMillis, alarmIntent + ) + + } else { + alarmMgr.set( + AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + timeFromNowInMillis, alarmIntent + ) + } + + } + + fun cancelServiceIntent(requestCode: Int, context: Context, intent: Intent) { + val alarmIntent = + PendingIntent.getService( + context, + requestCode, + intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + alarmIntent.cancel() + } + + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/services/BluetoothMonitoringService.kt b/app/src/main/java/au/gov/health/covidsafe/services/BluetoothMonitoringService.kt new file mode 100644 index 0000000..8779923 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/services/BluetoothMonitoringService.kt @@ -0,0 +1,668 @@ +package au.gov.health.covidsafe.services + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothManager +import android.content.* +import android.os.Build +import android.os.IBinder +import android.os.PowerManager +import androidx.annotation.Keep +import androidx.lifecycle.LifecycleService +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.bluetooth.BLEAdvertiser +import au.gov.health.covidsafe.bluetooth.gatt.ACTION_RECEIVED_STATUS +import au.gov.health.covidsafe.bluetooth.gatt.ACTION_RECEIVED_STREETPASS +import au.gov.health.covidsafe.bluetooth.gatt.STATUS +import au.gov.health.covidsafe.bluetooth.gatt.STREET_PASS +import au.gov.health.covidsafe.factory.NetworkFactory +import au.gov.health.covidsafe.interactor.usecase.UpdateBroadcastMessageAndPerformScanWithExponentialBackOff +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.notifications.NotificationTemplates +import au.gov.health.covidsafe.receivers.PrivacyCleanerReceiver +import au.gov.health.covidsafe.status.Status +import au.gov.health.covidsafe.status.persistence.StatusRecord +import au.gov.health.covidsafe.status.persistence.StatusRecordStorage +import au.gov.health.covidsafe.streetpass.ConnectionRecord +import au.gov.health.covidsafe.streetpass.StreetPassScanner +import au.gov.health.covidsafe.streetpass.StreetPassServer +import au.gov.health.covidsafe.streetpass.StreetPassWorker +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import pub.devrel.easypermissions.EasyPermissions +import java.lang.ref.WeakReference +import kotlin.coroutines.CoroutineContext +@Keep +class BluetoothMonitoringService : LifecycleService(), CoroutineScope { + + private var mNotificationManager: NotificationManager? = null + + @Keep + private lateinit var serviceUUID: String + + private var streetPassServer: StreetPassServer? = null + private var streetPassScanner: StreetPassScanner? = null + private var advertiser: BLEAdvertiser? = null + + private var worker: StreetPassWorker? = null + + private val streetPassReceiver = StreetPassReceiver() + private val statusReceiver = StatusReceiver() + private val bluetoothStatusReceiver = BluetoothStatusReceiver() + + private lateinit var streetPassRecordStorage: StreetPassRecordStorage + private lateinit var statusRecordStorage: StatusRecordStorage + + private var job: Job = Job() + + override val coroutineContext: CoroutineContext + get() = Dispatchers.Main + job + + private lateinit var commandHandler: CommandHandler + + private lateinit var mService: SensorMonitoringService + private var mBound: Boolean = false + + private lateinit var localBroadcastManager: LocalBroadcastManager + + private val awsClient = NetworkFactory.awsClient + + /** Defines callbacks for service binding, passed to bindService() */ + private val connection = object : ServiceConnection { + + override fun onServiceConnected(className: ComponentName, service: IBinder) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + val binder = service as SensorMonitoringService.LocalBinder + mService = binder.getService() + mBound = true + } + + override fun onServiceDisconnected(arg0: ComponentName) { + mBound = false + } + } + + override fun onCreate() { + super.onCreate() + localBroadcastManager = LocalBroadcastManager.getInstance(this) + setup() + } + + private fun setup() { + val pm = getSystemService(Context.POWER_SERVICE) as PowerManager + + CentralLog.setPowerManager(pm) + + commandHandler = CommandHandler(WeakReference(this)) + + CentralLog.d(TAG, "Creating service - BluetoothMonitoringService") + serviceUUID = BuildConfig.BLE_SSID + + worker = StreetPassWorker(this.applicationContext) + + unregisterReceivers() + registerReceivers() + + streetPassRecordStorage = StreetPassRecordStorage(this.applicationContext) + statusRecordStorage = StatusRecordStorage(this.applicationContext) + PrivacyCleanerReceiver.startAlarm(this.applicationContext) + setupNotifications() + broadcastMessage = Utils.retrieveBroadcastMessage(this.applicationContext) + } + + fun teardown() { + streetPassServer?.tearDown() + streetPassServer = null + + streetPassScanner?.stopScan() + streetPassScanner = null + + commandHandler.removeCallbacksAndMessages(null) + + Utils.cancelBMUpdateCheck(this.applicationContext) + Utils.cancelNextScan(this.applicationContext) + Utils.cancelNextAdvertise(this.applicationContext) + } + + private fun setupNotifications() { + + val mNotificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + + // Android O requires a Notification Channel. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val name = CHANNEL_SERVICE + // Create the channel for the notification + val mChannel = + NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW) + mChannel.enableLights(false) + mChannel.enableVibration(true) + mChannel.vibrationPattern = longArrayOf(0L) + mChannel.setSound(null, null) + mChannel.setShowBadge(false) + + // Set the Notification Channel for the Notification Manager. + mNotificationManager.createNotificationChannel(mChannel) + } + } + + private fun hasLocationPermissions(): Boolean { + val perms = Utils.getRequiredPermissions() + return EasyPermissions.hasPermissions(this.applicationContext, *perms) + } + + private fun isBluetoothEnabled(): Boolean { + var btOn = false + val bluetoothAdapter: BluetoothAdapter? by lazy(LazyThreadSafetyMode.NONE) { + val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + bluetoothManager.adapter + } + + bluetoothAdapter?.let { + btOn = it.isEnabled + } + return btOn + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + super.onStartCommand(intent, flags, startId) + CentralLog.i(TAG, "Service onStartCommand") + + // Bind to LocalService + Intent(this.applicationContext, SensorMonitoringService::class.java).also { intent -> + bindService(intent, connection, Context.BIND_AUTO_CREATE) + } + + //check for permissions + if (!hasLocationPermissions() || !isBluetoothEnabled()) { + CentralLog.i( + TAG, + "location permission: ${hasLocationPermissions()} bluetooth: ${isBluetoothEnabled()}" + ) + val notif = + NotificationTemplates.lackingThingsNotification(this.applicationContext, CHANNEL_ID) + startForeground(NOTIFICATION_ID, notif) + return START_STICKY + } + + intent?.let { + val cmd = intent.getIntExtra(COMMAND_KEY, Command.INVALID.index) + runService(Command.findByValue(cmd)) + + return START_STICKY + } + + if (intent == null) { + CentralLog.e(TAG, "Nothing in intent @ onStartCommand") + commandHandler.startBluetoothMonitoringService() + } + + // Tells the system to not try to recreate the service after it has been killed. + return START_STICKY + } + + fun runService(cmd: Command?) { + + CentralLog.i(TAG, "Command is:${cmd?.string}") + + //check for permissions + if (!hasLocationPermissions() || !isBluetoothEnabled()) { + CentralLog.i( + TAG, + "location permission: ${hasLocationPermissions()} bluetooth: ${isBluetoothEnabled()}" + ) + val notif = + NotificationTemplates.lackingThingsNotification(this.applicationContext, CHANNEL_ID) + startForeground(NOTIFICATION_ID, notif) + return + } + + when (cmd) { + Command.ACTION_START -> { + setupService() + actionStart() + Utils.scheduleNextHealthCheck(this.applicationContext, healthCheckInterval) + Utils.scheduleBMUpdateCheck(this.applicationContext, bmCheckInterval) + } + + Command.ACTION_SCAN -> { + actionScan() + } + + Command.ACTION_ADVERTISE -> { + actionAdvertise() + } + + Command.ACTION_UPDATE_BM -> { + actionUpdateBm() + } + + Command.ACTION_STOP -> { + actionStop() + } + + Command.ACTION_SELF_CHECK -> { + actionHealthCheck() + } + + else -> CentralLog.i(TAG, "Invalid command: $cmd. Nothing to do") + } + } + + private fun actionStop() { + stopForeground(true) + stopSelf() + CentralLog.w(TAG, "Service Stopping") + } + + private fun actionHealthCheck() { + Utils.scheduleNextHealthCheck(this.applicationContext, healthCheckInterval) + performHealthCheck() + } + + private fun actionStart() { + if (Preference.isOnBoarded(this)) { + CentralLog.d(TAG, "Service Starting ") + + startForeground( + NOTIFICATION_ID, + NotificationTemplates.getRunningNotification( + this.applicationContext, + CHANNEL_ID + ) + ) + //ensure BM is ready here + if (Preference.isOnBoarded(this) && Utils.needToUpdate(this.applicationContext) || broadcastMessage == null) { + //need to pull new BM + + UpdateBroadcastMessageAndPerformScanWithExponentialBackOff(awsClient, applicationContext, lifecycle).invoke( + params = null, + onSuccess = { + broadcastMessage = it.tempId + setupCycles() + }, + onFailure = { + } + ) + } else if (Preference.isOnBoarded(this)) { + setupCycles() + } + } + } + + + private fun actionUpdateBm() { + Utils.scheduleBMUpdateCheck(this.applicationContext, bmCheckInterval) + + CentralLog.i(TAG, "checking need to update BM") + if (Preference.isOnBoarded(this) && Utils.needToUpdate(this.applicationContext) || broadcastMessage == null) { + //need to pull new BM + + UpdateBroadcastMessageAndPerformScanWithExponentialBackOff(awsClient, applicationContext, lifecycle).invoke( + params = null, + onSuccess = { + broadcastMessage = it.tempId + }, + onFailure = { + } + ) + } else { + CentralLog.i(TAG, "Don't need to update bm") + } + + } + + private fun calcPhaseShift(min: Long, max: Long): Long { + return (min + (Math.random() * (max - min))).toLong() + } + + private fun actionScan() { + if (Preference.isOnBoarded(this) && Utils.needToUpdate(this.applicationContext) || broadcastMessage == null) { + //need to pull new BM + UpdateBroadcastMessageAndPerformScanWithExponentialBackOff(awsClient, applicationContext, lifecycle).invoke( + params = null, + onSuccess = { + broadcastMessage = it.tempId + performScanAndScheduleNextScan() + }, + onFailure = { + } + ) + } else if (Preference.isOnBoarded(this)) { + performScanAndScheduleNextScan() + } + } + + private fun actionAdvertise() { + setupAdvertiser() + + if (isBluetoothEnabled()) { + advertiser?.startAdvertising(advertisingDuration) + } else { + CentralLog.w(TAG, "Unable to start advertising, bluetooth is off") + } + + commandHandler.scheduleNextAdvertise(advertisingDuration + advertisingGap) + } + + private fun setupService() { + streetPassServer = + streetPassServer ?: StreetPassServer(this.applicationContext, serviceUUID) + setupScanner() + setupAdvertiser() + } + + private fun setupScanner() { + streetPassScanner = streetPassScanner ?: StreetPassScanner( + this, + serviceUUID, + scanDuration + ) + } + + private fun setupAdvertiser() { + advertiser = advertiser ?: BLEAdvertiser(serviceUUID) + } + + private fun setupCycles() { + setupScanCycles() + setupAdvertisingCycles() + } + + private fun setupScanCycles() { + actionScan() + } + + private fun setupAdvertisingCycles() { + actionAdvertise() + } + + private fun performScanAndScheduleNextScan() { + + setupScanner() + + commandHandler.scheduleNextScan( + scanDuration + calcPhaseShift( + minScanInterval, + maxScanInterval + ) + ) + + startScan() + + } + + private fun startScan() { + + if (isBluetoothEnabled()) { + + streetPassScanner?.let { scanner -> + if (!scanner.isScanning()) { + scanner.startScan() + } else { + CentralLog.e(TAG, "Already scanning!") + } + } + } else { + CentralLog.w(TAG, "Unable to start scan - bluetooth is off") + } + } + + private fun performHealthCheck() { + + CentralLog.i(TAG, "Performing self diagnosis") + + if (!hasLocationPermissions() || !isBluetoothEnabled()) { + CentralLog.i(TAG, "no location permission") + val notif = + NotificationTemplates.lackingThingsNotification(this.applicationContext, CHANNEL_ID) + startForeground(NOTIFICATION_ID, notif) + return + } + + startForeground( + NOTIFICATION_ID, + NotificationTemplates.getRunningNotification( + this.applicationContext, + CHANNEL_ID + ) + ) + + //ensure our service is there + setupService() + + if (!commandHandler.hasScanScheduled()) { + CentralLog.w(TAG, "Missing Scan Schedule - rectifying") + setupScanCycles() + } else { + CentralLog.w(TAG, "Scan Schedule present") + } + + if (!commandHandler.hasAdvertiseScheduled()) { + CentralLog.w(TAG, "Missing Advertise Schedule - rectifying") + setupAdvertisingCycles() + } else { + CentralLog.w( + TAG, + "Advertise Schedule present. Should be advertising?: ${advertiser?.shouldBeAdvertising + ?: false}. Is Advertising?: ${advertiser?.isAdvertising ?: false}" + ) + } + } + + override fun onDestroy() { + super.onDestroy() + CentralLog.i(TAG, "BluetoothMonitoringService destroyed - tearing down") + + teardown() + unregisterReceivers() + + worker?.terminateConnections() + worker?.unregisterReceivers() + + job.cancel() + + if (mBound) { + unbindService(connection) + mBound = false + } + + CentralLog.i(TAG, "BluetoothMonitoringService destroyed") + } + + private fun registerReceivers() { + val recordAvailableFilter = IntentFilter(ACTION_RECEIVED_STREETPASS) + localBroadcastManager.registerReceiver(streetPassReceiver, recordAvailableFilter) + + val statusReceivedFilter = IntentFilter(ACTION_RECEIVED_STATUS) + localBroadcastManager.registerReceiver(statusReceiver, statusReceivedFilter) + + val bluetoothStatusReceivedFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + registerReceiver(bluetoothStatusReceiver, bluetoothStatusReceivedFilter) + + CentralLog.i(TAG, "Receivers registered") + } + + private fun unregisterReceivers() { + try { + localBroadcastManager.unregisterReceiver(streetPassReceiver) + } catch (e: Throwable) { + CentralLog.w(TAG, "streetPassReceiver is not registered?") + } + + try { + localBroadcastManager.unregisterReceiver(statusReceiver) + } catch (e: Throwable) { + CentralLog.w(TAG, "statusReceiver is not registered?") + } + + try { + unregisterReceiver(bluetoothStatusReceiver) + } catch (e: Throwable) { + CentralLog.w(TAG, "bluetoothStatusReceiver is not registered?") + } + } + + inner class BluetoothStatusReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context?, intent: Intent?) { + intent?.let { + val action = intent.action + if (action == BluetoothAdapter.ACTION_STATE_CHANGED) { + + when (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)) { + BluetoothAdapter.STATE_TURNING_OFF -> { + CentralLog.d(TAG, "BluetoothAdapter.STATE_TURNING_OFF") + val notif = NotificationTemplates.lackingThingsNotification( + this@BluetoothMonitoringService.applicationContext, + CHANNEL_ID + ) + startForeground(NOTIFICATION_ID, notif) + teardown() + } + BluetoothAdapter.STATE_OFF -> { + CentralLog.d(TAG, "BluetoothAdapter.STATE_OFF") + } + BluetoothAdapter.STATE_TURNING_ON -> { + CentralLog.d(TAG, "BluetoothAdapter.STATE_TURNING_ON") + } + BluetoothAdapter.STATE_ON -> { + CentralLog.d(TAG, "BluetoothAdapter.STATE_ON") + Utils.startBluetoothMonitoringService(this@BluetoothMonitoringService.applicationContext) + } + } + } + } + } + } + + inner class StreetPassReceiver : BroadcastReceiver() { + + private val TAG = "StreetPassReceiver" + + override fun onReceive(context: Context, intent: Intent) { + + if (ACTION_RECEIVED_STREETPASS == intent.action) { + val connRecord: ConnectionRecord = intent.getParcelableExtra(STREET_PASS) + CentralLog.d( + TAG, + "StreetPass received: $connRecord" + ) + + if (connRecord.msg.isNotEmpty()) { + + if (mBound) { + val proximity = mService.proximity + val light = mService.light + CentralLog.d( + TAG, + "Sensor values just before saving StreetPassRecord: proximity=$proximity light=$light" + ) + } + + val record = StreetPassRecord( + v = connRecord.version, + msg = connRecord.msg, + org = connRecord.org, + modelP = connRecord.peripheral.modelP, + modelC = connRecord.central.modelC, + rssi = connRecord.rssi, + txPower = connRecord.txPower + ) + + + launch{ + CentralLog.d( + TAG, + "Coroutine - Saving StreetPassRecord: ${Utils.getDate(record.timestamp)} $record") + + streetPassRecordStorage.saveRecord(record) + } + } + } + } + } + + inner class StatusReceiver : BroadcastReceiver() { + private val TAG = "StatusReceiver" + + override fun onReceive(context: Context, intent: Intent) { + + if (ACTION_RECEIVED_STATUS == intent.action) { + val statusRecord: Status = intent.getParcelableExtra(STATUS) + CentralLog.d(TAG, "Status received: ${statusRecord.msg}") + + if (statusRecord.msg.isNotEmpty()) { + val statusRecord = StatusRecord(statusRecord.msg) + launch { + statusRecordStorage.saveRecord(statusRecord) + } + } + } + } + } + + enum class Command(val index: Int, val string: String) { + INVALID(-1, "INVALID"), + ACTION_START(0, "START"), + ACTION_SCAN(1, "SCAN"), + ACTION_STOP(2, "STOP"), + ACTION_ADVERTISE(3, "ADVERTISE"), + ACTION_SELF_CHECK(4, "SELF_CHECK"), + ACTION_UPDATE_BM(5, "UPDATE_BM"); + + companion object { + private val types = values().associate { it.index to it } + fun findByValue(value: Int) = types[value] + } + } + + companion object { + + private const val TAG = "BTMService" + + private const val NOTIFICATION_ID = BuildConfig.SERVICE_FOREGROUND_NOTIFICATION_ID + private const val CHANNEL_ID = BuildConfig.SERVICE_FOREGROUND_CHANNEL_ID + const val CHANNEL_SERVICE = BuildConfig.SERVICE_FOREGROUND_CHANNEL_NAME + + const val COMMAND_KEY = "${BuildConfig.APPLICATION_ID}_CMD" + + const val PENDING_ACTIVITY = 5 + const val PENDING_START = 6 + const val PENDING_SCAN_REQ_CODE = 7 + const val PENDING_ADVERTISE_REQ_CODE = 8 + const val PENDING_HEALTH_CHECK_CODE = 9 + const val PENDING_WIZARD_REQ_CODE = 10 + const val PENDING_BM_UPDATE = 11 + const val PENDING_PRIVACY_CLEANER_CODE = 12 + const val DAILY_UPLOAD_NOTIFICATION_CODE = 13 + + + var broadcastMessage: String? = null + + const val scanDuration: Long = BuildConfig.SCAN_DURATION + const val minScanInterval: Long = BuildConfig.MIN_SCAN_INTERVAL + const val maxScanInterval: Long = BuildConfig.MAX_SCAN_INTERVAL + + const val advertisingDuration: Long = BuildConfig.ADVERTISING_DURATION + const val advertisingGap: Long = BuildConfig.ADVERTISING_INTERVAL + + const val maxQueueTime: Long = BuildConfig.MAX_QUEUE_TIME + const val bmCheckInterval: Long = BuildConfig.BM_CHECK_INTERVAL + const val healthCheckInterval: Long = BuildConfig.HEALTH_CHECK_INTERVAL + + const val connectionTimeout: Long = BuildConfig.CONNECTION_TIMEOUT + + const val blacklistDuration: Long = BuildConfig.BLACKLIST_DURATION + + } + + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/services/CommandHandler.kt b/app/src/main/java/au/gov/health/covidsafe/services/CommandHandler.kt new file mode 100644 index 0000000..391b0b4 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/services/CommandHandler.kt @@ -0,0 +1,55 @@ +package au.gov.health.covidsafe.services + +import android.os.Handler +import android.os.Message +import java.lang.ref.WeakReference + +class CommandHandler(val service: WeakReference) : Handler() { + override fun handleMessage(msg: Message?) { + msg?.let { + val cmd = msg.what + service.get()?.runService(BluetoothMonitoringService.Command.findByValue(cmd)) + } + } + + private fun sendCommandMsg(cmd: BluetoothMonitoringService.Command, delay: Long) { + val msg = Message.obtain(this, cmd.index) + sendMessageDelayed(msg, delay) + } + + private fun sendCommandMsg(cmd: BluetoothMonitoringService.Command) { + val msg = obtainMessage(cmd.index) + msg.arg1 = cmd.index + sendMessage(msg) + } + + fun startBluetoothMonitoringService() { + sendCommandMsg(BluetoothMonitoringService.Command.ACTION_START) + } + + fun scheduleNextScan(timeInMillis: Long) { + cancelNextScan() + sendCommandMsg(BluetoothMonitoringService.Command.ACTION_SCAN, timeInMillis) + } + + private fun cancelNextScan() { + removeMessages(BluetoothMonitoringService.Command.ACTION_SCAN.index) + } + + fun hasScanScheduled(): Boolean { + return hasMessages(BluetoothMonitoringService.Command.ACTION_SCAN.index) + } + + fun scheduleNextAdvertise(timeInMillis: Long) { + cancelNextAdvertise() + sendCommandMsg(BluetoothMonitoringService.Command.ACTION_ADVERTISE, timeInMillis) + } + + private fun cancelNextAdvertise() { + removeMessages(BluetoothMonitoringService.Command.ACTION_ADVERTISE.index) + } + + fun hasAdvertiseScheduled(): Boolean { + return hasMessages(BluetoothMonitoringService.Command.ACTION_ADVERTISE.index) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/services/SensorMonitoringService.kt b/app/src/main/java/au/gov/health/covidsafe/services/SensorMonitoringService.kt new file mode 100644 index 0000000..6c4abbf --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/services/SensorMonitoringService.kt @@ -0,0 +1,96 @@ +package au.gov.health.covidsafe.services + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.hardware.Sensor +import android.hardware.SensorEvent +import android.hardware.SensorEventListener +import android.hardware.SensorManager +import android.os.Binder +import android.os.IBinder +import au.gov.health.covidsafe.logging.CentralLog +import kotlin.math.sqrt + +class SensorMonitoringService : Service(), SensorEventListener { + private lateinit var sensorManager: SensorManager + private var _light: FloatArray? = null + private var _proximity: FloatArray? = null + private val binder = LocalBinder() + + override fun onCreate() { + super.onCreate() + sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager + + val proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY) + val lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) + + if (proximitySensor != null) { + CentralLog.d(TAG, "Proximity sensor: $proximitySensor") + sensorManager.registerListener(this, proximitySensor, SENSOR_DELAY_SUPER_SLOW) + + } else { + CentralLog.d(TAG, "Proximity sensor not available") + } + + if (lightSensor != null) { + CentralLog.d(TAG, "Light sensor: $lightSensor") + sensorManager.registerListener(this, lightSensor, SENSOR_DELAY_SUPER_SLOW) + } else { + CentralLog.d(TAG, "Light sensor not available") + } + + CentralLog.d(TAG, "SensorMonitoringService started") + } + + override fun onDestroy() { + sensorManager.unregisterListener(this) + CentralLog.d(TAG, "SensorMonitoringService destroyed") + super.onDestroy() + } + + inner class LocalBinder : Binder() { + fun getService(): SensorMonitoringService = this@SensorMonitoringService + } + + override fun onBind(intent: Intent): IBinder { + return binder + } + + override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { + CentralLog.d(TAG, "Sensor accuracy changed! $sensor") + } + + override fun onSensorChanged(event: SensorEvent) { + when (event.sensor.type) { + Sensor.TYPE_PROXIMITY -> { + _proximity = event.values + } + Sensor.TYPE_LIGHT -> { + _light = event.values + } + else -> { + CentralLog.w(TAG, "Unexpected sensor type changed: ${event.sensor.type}") + } + } + } + + val proximity + get() = if (_proximity != null) { + sqrt((_proximity as FloatArray).reduce { acc: Float, n: Float -> acc + n * n }) + } else { + -1.0f + } + + val light + get() = if (_light != null) { + sqrt((_light as FloatArray).reduce { acc: Float, n: Float -> acc + n * n }) + } else { + -1.0f + } + + companion object { + const val TAG = "SensorMonitoringService" + const val SENSOR_DELAY_SUPER_SLOW = 3_000_000 + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/status/Status.kt b/app/src/main/java/au/gov/health/covidsafe/status/Status.kt new file mode 100644 index 0000000..eac69ac --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/status/Status.kt @@ -0,0 +1,9 @@ +package au.gov.health.covidsafe.status + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +data class Status( + val msg: String +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecord.kt b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecord.kt new file mode 100644 index 0000000..6739728 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecord.kt @@ -0,0 +1,20 @@ +package au.gov.health.covidsafe.status.persistence + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "status_table") +class StatusRecord constructor( + + @ColumnInfo(name = "msg") + var msg: String +) { + + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") + var id: Int = 0 + + @ColumnInfo(name = "timestamp") + var timestamp: Long = System.currentTimeMillis() +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordDao.kt b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordDao.kt new file mode 100644 index 0000000..4465d59 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordDao.kt @@ -0,0 +1,32 @@ +package au.gov.health.covidsafe.status.persistence + +import androidx.lifecycle.LiveData +import androidx.room.* +import androidx.sqlite.db.SupportSQLiteQuery + +@Dao +interface StatusRecordDao { + + @Query("SELECT * from status_table ORDER BY timestamp ASC") + fun getRecords(): LiveData> + + @Query("SELECT * from status_table ORDER BY timestamp ASC") + fun getCurrentRecords(): List + + @Query("SELECT * from status_table where msg = :msg ORDER BY timestamp DESC LIMIT 1") + fun getMostRecentRecord(msg: String): LiveData + + @Query("DELETE FROM status_table WHERE timestamp <= :timeInMs") + fun deleteDataOlder(timeInMs: Long): Int + + @Query("DELETE FROM status_table") + fun nukeDb() + + @RawQuery + fun getRecordsViaQuery(query: SupportSQLiteQuery): List + + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insert(record: StatusRecord) + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordStorage.kt b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordStorage.kt new file mode 100644 index 0000000..762c0db --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/status/persistence/StatusRecordStorage.kt @@ -0,0 +1,22 @@ +package au.gov.health.covidsafe.status.persistence + +import android.content.Context +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase + +class StatusRecordStorage(val context: Context) { + + private val statusDao = StreetPassRecordDatabase.getDatabase(context).statusDao() + + suspend fun saveRecord(record: StatusRecord) { + statusDao.insert(record) + } + + fun getAllRecords(): List { + return statusDao.getCurrentRecords() + } + + fun deleteDataOlderThan(timeInMs: Long): Int { + return statusDao.deleteDataOlder(timeInMs) + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/BlacklistEntry.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/BlacklistEntry.kt new file mode 100644 index 0000000..51f177d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/BlacklistEntry.kt @@ -0,0 +1,3 @@ +package au.gov.health.covidsafe.streetpass + +class BlacklistEntry(val uniqueIdentifier: String?) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/ConnectablePeripheral.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/ConnectablePeripheral.kt new file mode 100644 index 0000000..d715424 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/ConnectablePeripheral.kt @@ -0,0 +1,40 @@ +package au.gov.health.covidsafe.streetpass + +import android.os.Parcelable +import kotlinx.android.parcel.Parcelize + +@Parcelize +class ConnectablePeripheral( + var transmissionPower: Int?, + var rssi: Int +) : Parcelable + +@Parcelize +data class PeripheralDevice( + val modelP: String, + val address: String? +) : Parcelable + +@Parcelize +data class CentralDevice( + val modelC: String, + val address: String? +) : Parcelable + +@Parcelize +data class ConnectionRecord( + val version: Int, + + val msg: String, + val org: String, + + val peripheral: PeripheralDevice, + val central: CentralDevice, + + var rssi: Int, + var txPower: Int? +) : Parcelable { + override fun toString(): String { + return "Central ${central.modelC} - ${central.address} ---> Peripheral ${peripheral.modelP} - ${peripheral.address}" + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPass.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPass.kt new file mode 100644 index 0000000..a596460 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPass.kt @@ -0,0 +1,5 @@ +package au.gov.health.covidsafe.streetpass + +import au.gov.health.covidsafe.BuildConfig + +const val ACTION_DEVICE_SCANNED = "${BuildConfig.APPLICATION_ID}.ACTION_DEVICE_SCANNED" diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassScanner.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassScanner.kt new file mode 100644 index 0000000..607e2a1 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassScanner.kt @@ -0,0 +1,122 @@ +package au.gov.health.covidsafe.streetpass + +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanResult +import android.content.Context +import android.os.Build +import android.os.Handler +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.bluetooth.BLEScanner +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.status.Status +import kotlin.properties.Delegates + +class StreetPassScanner constructor( + context: Context, + serviceUUIDString: String, + private val scanDurationInMillis: Long +) { + + private var scanner: BLEScanner by Delegates.notNull() + + private var context: Context by Delegates.notNull() + private val TAG = "StreetPassScanner" + + private var handler: Handler = Handler() + + var scannerCount = 0 + + private val scanCallback = BleScanCallback() + + init { + scanner = BLEScanner(context, serviceUUIDString, 0) + this.context = context + } + + fun startScan() { + + val statusRecord = Status("Scanning Started") + Utils.broadcastStatusReceived(context, statusRecord) + + scanner.startScan(scanCallback) + scannerCount++ + + handler.postDelayed( + { stopScan() } + , scanDurationInMillis) + + + CentralLog.d(TAG, "scanning started") + } + + fun stopScan() { + if (scannerCount > 0) { + val statusRecord = Status("Scanning Stopped") + Utils.broadcastStatusReceived(context, statusRecord) + scannerCount-- + scanner.stopScan() + } + } + + fun isScanning(): Boolean { + return scannerCount > 0 + } + + inner class BleScanCallback : ScanCallback() { + + private val TAG = "BleScanCallback" + + private fun processScanResult(scanResult: ScanResult?) { + + scanResult?.let { result -> + val device = result.device + val rssi = result.rssi // get RSSI value + + var txPower: Int? = null + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + txPower = result.txPower + if (txPower == 127) { + txPower = null + } + } + + val manuData: ByteArray = scanResult.scanRecord?.getManufacturerSpecificData(1023) + ?: "N.A".toByteArray() + val manuString = String(manuData, Charsets.UTF_8) + + val connectable = ConnectablePeripheral(txPower, rssi) + + CentralLog.i(TAG, "Scanned: $manuString - ${device.address}") + + Utils.broadcastDeviceScanned(context, device, connectable) + } + } + + override fun onScanResult(callbackType: Int, result: ScanResult?) { + super.onScanResult(callbackType, result) + processScanResult(result) + } + + override fun onScanFailed(errorCode: Int) { + super.onScanFailed(errorCode) + + val reason = when (errorCode) { + SCAN_FAILED_ALREADY_STARTED -> "$errorCode - SCAN_FAILED_ALREADY_STARTED" + SCAN_FAILED_APPLICATION_REGISTRATION_FAILED -> "$errorCode - SCAN_FAILED_APPLICATION_REGISTRATION_FAILED" + SCAN_FAILED_FEATURE_UNSUPPORTED -> "$errorCode - SCAN_FAILED_FEATURE_UNSUPPORTED" + SCAN_FAILED_INTERNAL_ERROR -> "$errorCode - SCAN_FAILED_INTERNAL_ERROR" + else -> { + "$errorCode - UNDOCUMENTED" + } + } + CentralLog.e(TAG, "BT Scan failed: $reason") + if (scannerCount > 0) { + scannerCount-- + } + } + } + + +} + diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassServer.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassServer.kt new file mode 100644 index 0000000..80e5401 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassServer.kt @@ -0,0 +1,32 @@ +package au.gov.health.covidsafe.streetpass + +import android.content.Context +import au.gov.health.covidsafe.bluetooth.gatt.GattServer +import au.gov.health.covidsafe.bluetooth.gatt.GattService + +class StreetPassServer constructor(val context: Context, serviceUUIDString: String) { + + private val TAG = "StreetPassServer" + private var gattServer: GattServer? = null + + init { + gattServer = setupGattServer(context, serviceUUIDString) + } + + private fun setupGattServer(context: Context, serviceUUIDString: String): GattServer? { + val gattServer = GattServer(context, serviceUUIDString) + val started = gattServer.startServer() + + if (started) { + val readService = GattService(context, serviceUUIDString) + gattServer.addService(readService) + return gattServer + } + return null + } + + fun tearDown() { + gattServer?.stop() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassWorker.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassWorker.kt new file mode 100644 index 0000000..ac3b9c7 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassWorker.kt @@ -0,0 +1,721 @@ +package au.gov.health.covidsafe.streetpass + +import android.bluetooth.* +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.Handler +import androidx.annotation.Keep +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.Utils +import au.gov.health.covidsafe.bluetooth.gatt.* +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.services.BluetoothMonitoringService +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.blacklistDuration +import au.gov.health.covidsafe.services.BluetoothMonitoringService.Companion.maxQueueTime +import java.util.* +import java.util.concurrent.PriorityBlockingQueue +@Keep +class StreetPassWorker(val context: Context) { + + private val workQueue: PriorityBlockingQueue = PriorityBlockingQueue() + private val blacklist: MutableList = Collections.synchronizedList(ArrayList()) + + private val workReceiver = StreetPassWorkReceiver() + private val deviceProcessedReceiver = DeviceProcessedReceiver() + private val serviceUUID: UUID = UUID.fromString(BuildConfig.BLE_SSID) + private val TAG = "StreetPassWorker" + + private val bluetoothManager = + context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager + + private lateinit var timeoutHandler: Handler + private lateinit var queueHandler: Handler + private lateinit var blacklistHandler: Handler + + private var currentPendingConnection: Work? = null + private var localBroadcastManager: LocalBroadcastManager = LocalBroadcastManager.getInstance(context) + + val onWorkTimeoutListener = object : Work.OnWorkTimeoutListener { + override fun onWorkTimeout(work: Work) { + + if (!isCurrentlyWorkedOn(work.device.address)) { + CentralLog.i(TAG, "Work already removed. Timeout ineffective??.") + } + + CentralLog.e( + TAG, + "Work timed out for ${work.device.address} @ ${work.connectable.rssi} queued for ${work.checklist.started.timePerformed - work.timeStamp}ms" + ) + CentralLog.e( + TAG, + "${work.device.address} work status: ${work.checklist}." + ) + + //connection never formed - don't need to disconnect + if (!work.checklist.connected.status) { + CentralLog.e(TAG, "No connection formed for ${work.device.address}") + if (work.device.address == currentPendingConnection?.device?.address) { + currentPendingConnection = null + } + + try { + work.gatt?.close() + } catch (e: Exception) { + CentralLog.e( + TAG, + "Unexpected error while attempting to close clientIf to ${work.device.address}: ${e.localizedMessage}" + ) + } + + finishWork(work) + } + //the connection is still there - might be stuck / work in progress + else if (work.checklist.connected.status && !work.checklist.disconnected.status) { + + if (work.checklist.readCharacteristic.status || work.checklist.writeCharacteristic.status || work.checklist.skipped.status) { + CentralLog.e( + TAG, + "Connected but did not disconnect in time for ${work.device.address}" + ) + + try { + work.gatt?.disconnect() + //disconnect callback won't get invoked + if (work.gatt == null) { + currentPendingConnection = null + finishWork(work) + } + } catch (e: Throwable) { + CentralLog.e( + TAG, + "Failed to clean up work, bluetooth state likely changed or other device's advertiser stopped: ${e.localizedMessage}" + ) + } + + } else { + CentralLog.e( + TAG, + "Connected but did nothing for ${work.device.address}" + ) + + try { + work.gatt?.disconnect() + //disconnect callback won't get invoked + if (work.gatt == null) { + currentPendingConnection = null + finishWork(work) + } + } catch (e: Throwable) { + CentralLog.e( + TAG, + "Failed to clean up work, bluetooth state likely changed or other device's advertiser stopped: ${e.localizedMessage}" + ) + } + } + } + + //all other edge cases? - disconnected + else { + CentralLog.e( + TAG, + "Disconnected but callback not invoked in time. Waiting.: ${work.device.address}: ${work.checklist}" + ) + } + } + } + + init { + prepare() + } + + private fun prepare() { + val deviceAvailableFilter = IntentFilter(ACTION_DEVICE_SCANNED) + localBroadcastManager.registerReceiver(workReceiver, deviceAvailableFilter) + + val deviceProcessedFilter = IntentFilter(ACTION_DEVICE_PROCESSED) + localBroadcastManager.registerReceiver(deviceProcessedReceiver, deviceProcessedFilter) + + timeoutHandler = Handler() + queueHandler = Handler() + blacklistHandler = Handler() + } + + fun isCurrentlyWorkedOn(address: String?): Boolean { + return currentPendingConnection?.let { + it.device.address == address + } ?: false + } + + fun addWork(work: Work): Boolean { + //if it's our current work. ignore + if (isCurrentlyWorkedOn(work.device.address)) { + CentralLog.i(TAG, "${work.device.address} is being worked on, not adding to queue") + return false + } + + //if its in blacklist - check for both mac address and manu data + + if (blacklist.any { it.uniqueIdentifier == work.device.address }) { + CentralLog.i(TAG, "${work.device.address} is in blacklist, not adding to queue") + return false + } + + //if we haven't seen this device yet + if (workQueue.none { it.device.address == work.device.address }) { + workQueue.offer(work) + queueHandler.postDelayed({ + if (workQueue.contains(work)) + CentralLog.i( + TAG, + "Work for ${work.device.address} removed from queue? : ${workQueue.remove( + work + )}" + ) + }, maxQueueTime) + CentralLog.i(TAG, "Added to work queue: ${work.device.address}") + return true + } + //this gadget is already in the queue, we can use the latest rssi and txpower? replace the entry + else { + + //ignore it + CentralLog.i(TAG, "${work.device.address} is already in work queue") + + val prevWork = workQueue.find { it.device.address == work.device.address } + val removed = workQueue.remove(prevWork) + val added = workQueue.offer(work) + + CentralLog.i(TAG, "Queue entry updated - removed: ${removed}, added: $added") + + return false + } + } + + fun doWork() { + + if (currentPendingConnection != null) { + CentralLog.i( + TAG, + "Already trying to connect to: ${currentPendingConnection?.device?.address}" + ) + //devices may reset their bluetooth before the disconnection happens properly and disconnect is never called. + //handle that situation here + + //if the job was finished but not removed + //or if the job was timed out but not removed + val timedout = System.currentTimeMillis() > currentPendingConnection?.timeout ?: 0 + if (currentPendingConnection?.finished ?: false || timedout) { + + CentralLog.w( + TAG, + "Handling erroneous current work for ${currentPendingConnection?.device?.address} : - finished: ${currentPendingConnection?.finished + ?: false}, timedout: $timedout" + ) + //check if there is, for some reason, an existing connection + if (currentPendingConnection != null) { + if (bluetoothManager.getConnectedDevices(BluetoothProfile.GATT).contains( + currentPendingConnection?.device + ) + ) { + CentralLog.w( + TAG, + "Disconnecting dangling connection to ${currentPendingConnection?.device?.address}" + ) + currentPendingConnection?.gatt?.disconnect() + } + } else { + doWork() + } + } + + return + } + + if (workQueue.isEmpty()) { + CentralLog.i(TAG, "Queue empty. Nothing to do.") + return + } + + CentralLog.i(TAG, "Queue size: ${workQueue.size}") + + var workToDo: Work? = null + val now = System.currentTimeMillis() + + while (workToDo == null && workQueue.isNotEmpty()) { + workToDo = workQueue.poll() + workToDo?.let { work -> + if (now - work.timeStamp > maxQueueTime) { + CentralLog.w( + TAG, + "Work request for ${work.device.address} too old. Not doing" + ) + workToDo = null + } + } + } + + workToDo?.let { + + val device = it.device + + if (blacklist.filter { it.uniqueIdentifier == device.address }.isNotEmpty()) { + CentralLog.w(TAG, "Already worked on ${device.address}. Skip.") + doWork() + return + } + + var currentWorkOrder = it + + val alreadyConnected = getConnectionStatus(device) + CentralLog.i(TAG, "Already connected to ${device.address} : $alreadyConnected") + + if (alreadyConnected) { + //this might mean that the other device is currently connected to this device's local gatt server + //skip. we'll rely on the other party to do a write + currentWorkOrder.checklist.skipped.status = true + currentWorkOrder.checklist.skipped.timePerformed = System.currentTimeMillis() + currentWorkOrder.let { + finishWork(it) + } + + } else { + + currentWorkOrder.let { + + if (it != null) { + + val gattCallback = StreetPassGattCallback(it) + CentralLog.i( + TAG, + "Starting work - connecting to device: ${device.address} @ ${it.connectable.rssi} ${System.currentTimeMillis() - it.timeStamp}ms ago" + ) + currentPendingConnection = it + + try { + it.checklist.started.status = true + it.checklist.started.timePerformed = System.currentTimeMillis() + + it.startWork(context, gattCallback) + + var connecting = it.gatt?.connect() ?: false + + if (!connecting) { + CentralLog.e( + TAG, + "not connecting to ${it.device.address}??" + ) + + //bail and do the next job + CentralLog.e(TAG, "Moving on to next task") + currentPendingConnection = null + doWork() + return + + } else { + CentralLog.i( + TAG, + "Connection to ${it.device.address} attempt in progress" + ) + } + + timeoutHandler.postDelayed( + it.timeoutRunnable, + BluetoothMonitoringService.connectionTimeout + ) + it.timeout = + System.currentTimeMillis() + BluetoothMonitoringService.connectionTimeout + + CentralLog.i(TAG, "Timeout scheduled for ${it.device.address}") + } catch (e: Throwable) { + CentralLog.e( + TAG, + "Unexpected error while attempting to connect to ${device.address}: ${e.localizedMessage}" + ) + CentralLog.e(TAG, "Moving on to next task") + currentPendingConnection = null + doWork() + return + } + + } else { + CentralLog.e(TAG, "Work not started - missing Work Object") + } + } + } + } + + if (workToDo == null) { + CentralLog.i(TAG, "No outstanding work") + } + + } + + private fun getConnectionStatus(device: BluetoothDevice): Boolean { + + val connectedDevices = bluetoothManager.getDevicesMatchingConnectionStates( + BluetoothProfile.GATT, + intArrayOf(BluetoothProfile.STATE_CONNECTED) + ) + return connectedDevices.contains(device) + } + + fun finishWork(work: Work) { + + if (work.finished) { + CentralLog.i( + TAG, + "Work on ${work.device.address} already finished and closed" + ) + return + } + + if (work.isCriticalsCompleted()) { + Utils.broadcastDeviceProcessed(context, work.device.address) + } + + CentralLog.i( + TAG, + "Work on ${work.device.address} stopped in: ${work.checklist.disconnected.timePerformed - work.checklist.started.timePerformed}" + ) + + CentralLog.i( + TAG, + "Work on ${work.device.address} completed?: ${work.isCriticalsCompleted()}. Connected in: ${work.checklist.connected.timePerformed - work.checklist.started.timePerformed}. connection lasted for: ${work.checklist.disconnected.timePerformed - work.checklist.connected.timePerformed}. Status: ${work.checklist}" + ) + + timeoutHandler.removeCallbacks(work.timeoutRunnable) + CentralLog.i(TAG, "Timeout removed for ${work.device.address}") + + work.finished = true + doWork() + } + + inner class StreetPassGattCallback(private val work: Work) : BluetoothGattCallback() { + + private fun endWorkConnection(gatt: BluetoothGatt) { + CentralLog.i(TAG, "Ending connection with: ${gatt.device.address}") + gatt.disconnect() + } + + override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) { + + gatt?.let { + + when (newState) { + BluetoothProfile.STATE_CONNECTED -> { + CentralLog.i(TAG, "Connected to other GATT server - ${gatt.device.address}") + + gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_BALANCED) + gatt.requestMtu(512) + + work.checklist.connected.status = true + work.checklist.connected.timePerformed = System.currentTimeMillis() + + } + + BluetoothProfile.STATE_DISCONNECTED -> { + CentralLog.i( + TAG, + "Disconnected from other GATT server - ${gatt.device.address}" + ) + work.checklist.disconnected.status = true + work.checklist.disconnected.timePerformed = System.currentTimeMillis() + + //remove timeout runnable if its still there + timeoutHandler.removeCallbacks(work.timeoutRunnable) + CentralLog.i(TAG, "Timeout removed for ${work.device.address}") + + //remove job from list of current work - if it is the current work + if (work.device.address == currentPendingConnection?.device?.address) { + currentPendingConnection = null + } + gatt.close() + finishWork(work) + } + + else -> { + CentralLog.i(TAG, "Connection status for ${gatt.device.address}: $newState") + endWorkConnection(gatt) + } + } + } + } + + override fun onMtuChanged(gatt: BluetoothGatt?, mtu: Int, status: Int) { + + if (!work.checklist.mtuChanged.status) { + + work.checklist.mtuChanged.status = true + work.checklist.mtuChanged.timePerformed = System.currentTimeMillis() + + CentralLog.i( + TAG, + "${gatt?.device?.address} MTU is $mtu. Was change successful? : ${status == BluetoothGatt.GATT_SUCCESS}" + ) + + gatt?.let { + val discoveryOn = gatt.discoverServices() + CentralLog.i( + TAG, + "Attempting to start service discovery on ${gatt.device.address}: $discoveryOn" + ) + } + } + } + + // New services discovered + override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { + when (status) { + BluetoothGatt.GATT_SUCCESS -> { + CentralLog.i( + TAG, + "onServicesDiscovered received: BluetoothGatt.GATT_SUCCESS - $status" + ) + CentralLog.i( + TAG, + "Discovered ${gatt.services.size} services on ${gatt.device.address}" + ) + + val service = gatt.getService(serviceUUID) + + service?.let { + val characteristic = service.getCharacteristic(serviceUUID) + if (characteristic != null) { + val readSuccess = gatt.readCharacteristic(characteristic) + CentralLog.i( + TAG, + "Attempt to read characteristic of our service on ${gatt.device.address}: $readSuccess" + ) + } else { + CentralLog.e( + TAG, + "${gatt.device.address} does not have our characteristic" + ) + endWorkConnection(gatt) + } + } + + if (service == null) { + CentralLog.e( + TAG, + "${gatt.device.address} does not have our service" + ) + endWorkConnection(gatt) + } + } + else -> { + CentralLog.w(TAG, "No services discovered on ${gatt.device.address}") + endWorkConnection(gatt) + } + } + } + + // data read from a perhipheral + //I am a central + override fun onCharacteristicRead( + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + status: Int + ) { + + CentralLog.i(TAG, "Read Status: $status") + when (status) { + BluetoothGatt.GATT_SUCCESS -> { + CentralLog.i( + TAG, + "Characteristic read from ${gatt.device.address}: ${characteristic.getStringValue( + 0 + )}" + ) + + when (characteristic.uuid) { + + serviceUUID -> { + //need to populate in the rssi here? + CentralLog.i( + TAG, + "onCharacteristicRead: ${work.device.address} - [${work.connectable.rssi}]" + ) + + val dataBytes = characteristic.value + + try { + val readData = ReadRequestPayload.createReadRequestPayload(dataBytes) + val peripheral = + PeripheralDevice(readData.modelP, work.device.address) + + val connectionRecord = ConnectionRecord( + version = readData.v, + msg = readData.msg, + org = readData.org, + peripheral = peripheral, + central = TracerApp.asCentralDevice(), + rssi = work.connectable.rssi, + txPower = work.connectable.transmissionPower + ) + + Utils.broadcastStreetPassReceived( + context, + connectionRecord + ) + + } catch (e: Throwable) { + CentralLog.e( + TAG, + "Failed to de-serialize request payload object - ${e.message}" + ) + } + } + } + work.checklist.readCharacteristic.status = true + work.checklist.readCharacteristic.timePerformed = System.currentTimeMillis() + } + + else -> { + CentralLog.w( + TAG, + "Failed to read characteristics from ${gatt.device.address}: $status" + ) + } + } + + // Only attempt to write BM back to peripheral if it is still valid + if (Utils.bmValid(context)) { + //may have failed to read, can try to write + //we are writing as the central device + val thisCentralDevice = TracerApp.asCentralDevice() + + val writedata = WriteRequestPayload( + v = TracerApp.protocolVersion, + msg = TracerApp.thisDeviceMsg(), + org = TracerApp.ORG, + modelC = thisCentralDevice.modelC, + rssi = work.connectable.rssi, + txPower = work.connectable.transmissionPower + ) + + characteristic.value = writedata.getPayload() + val writeSuccess = gatt.writeCharacteristic(characteristic) + CentralLog.i( + TAG, + "Attempt to write characteristic to our service on ${gatt.device.address}: $writeSuccess" + ) + } else { + CentralLog.i( + TAG, + "Expired BM. Skipping attempt to write characteristic to our service on ${gatt.device.address}" + ) + + endWorkConnection(gatt) + } + } + + override fun onCharacteristicWrite( + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + status: Int + ) { + + when (status) { + BluetoothGatt.GATT_SUCCESS -> { + CentralLog.i(TAG, "Characteristic wrote successfully") + work.checklist.writeCharacteristic.status = true + work.checklist.writeCharacteristic.timePerformed = System.currentTimeMillis() + } + else -> { + CentralLog.i(TAG, "Failed to write characteristics: $status") + } + } + + endWorkConnection(gatt) + } + + } + + fun terminateConnections() { + CentralLog.d(TAG, "Cleaning up worker.") + + currentPendingConnection?.gatt?.disconnect() + currentPendingConnection = null + + timeoutHandler.removeCallbacksAndMessages(null) + queueHandler.removeCallbacksAndMessages(null) + blacklistHandler.removeCallbacksAndMessages(null) + + //concurrent modifications? + workQueue.clear() + blacklist.clear() + } + + fun unregisterReceivers() { + try { + localBroadcastManager.unregisterReceiver(deviceProcessedReceiver) + } catch (e: Throwable) { + CentralLog.e(TAG, "Unable to close receivers: ${e.localizedMessage}") + } + + try { + localBroadcastManager.unregisterReceiver(workReceiver) + } catch (e: Throwable) { + CentralLog.e(TAG, "Unable to close receivers: ${e.localizedMessage}") + } + } + + inner class DeviceProcessedReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + if (ACTION_DEVICE_PROCESSED == intent.action) { + val deviceAddress = intent.getStringExtra(DEVICE_ADDRESS) + CentralLog.d(TAG, "Adding to blacklist: $deviceAddress") + val entry = BlacklistEntry(deviceAddress) + blacklist.add(entry) + blacklistHandler.postDelayed({ + CentralLog.i( + TAG, + "blacklist for ${entry.uniqueIdentifier} removed? : ${blacklist.remove(entry)}" + ) + }, blacklistDuration) + } + } + } + + inner class StreetPassWorkReceiver : BroadcastReceiver() { + + private val TAG = "StreetPassWorkReceiver" + + override fun onReceive(context: Context?, intent: Intent?) { + + intent?.let { + if (ACTION_DEVICE_SCANNED == intent.action) { + //get data from extras + val device: BluetoothDevice? = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) + val connectable: ConnectablePeripheral? = + intent.getParcelableExtra(CONNECTION_DATA) + + val devicePresent = device != null + val connectablePresent = connectable != null + + CentralLog.i( + TAG, + "Device received: ${device?.address}. Device present: $devicePresent, Connectable Present: $connectablePresent" + ) + + device?.let { + connectable?.let { + val work = Work(device, connectable, onWorkTimeoutListener) + if (addWork(work)) { + doWork() + } + } + } + } + } + } + } +} + diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/Work.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/Work.kt new file mode 100644 index 0000000..a7c47d2 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/Work.kt @@ -0,0 +1,71 @@ +package au.gov.health.covidsafe.streetpass + +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothGatt +import android.content.Context +import com.google.gson.Gson +import au.gov.health.covidsafe.logging.CentralLog +import kotlin.properties.Delegates + +class Work constructor( + var device: BluetoothDevice, + var connectable: ConnectablePeripheral, + private val onWorkTimeoutListener: OnWorkTimeoutListener +) : Comparable { + var timeStamp: Long by Delegates.notNull() + var checklist = WorkCheckList() + var gatt: BluetoothGatt? = null + var finished = false + var timeout : Long = 0 + + private val TAG = "Work" + + val timeoutRunnable: Runnable = Runnable { + onWorkTimeoutListener.onWorkTimeout(this) + } + + init { + timeStamp = System.currentTimeMillis() + } + + fun isCriticalsCompleted(): Boolean { + return (checklist.connected.status && checklist.readCharacteristic.status && checklist.writeCharacteristic.status) || checklist.skipped.status + } + + fun startWork( + context: Context, + gattCallback: StreetPassWorker.StreetPassGattCallback + ) { + gatt = device.connectGatt(context, false, gattCallback) + if (gatt == null) { + CentralLog.e(TAG, "Unable to connect to ${device.address}") + } + } + + override fun compareTo(other: Work): Int { + return -(timeStamp - other.timeStamp).toInt() + } + + inner class WorkCheckList { + var started = Check() + var connected = Check() + var mtuChanged = Check() + var readCharacteristic = Check() + var writeCharacteristic = Check() + var disconnected = Check() + var skipped = Check() + + override fun toString(): String { + return Gson().toJson(this) + } + } + + inner class Check { + var status = false + var timePerformed: Long = 0 + } + + interface OnWorkTimeoutListener { + fun onWorkTimeout(work: Work) + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecord.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecord.kt new file mode 100644 index 0000000..eb5feea --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecord.kt @@ -0,0 +1,45 @@ +package au.gov.health.covidsafe.streetpass.persistence + +import androidx.annotation.Keep +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Keep +@Entity(tableName = "record_table") +class StreetPassRecord( + @ColumnInfo(name = "v") + var v: Int, + + @ColumnInfo(name = "msg") + var msg: String, + + @ColumnInfo(name = "org") + var org: String, + + @ColumnInfo(name = "modelP") + val modelP: String, + + @ColumnInfo(name = "modelC") + val modelC: String, + + @ColumnInfo(name = "rssi") + val rssi: Int, + + @ColumnInfo(name = "txPower") + val txPower: Int? + +) { + + @PrimaryKey(autoGenerate = true) + @ColumnInfo(name = "id") + var id: Int = 0 + + @ColumnInfo(name = "timestamp") + var timestamp: Long = System.currentTimeMillis() + + override fun toString(): String { + return "StreetPassRecord(v=$v, msg='$msg', org='$org', modelP='$modelP', modelC='$modelC', rssi=$rssi, txPower=$txPower, id=$id, timestamp=$timestamp)" + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDao.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDao.kt new file mode 100644 index 0000000..9ea4678 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDao.kt @@ -0,0 +1,31 @@ +package au.gov.health.covidsafe.streetpass.persistence + +import androidx.lifecycle.LiveData +import androidx.room.* +import androidx.sqlite.db.SupportSQLiteQuery + +@Dao +interface StreetPassRecordDao { + + @Query("SELECT * from record_table ORDER BY timestamp ASC") + fun getRecords(): LiveData> + + @Query("SELECT * from record_table ORDER BY timestamp DESC LIMIT 1") + fun getMostRecentRecord(): LiveData + + @Query("SELECT * from record_table ORDER BY timestamp ASC") + fun getCurrentRecords(): List + + @Query("DELETE FROM record_table WHERE timestamp <= :timeInMs") + fun deleteDataOlder(timeInMs: Long): Int + + @Query("DELETE FROM record_table") + fun nukeDb() + + @RawQuery + fun getRecordsViaQuery(query: SupportSQLiteQuery): List + + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insert(record: StreetPassRecord) + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDatabase.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDatabase.kt new file mode 100644 index 0000000..b990256 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordDatabase.kt @@ -0,0 +1,76 @@ +package au.gov.health.covidsafe.streetpass.persistence + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import au.gov.health.covidsafe.status.persistence.StatusRecord +import au.gov.health.covidsafe.status.persistence.StatusRecordDao + + +@Database( + entities = [StreetPassRecord::class, StatusRecord::class], + version = 2, + exportSchema = true +) +abstract class StreetPassRecordDatabase : RoomDatabase() { + + abstract fun recordDao(): StreetPassRecordDao + abstract fun statusDao(): StatusRecordDao + + companion object { + @Volatile + private var INSTANCE: StreetPassRecordDatabase? = null + + fun getDatabase(context: Context): StreetPassRecordDatabase { + val tempInstance = INSTANCE + if (tempInstance != null) { + return tempInstance + } + synchronized(this) { + val instance = Room.databaseBuilder( + context, + StreetPassRecordDatabase::class.java, + "record_database" + ) + .addMigrations(MIGRATION_1_2) + .build() + INSTANCE = instance + return instance + } + } + + private val MIGRATION_1_2 = object : Migration(1, 2) { + override fun migrate(database: SupportSQLiteDatabase) { + //adding of status table + database.execSQL("CREATE TABLE IF NOT EXISTS `status_table` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `msg` TEXT NOT NULL)") + + if (!isFieldExist(database, "record_table", "v")) { + database.execSQL("ALTER TABLE `record_table` ADD COLUMN `v` INTEGER NOT NULL DEFAULT 1") + } + + if (!isFieldExist(database, "record_table", "org")) { + database.execSQL("ALTER TABLE `record_table` ADD COLUMN `org` TEXT NOT NULL DEFAULT 'AU_DTA'") + } + + } + } + + fun isFieldExist(db: SupportSQLiteDatabase, tableName: String, fieldName: String): Boolean { + var isExist = false + val res = + db.query("PRAGMA table_info($tableName)", null) + res.moveToFirst() + do { + val currentColumn = res.getString(1) + if (currentColumn == fieldName) { + isExist = true + } + } while (res.moveToNext()) + return isExist + } + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordRepository.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordRepository.kt new file mode 100644 index 0000000..2eb7280 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordRepository.kt @@ -0,0 +1,8 @@ +package au.gov.health.covidsafe.streetpass.persistence + +import androidx.lifecycle.LiveData + +class StreetPassRecordRepository(recordDao: StreetPassRecordDao) { + val allRecords: LiveData> = recordDao.getRecords() + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordStorage.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordStorage.kt new file mode 100644 index 0000000..53c8536 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/persistence/StreetPassRecordStorage.kt @@ -0,0 +1,29 @@ +package au.gov.health.covidsafe.streetpass.persistence + +import android.content.Context + +class StreetPassRecordStorage(val context: Context) { + + private val recordDao = StreetPassRecordDatabase.getDatabase(context).recordDao() + + suspend fun saveRecord(record: StreetPassRecord) { + recordDao.insert(record) + } + + fun deleteDataOlderThan(timeInMs: Long): Int { + return recordDao.deleteDataOlder(timeInMs) + } + + fun nukeDb() { + recordDao.nukeDb() + } + + suspend fun nukeDbAsync() { + recordDao.nukeDb() + } + + fun getAllRecords(): List { + return recordDao.getCurrentRecords() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/view/RecordViewModel.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/view/RecordViewModel.kt new file mode 100644 index 0000000..29ef022 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/view/RecordViewModel.kt @@ -0,0 +1,23 @@ +package au.gov.health.covidsafe.streetpass.view + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordDatabase +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordRepository + +class RecordViewModel(app: Application) : AndroidViewModel(app) { + + private var repo: StreetPassRecordRepository + + var allRecords: LiveData> + + init { + val recordDao = StreetPassRecordDatabase.getDatabase(app).recordDao() + repo = StreetPassRecordRepository(recordDao) + allRecords = repo.allRecords + } + + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/streetpass/view/StreetPassRecordViewModel.kt b/app/src/main/java/au/gov/health/covidsafe/streetpass/view/StreetPassRecordViewModel.kt new file mode 100644 index 0000000..a41417e --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/streetpass/view/StreetPassRecordViewModel.kt @@ -0,0 +1,16 @@ +package au.gov.health.covidsafe.streetpass.view + +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord + +class StreetPassRecordViewModel(record: StreetPassRecord, val number: Int) { + val version = record.v + val modelC = record.modelC + val modelP = record.modelP + val msg = record.msg + val timeStamp = record.timestamp + val rssi = record.rssi + val transmissionPower = record.txPower + val org = record.org + + constructor(record: StreetPassRecord) : this(record, 1) +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/BaseFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/BaseFragment.kt new file mode 100644 index 0000000..b9b45f6 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/BaseFragment.kt @@ -0,0 +1,34 @@ +package au.gov.health.covidsafe.ui + +import android.os.Bundle +import androidx.fragment.app.Fragment +import androidx.navigation.Navigator +import androidx.navigation.fragment.NavHostFragment +import au.gov.health.covidsafe.HasBlockingState + +open class BaseFragment : Fragment() { + + override fun onResume() { + super.onResume() + val activity = this.activity + if (activity is HasBlockingState) { + activity.isUiBlocked = false + } + } + + protected fun navigateTo(actionId: Int, bundle: Bundle? = null, navigatorExtras: Navigator.Extras? = null) { + val activity = this.activity + if (activity is HasBlockingState) { + activity.isUiBlocked = true + } + NavHostFragment.findNavController(this).navigate(actionId, bundle, null, navigatorExtras) + } + + protected fun popBackStack() { + val activity = this.activity + if (activity is HasBlockingState) { + activity.isUiBlocked = true + } + NavHostFragment.findNavController(this).popBackStack() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/PagerChildFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/PagerChildFragment.kt new file mode 100644 index 0000000..ab462e9 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/PagerChildFragment.kt @@ -0,0 +1,63 @@ +package au.gov.health.covidsafe.ui + +import androidx.annotation.StringRes + +abstract class PagerChildFragment : BaseFragment() { + override fun onResume() { + super.onResume() + updateToolBar() + updateButton() + updateProgressBar() + updateButtonState() + } + + private fun updateProgressBar() { + (parentFragment?.parentFragment as? PagerContainer)?.updateProgressBar(stepProgress) + (activity as? PagerContainer)?.updateProgressBar(stepProgress) + } + + private fun updateToolBar() { + (parentFragment?.parentFragment as? PagerContainer)?.setNavigationIcon(navigationIcon) + (activity as? PagerContainer)?.setNavigationIcon(navigationIcon) + } + + private fun updateButton() { + val updateButtonLayout = getUploadButtonLayout() + if (updateButtonLayout is UploadButtonLayout.ContinueLayout) { + updateButtonState() + } + (parentFragment?.parentFragment as? PagerContainer)?.refreshButton(updateButtonLayout) + (activity as? PagerContainer)?.refreshButton(updateButtonLayout) + } + + fun enableContinueButton() { + (parentFragment?.parentFragment as? PagerContainer)?.enableNextButton() + (activity as? PagerContainer)?.enableNextButton() + } + + fun disableContinueButton() { + (parentFragment?.parentFragment as? PagerContainer)?.disableNextButton() + (activity as? PagerContainer)?.disableNextButton() + } + + fun showLoading() { + (parentFragment?.parentFragment as? PagerContainer)?.showLoading() + (activity as? PagerContainer)?.showLoading() + } + + fun hideLoading() { + (parentFragment?.parentFragment as? PagerContainer)?.hideLoading((getUploadButtonLayout() as? UploadButtonLayout.ContinueLayout)?.buttonText) + (activity as? PagerContainer)?.hideLoading((getUploadButtonLayout() as? UploadButtonLayout.ContinueLayout)?.buttonText) + } + + abstract val navigationIcon: Int? + abstract var stepProgress: Int? + abstract fun getUploadButtonLayout(): UploadButtonLayout + abstract fun updateButtonState() +} + +sealed class UploadButtonLayout { + class ContinueLayout(@StringRes val buttonText: Int, val buttonListener: (() -> Unit)?) : UploadButtonLayout() + class QuestionLayout(val buttonYesListener: () -> Unit, val buttonNoListener: () -> Unit) : UploadButtonLayout() +} + diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/PagerContainer.kt b/app/src/main/java/au/gov/health/covidsafe/ui/PagerContainer.kt new file mode 100644 index 0000000..30d4504 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/PagerContainer.kt @@ -0,0 +1,13 @@ +package au.gov.health.covidsafe.ui + +import androidx.annotation.StringRes + +interface PagerContainer { + fun enableNextButton() + fun disableNextButton() + fun showLoading() + fun hideLoading(@StringRes stringRes: Int?) + fun updateProgressBar(stepProgress: Int?) + fun setNavigationIcon(navigationIcon: Int?) + fun refreshButton(updateButtonLayout: UploadButtonLayout) +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/HelpFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/HelpFragment.kt new file mode 100644 index 0000000..89bcd9d --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/HelpFragment.kt @@ -0,0 +1,79 @@ +package au.gov.health.covidsafe.ui.home + +import android.content.Intent +import android.graphics.Bitmap +import android.net.Uri +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.webkit.WebResourceRequest +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.core.view.isVisible +import androidx.navigation.fragment.findNavController +import com.atlassian.mobilekit.module.feedback.FeedbackModule +import kotlinx.android.synthetic.main.fragment_help.* +import kotlinx.android.synthetic.main.fragment_help.view.* +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.BaseFragment + +class HelpFragment : BaseFragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = inflater.inflate(R.layout.fragment_help, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val webView = view.helpWebView + webView.settings.javaScriptEnabled = true + webView.webViewClient = createWebVieClient(view) + webView.loadUrl(HELP_URL) + reportAnIssue.setOnClickListener { + FeedbackModule.showFeedbackScreen() + } + toolbar.setNavigationOnClickListener { findNavController().popBackStack() } + } + + private fun createWebVieClient(view: View): WebViewClient = + object : WebViewClient() { + private var isRedirecting = false + private var loadFinished = false + + override fun shouldOverrideUrlLoading(webView: WebView, request: WebResourceRequest): Boolean { + if (!loadFinished) isRedirecting = true + loadFinished = false + val urlString = request.url.toString() + if (urlString == HELP_URL) { + webView.loadUrl(request.url.toString()) + } else { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(urlString)) + webView.context.startActivity(intent) + } + return true + } + + override fun onPageStarted(webView: WebView, url: String?, favicon: Bitmap?) { + super.onPageStarted(webView, url, favicon) + loadFinished = false + view.progress.isVisible = true + } + + override fun onPageFinished(webView: WebView, url: String?) { + super.onPageFinished(webView, url) + + if (!isRedirecting) loadFinished = true + + if (loadFinished && !isRedirecting) { + view.progress.isVisible = false + } else { + isRedirecting = false + } + } + } +} + +private const val HELP_URL = "https://www.covidsafe.gov.au/help-topics.html" diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt new file mode 100644 index 0000000..3141017 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomeFragment.kt @@ -0,0 +1,332 @@ +package au.gov.health.covidsafe.ui.home + +import android.Manifest +import android.bluetooth.BluetoothAdapter +import android.content.* +import android.net.Uri +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.navigation.fragment.findNavController +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.WebViewActivity +import au.gov.health.covidsafe.extensions.* +import au.gov.health.covidsafe.ui.BaseFragment +import kotlinx.android.synthetic.main.fragment_home.* +import kotlinx.android.synthetic.main.fragment_home.view.* +import kotlinx.android.synthetic.main.fragment_home_external_links.* +import kotlinx.android.synthetic.main.fragment_home_setup_complete_header.* +import kotlinx.android.synthetic.main.fragment_home_setup_incomplete_content.* +import pub.devrel.easypermissions.AppSettingsDialog +import pub.devrel.easypermissions.EasyPermissions + +class HomeFragment : BaseFragment(), EasyPermissions.PermissionCallbacks { + + private lateinit var presenter: HomePresenter + + private var mIsBroadcastListenerRegistered = false + + private var counter: Int = 0 + + private val mBroadcastListener: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action + if (action == BluetoothAdapter.ACTION_STATE_CHANGED) { + when (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)) { + BluetoothAdapter.STATE_OFF -> { + bluetooth_card_view.render(formatBlueToothTitle(false), false) + refreshSetupCompleteOrIncompleteUi() + } + BluetoothAdapter.STATE_TURNING_OFF -> { + bluetooth_card_view.render(formatBlueToothTitle(false), false) + refreshSetupCompleteOrIncompleteUi() + } + BluetoothAdapter.STATE_ON -> { + bluetooth_card_view.render(formatBlueToothTitle(true), true) + refreshSetupCompleteOrIncompleteUi() + } + } + } + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + presenter = HomePresenter(this) + return inflater.inflate(R.layout.fragment_home, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.home_header_help.setOnClickListener { + findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToHelpFragment()) + } + if (BuildConfig.ENABLE_DEBUG_SCREEN) { + view.header_background.setOnClickListener { + counter++ + if (counter >= 2) { + counter = 0 + findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToPeekActivity()) + } + } + } + home_version_number.text = getString(R.string.home_version_number, BuildConfig.VERSION_NAME) + } + + override fun onResume() { + super.onResume() + bluetooth_card_view.setOnClickListener { requestBlueToothPermissionThenNextPermission() } + location_card_view.setOnClickListener { askForLocationPermission() } + battery_card_view.setOnClickListener { excludeFromBatteryOptimization() } + home_been_tested_button.setOnClickListener { + navigateTo(R.id.action_home_to_selfIsolate) + } + home_setup_complete_share.setOnClickListener { + shareThisApp() + } + home_setup_complete_news.setOnClickListener { + goToNewsWebsite() + } + home_setup_complete_app.setOnClickListener { + goToCovidApp() + } + + if (!mIsBroadcastListenerRegistered) { + registerBroadcast() + } + refreshSetupCompleteOrIncompleteUi() + } + + override fun onPause() { + super.onPause() + bluetooth_card_view.setOnClickListener(null) + location_card_view.setOnClickListener(null) + battery_card_view.setOnClickListener(null) + home_been_tested_button.setOnClickListener(null) + home_setup_complete_share.setOnClickListener(null) + home_setup_complete_news.setOnClickListener(null) + home_setup_complete_app.setOnClickListener(null) + activity?.let { activity -> + if (mIsBroadcastListenerRegistered) { + activity.unregisterReceiver(mBroadcastListener) + mIsBroadcastListenerRegistered = false + } + } + } + + override fun onDestroyView() { + super.onDestroyView() + home_root.removeAllViews() + } + + private fun refreshSetupCompleteOrIncompleteUi() { + val isUploaded = context?.let { + Preference.isDataUploaded(it) + } ?: run { + false + } + home_been_tested_button.visibility = if (isUploaded) GONE else VISIBLE + when { + !allPermissionsEnabled() -> { + home_header_setup_complete_header_uploaded.visibility = GONE + home_header_setup_complete_header_divider.visibility = GONE + home_header_setup_complete_header.setText(R.string.home_header_inactive_title) + home_header_picture_setup_complete.setImageResource(R.drawable.ic_logo_home_inactive) + home_header_help.setImageResource(R.drawable.ic_help_outline_black) + context?.let { context -> + val backGroundColor = ContextCompat.getColor(context, R.color.grey) + header_background.setBackgroundColor(backGroundColor) + header_background_overlap.setBackgroundColor(backGroundColor) + + val textColor = ContextCompat.getColor(context, R.color.slack_black) + home_header_setup_complete_header_uploaded.setTextColor(textColor) + home_header_setup_complete_header.setTextColor(textColor) + } + content_setup_incomplete_group.visibility = VISIBLE + updateBlueToothStatus() + updatePushNotificationStatus() + updateBatteryOptimizationStatus() + updateLocationStatus() + } + isUploaded -> { + home_header_setup_complete_header_uploaded.visibility = VISIBLE + home_header_setup_complete_header_divider.visibility = VISIBLE + home_header_setup_complete_header.setText(R.string.home_header_active_title) + home_header_picture_setup_complete.setImageResource(R.drawable.ic_logo_home_uploaded) + home_header_picture_setup_complete.setAnimation("spinner_home_upload_complete.json") + home_header_help.setImageResource(R.drawable.ic_help_outline_white) + content_setup_incomplete_group.visibility = GONE + context?.let { context -> + val backGroundColor = ContextCompat.getColor(context, R.color.dark_green) + header_background.setBackgroundColor(backGroundColor) + header_background_overlap.setBackgroundColor(backGroundColor) + + val textColor = ContextCompat.getColor(context, R.color.white) + home_header_setup_complete_header_uploaded.setTextColor(textColor) + home_header_setup_complete_header.setTextColor(textColor) + } + } + + else -> { + home_header_setup_complete_header_uploaded.visibility = GONE + home_header_setup_complete_header_divider.visibility = GONE + home_header_setup_complete_header.setText(R.string.home_header_active_title) + home_header_help.setImageResource(R.drawable.ic_help_outline_black) + home_header_picture_setup_complete.setAnimation("spinner_home.json") + content_setup_incomplete_group.visibility = GONE + context?.let { context -> + val backGroundColor = ContextCompat.getColor(context, R.color.lighter_green) + header_background.setBackgroundColor(backGroundColor) + header_background_overlap.setBackgroundColor(backGroundColor) + + val textColor = ContextCompat.getColor(context, R.color.slack_black) + home_header_setup_complete_header_uploaded.setTextColor(textColor) + home_header_setup_complete_header.setTextColor(textColor) + } + } + } + } + + private fun allPermissionsEnabled(): Boolean { + val bluetoothEnabled = isBlueToothEnabled() ?: true + val pushNotificationEnabled = isPushNotificationEnabled() ?: true + val nonBatteryOptimizationAllowed = isNonBatteryOptimizationAllowed() ?: true + val locationStatusAllowed = isFineLocationEnabled() ?: true + + return bluetoothEnabled && + pushNotificationEnabled && + nonBatteryOptimizationAllowed && + locationStatusAllowed + } + + private fun registerBroadcast() { + activity?.let { activity -> + var f = IntentFilter() + activity.registerReceiver(mBroadcastListener, f) + // bluetooth on/off + f = IntentFilter() + f.addAction(BluetoothAdapter.ACTION_STATE_CHANGED) + activity.registerReceiver(mBroadcastListener, f) + mIsBroadcastListenerRegistered = true + } + } + + private fun shareThisApp() { + val newIntent = Intent(Intent.ACTION_SEND) + newIntent.type = "text/plain" + newIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_this_app_content)) + newIntent.putExtra(Intent.EXTRA_HTML_TEXT, getString(R.string.share_this_app_content_html)) + startActivity(Intent.createChooser(newIntent, null)) + } + + private fun updateBlueToothStatus() { + isBlueToothEnabled()?.let { + bluetooth_card_view.visibility = VISIBLE + bluetooth_card_view.render(formatBlueToothTitle(it), it) + } ?: run { + bluetooth_card_view.visibility = GONE + } + } + + private fun updatePushNotificationStatus() { + isPushNotificationEnabled()?.let { + push_card_view.visibility = VISIBLE + push_card_view.render(formatPushNotificationTitle(it), it) + } ?: run { + push_card_view.visibility = GONE + } + } + + private fun updateBatteryOptimizationStatus() { + isNonBatteryOptimizationAllowed()?.let { + battery_card_view.visibility = VISIBLE + battery_card_view.render(formatNonBatteryOptimizationTitle(!it), it) + } ?: run { + battery_card_view.visibility = GONE + } + } + + private fun updateLocationStatus() { + isFineLocationEnabled()?.let { + location_card_view.visibility = VISIBLE + location_card_view.render(formatLocationTitle(it), it) + } ?: run { + location_card_view.visibility = VISIBLE + } + } + + private fun formatBlueToothTitle(on: Boolean): String { + return resources.getString(R.string.home_bluetooth_permission, getPermissionEnabledTitle(on)) + } + + private fun formatLocationTitle(on: Boolean): String { + return resources.getString(R.string.home_location_permission, getPermissionEnabledTitle(on)) + } + + private fun formatNonBatteryOptimizationTitle(on: Boolean): String { + return resources.getString(R.string.home_non_battery_optimization_permission, getPermissionEnabledTitle(on)) + } + + private fun formatPushNotificationTitle(on: Boolean): String { + return resources.getString(R.string.home_push_notification_permission, getPermissionEnabledTitle(on)) + } + + private fun getPermissionEnabledTitle(on: Boolean): String { + return resources.getString(if (on) R.string.home_permission_on else R.string.home_permission_off) + } + + private fun goToNewsWebsite() { + val url = getString(R.string.home_set_complete_external_link_news_url) + try { + Intent(Intent.ACTION_VIEW).run { + data = Uri.parse(url) + startActivity(this) + } + } catch (e: ActivityNotFoundException) { + val intent = Intent(activity, WebViewActivity::class.java) + intent.putExtra(WebViewActivity.URL_ARG, url) + startActivity(intent) + } + } + + private fun goToCovidApp() { + val url = getString(R.string.home_set_complete_external_link_app_url) + try { + Intent(Intent.ACTION_VIEW).run { + data = Uri.parse(url) + startActivity(this) + } + } catch (e: ActivityNotFoundException) { + val intent = Intent(activity, WebViewActivity::class.java) + intent.putExtra(WebViewActivity.URL_ARG, url) + startActivity(intent) + } + } + + override fun onPermissionsDenied(requestCode: Int, perms: MutableList) { + if (requestCode == LOCATION && EasyPermissions.somePermissionPermanentlyDenied(this, listOf(Manifest.permission.ACCESS_FINE_LOCATION))) { + AppSettingsDialog.Builder(this).build().show() + } + } + + override fun onPermissionsGranted(requestCode: Int, perms: MutableList) { + if (requestCode == LOCATION) { + checkBLESupport() + } + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/HomePresenter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomePresenter.kt new file mode 100644 index 0000000..e5a5aa4 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/HomePresenter.kt @@ -0,0 +1,10 @@ +package au.gov.health.covidsafe.ui.home + +import androidx.lifecycle.LifecycleObserver + +class HomePresenter(fragment: HomeFragment) : LifecycleObserver { + + init { + fragment.lifecycle.addObserver(this) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/view/ExternalLinkCard.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/view/ExternalLinkCard.kt new file mode 100644 index 0000000..f5f1efe --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/view/ExternalLinkCard.kt @@ -0,0 +1,34 @@ +package au.gov.health.covidsafe.ui.home.view + +import android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.view.LayoutInflater +import androidx.constraintlayout.widget.ConstraintLayout +import au.gov.health.covidsafe.R +import kotlinx.android.synthetic.main.view_card_external_link_card.view.* + +class ExternalLinkCard @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + init { + LayoutInflater.from(context).inflate(R.layout.view_card_external_link_card, this, true) + + val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.ExternalLinkCard) + val icon = a.getDrawable(R.styleable.ExternalLinkCard_external_linkCard_icon) + val title = a.getString(R.styleable.ExternalLinkCard_external_linkCard_title) + val content = a.getString(R.styleable.ExternalLinkCard_external_linkCard_content) + val padding = a.getDimension(R.styleable.ExternalLinkCard_external_linkCard_icon_padding, 0f).toInt() + val iconBackground = a.getResourceId(R.styleable.ExternalLinkCard_external_linkCard_icon_background, R.color.transparent) + + external_link_round_image.setImageDrawable(icon) + external_link_round_image.setBackgroundResource(iconBackground) + external_link_round_image.setPadding(padding, padding, padding, padding) + external_link_headline.text = title + external_link_content.text = content + a.recycle() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/home/view/PermissionStatusCard.kt b/app/src/main/java/au/gov/health/covidsafe/ui/home/view/PermissionStatusCard.kt new file mode 100644 index 0000000..c1869df --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/home/view/PermissionStatusCard.kt @@ -0,0 +1,37 @@ +package au.gov.health.covidsafe.ui.home.view + +import android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.FrameLayout +import au.gov.health.covidsafe.R +import kotlinx.android.synthetic.main.view_card_permission_card.view.* + +class PermissionStatusCard @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { + + init { + LayoutInflater.from(context).inflate(R.layout.view_card_permission_card, this, true) + + val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.PermissionStatusCard) + val title = a.getString(R.styleable.PermissionStatusCard_permissionStatusCard_title) + a.recycle() + + permission_title.text = title + + val height = context.resources.getDimensionPixelSize(R.dimen.permission_height) + layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height) + } + + fun render(text: String, correct: Boolean) { + permission_icon.isSelected = correct + permission_title.text = text + } + + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt new file mode 100644 index 0000000..01b5dbb --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/OnboardingActivity.kt @@ -0,0 +1,104 @@ +package au.gov.health.covidsafe.ui.onboarding + +import android.os.Bundle +import android.view.View.GONE +import android.view.View.VISIBLE +import androidx.annotation.StringRes +import androidx.core.content.ContextCompat +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import au.gov.health.covidsafe.HasBlockingState +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerContainer +import au.gov.health.covidsafe.ui.UploadButtonLayout +import com.github.razir.progressbutton.bindProgressButton +import com.github.razir.progressbutton.hideProgress +import com.github.razir.progressbutton.showProgress +import kotlinx.android.synthetic.main.activity_onboarding.* + +class OnboardingActivity : FragmentActivity(), HasBlockingState, PagerContainer { + + override var isUiBlocked: Boolean = false + set(value) { + loadingProgressBarFrame?.isVisible = value + field = value + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_onboarding) + bindProgressButton(onboarding_next) + if (isUiBlocked) { + loadingProgressBarFrame?.isVisible = true + } + } + + override fun onAttachFragment(fragment: Fragment) { + super.onAttachFragment(fragment) + isUiBlocked = false + } + + override fun onResume() { + super.onResume() + + toolbar.setNavigationOnClickListener { + super.onBackPressed() + } + } + + override fun updateProgressBar(stepProgress: Int?) { + stepProgress?.let { progress -> + onboarding_progress_bar.visibility = VISIBLE + onboarding_progress_bar.progress = progress + } ?: run { + onboarding_progress_bar.visibility = GONE + } + } + + override fun setNavigationIcon(navigationIcon: Int?) { + if (navigationIcon == null) { + toolbar.navigationIcon = null + } else { + toolbar.navigationIcon = ContextCompat.getDrawable(this, navigationIcon) + } + } + + override fun refreshButton(updateButtonLayout: UploadButtonLayout) { + if (updateButtonLayout is UploadButtonLayout.ContinueLayout) { + onboarding_next.setText(updateButtonLayout.buttonText) + onboarding_next.setOnClickListener { + updateButtonLayout.buttonListener?.invoke() + } + } + } + + override fun onPause() { + super.onPause() + onboarding_next.setOnClickListener(null) + toolbar.setNavigationOnClickListener(null) + } + + override fun enableNextButton() { + onboarding_next.isEnabled = true + } + + override fun disableNextButton() { + onboarding_next.isEnabled = false + } + + override fun showLoading() { + onboarding_next.showProgress { + progressColorRes = R.color.slack_black_2 + } + } + + override fun hideLoading(@StringRes stringRes: Int?) { + if (stringRes == null) { + onboarding_next.hideProgress() + } else { + onboarding_next.hideProgress(newTextRes = stringRes) + } + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/dataprivacy/DataPrivacyFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/dataprivacy/DataPrivacyFragment.kt new file mode 100644 index 0000000..b12d786 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/dataprivacy/DataPrivacyFragment.kt @@ -0,0 +1,39 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.dataprivacy + +import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_data_privacy.* +import kotlinx.android.synthetic.main.fragment_data_privacy.view.* + +class DataPrivacyFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_data_privacy, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.data_privacy_content.movementMethod = LinkMovementMethod.getInstance() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.data_privacy_button) { + navigateTo(DataPrivacyFragmentDirections.actionDataPrivacyToRegistrationConsentFragment().actionId) + } + + override fun updateButtonState() { + enableContinueButton() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberFragment.kt new file mode 100644 index 0000000..f84425e --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberFragment.kt @@ -0,0 +1,144 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.enternumber + +import android.app.AlertDialog +import android.os.Bundle +import android.text.Editable +import android.text.InputFilter +import android.text.TextWatcher +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.View.VISIBLE +import android.view.ViewGroup +import androidx.annotation.NavigationRes +import androidx.core.os.bundleOf +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import au.gov.health.covidsafe.ui.onboarding.fragment.enterpin.EnterPinFragment.Companion.ENTER_PIN_CHALLENGE_NAME +import au.gov.health.covidsafe.ui.onboarding.fragment.enterpin.EnterPinFragment.Companion.ENTER_PIN_DESTINATION_ID +import au.gov.health.covidsafe.ui.onboarding.fragment.enterpin.EnterPinFragment.Companion.ENTER_PIN_PHONE_NUMBER +import au.gov.health.covidsafe.ui.onboarding.fragment.enterpin.EnterPinFragment.Companion.ENTER_PIN_PROGRESS +import au.gov.health.covidsafe.ui.onboarding.fragment.enterpin.EnterPinFragment.Companion.ENTER_PIN_SESSION +import kotlinx.android.synthetic.main.fragment_enter_number.* +import kotlinx.android.synthetic.main.fragment_enter_number.view.* + +class EnterNumberFragment : PagerChildFragment() { + + companion object { + const val ENTER_NUMBER_DESTINATION_ID = "destination_id" + const val ENTER_NUMBER_PROGRESS = "progress" + } + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = 2 + + private val enterNumberPresenter = EnterNumberPresenter(this) + private var alertDialog: AlertDialog? = null + @NavigationRes + private var destinationId: Int? = null + + private val phoneNumberTextWatcher: TextWatcher = object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + // change LengthFilter if user making a mistake of entering phone number starting with 0 + val phoneNumberLength = TracerApp.AppContext.resources.getInteger(R.integer.australian_phone_number_length) + val filters = enter_number_phone_number.filters + val newFilterLength = if (s?.toString()?.startsWith("0") == true) { + phoneNumberLength + 1 + } else { + phoneNumberLength + } + enter_number_phone_number.filters = filters.filterNot { it is InputFilter.LengthFilter }.toTypedArray() + + InputFilter.LengthFilter(newFilterLength) + + updateButtonState() + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_enter_number, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.use_oz_phone_number.movementMethod = LinkMovementMethod.getInstance() + arguments?.let { + destinationId = it.getInt(ENTER_NUMBER_DESTINATION_ID) + stepProgress = if (it.containsKey(ENTER_NUMBER_PROGRESS)) it.getInt(ENTER_PIN_PROGRESS) else null + } + } + + override fun onResume() { + super.onResume() + enter_number_phone_number.selectAll() + enter_number_phone_number.addTextChangedListener(phoneNumberTextWatcher) + updateButtonState() + } + + override fun onPause() { + super.onPause() + enter_number_phone_number.removeTextChangedListener(phoneNumberTextWatcher) + } + + fun showInvalidPhoneNumber() { + invalid_phone_number.visibility = VISIBLE + enter_number_phone_number.background = context?.getDrawable(R.drawable.phone_number_invalid_background) + } + + override fun updateButtonState() { + if (enterNumberPresenter.validateAuNumber(enter_number_phone_number?.text?.toString())) { + enableContinueButton() + } else { + disableContinueButton() + } + } + + fun showGenericError() { + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } + + fun navigateToOTPPage( + session: String?, + challengeName: String?, + phoneNumber: String) { + val bundle = bundleOf( + ENTER_PIN_SESSION to session, + ENTER_PIN_CHALLENGE_NAME to challengeName, + ENTER_PIN_PHONE_NUMBER to phoneNumber, + ENTER_PIN_DESTINATION_ID to destinationId).also { bundle -> + stepProgress?.let { + bundle.putInt(ENTER_PIN_PROGRESS, it + 1) + } + } + navigateTo(R.id.action_enterNumberFragment_to_otpFragment, bundle) + } + + override fun onDestroyView() { + super.onDestroyView() + alertDialog?.dismiss() + root.removeAllViews() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.enter_number_button) { + enterNumberPresenter.requestOTP(enter_number_phone_number.text.toString().trim()) + } + + fun showCheckInternetError() { + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_internet_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberPresenter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberPresenter.kt new file mode 100644 index 0000000..9167abb --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enternumber/EnterNumberPresenter.kt @@ -0,0 +1,91 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.enternumber + + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.extensions.isInternetAvailable +import au.gov.health.covidsafe.factory.NetworkFactory +import au.gov.health.covidsafe.interactor.usecase.GetOnboardingOtp +import au.gov.health.covidsafe.interactor.usecase.GetOnboardingOtpException +import au.gov.health.covidsafe.interactor.usecase.GetOtpParams + + +class EnterNumberPresenter(private val enterNumberFragment: EnterNumberFragment) : LifecycleObserver { + + private val TAG = this.javaClass.simpleName + + private lateinit var phoneNumber: String + private lateinit var getOnboardingOtp: GetOnboardingOtp + + init { + enterNumberFragment.lifecycle.addObserver(this) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) + private fun onCreate() { + getOnboardingOtp = GetOnboardingOtp(NetworkFactory.awsClient, enterNumberFragment.lifecycle) + } + + internal fun requestOTP(phoneNumber: String) { + when { + enterNumberFragment.activity?.isInternetAvailable() == false -> { + enterNumberFragment.showCheckInternetError() + } + validateAuNumber(phoneNumber) -> { + val cleansedNumber = if (phoneNumber.startsWith("0")) { + phoneNumber.takeLast(TracerApp.AppContext.resources.getInteger(R.integer.australian_phone_number_length)) + } else phoneNumber + val fullNumber = "${enterNumberFragment.resources.getString(R.string.enter_number_prefix)}$cleansedNumber" + Preference.putPhoneNumber(TracerApp.AppContext, fullNumber) + this.phoneNumber = cleansedNumber + makeOTPCall(cleansedNumber) + } + else -> { + enterNumberFragment.showInvalidPhoneNumber() + } + } + } + + /** + * @param phoneNumber cleansed phone number, 9 digits, doesn't start with 0 + */ + private fun makeOTPCall(phoneNumber: String) { + enterNumberFragment.activity?.let { + enterNumberFragment.disableContinueButton() + enterNumberFragment.showLoading() + getOnboardingOtp.invoke(GetOtpParams(phoneNumber, + Preference.getDeviceID(enterNumberFragment.requireContext()), + Preference.getPostCode(enterNumberFragment.requireContext()), + Preference.getAge(enterNumberFragment.requireContext()), + Preference.getName(enterNumberFragment.requireContext())), + onSuccess = { + enterNumberFragment.navigateToOTPPage( + it.session, + it.challengeName, + phoneNumber) + }, + onFailure = { + if (it is GetOnboardingOtpException.GetOtpInvalidNumberException) { + enterNumberFragment.showInvalidPhoneNumber() + } else { + enterNumberFragment.showGenericError() + } + enterNumberFragment.hideLoading() + enterNumberFragment.enableContinueButton() + }) + } + } + + internal fun validateAuNumber(phoneNumber: String?): Boolean { + var australianPhoneNumberLength = enterNumberFragment.resources.getInteger(R.integer.australian_phone_number_length) + if (phoneNumber?.startsWith("0") == true) { + australianPhoneNumberLength++ + } + return (phoneNumber?.length ?: 0) == australianPhoneNumberLength + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinFragment.kt new file mode 100644 index 0000000..13e97b0 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinFragment.kt @@ -0,0 +1,191 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.enterpin + +import android.app.AlertDialog +import android.os.Bundle +import android.os.CountDownTimer +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.NavigationRes +import androidx.core.content.ContextCompat +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.extensions.toHyperlink +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import com.atlassian.mobilekit.module.core.utils.SystemUtils +import kotlinx.android.synthetic.main.fragment_enter_pin.* +import kotlinx.android.synthetic.main.fragment_enter_pin.view.* +import kotlin.math.floor + + +class EnterPinFragment : PagerChildFragment() { + + companion object { + const val ENTER_PIN_SESSION = "session" + const val ENTER_PIN_CHALLENGE_NAME = "challenge_name" + const val ENTER_PIN_PHONE_NUMBER = "phone_number" + const val ENTER_PIN_DESTINATION_ID = "destination_id" + const val ENTER_PIN_PROGRESS = "progress" + } + + override val navigationIcon = R.drawable.ic_up + override var stepProgress: Int? = 3 + + private val COUNTDOWN_DURATION = 5 * 60L // OTP Code expiry + + private var alertDialog: AlertDialog? = null + private var stopWatch: CountDownTimer? = null + private lateinit var presenter: EnterPinPresenter + @NavigationRes + private var destinationId: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_enter_pin, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + arguments?.let { + val session = it.getString(ENTER_PIN_SESSION) + val challengeName = it.getString(ENTER_PIN_CHALLENGE_NAME) + val phoneNumber = it.getString(ENTER_PIN_PHONE_NUMBER) + destinationId = it.getInt(ENTER_PIN_DESTINATION_ID) + stepProgress = if (it.containsKey(ENTER_PIN_PROGRESS)) it.getInt(ENTER_PIN_PROGRESS) else null + enter_pin_headline.text = resources.getString(R.string.enter_pin_headline, resources.getString(R.string.enter_number_prefix), phoneNumber) + presenter = EnterPinPresenter(this@EnterPinFragment, + session, + challengeName, + phoneNumber) + } + + enter_pin_wrong_number.toHyperlink { + popBackStack() + } + + enter_pin_resend_pin.toHyperlink { + presenter.resendCode() + } + + view.pin_issue.movementMethod = LinkMovementMethod.getInstance() + + startTimer() + } + + override fun onResume() { + super.onResume() + updateButtonState() + pin.onPinChanged = { + updateButtonState() + hideInvalidOtp() + } + } + + override fun onPause() { + super.onPause() + pin.onPinChanged = null + } + + private fun startTimer() { + stopWatch = object : CountDownTimer(COUNTDOWN_DURATION * 1000, 1000) { + override fun onTick(millisUntilFinished: Long) { + val numberOfMins = floor((millisUntilFinished * 1.0) / 60000) + val numberOfMinsInt = numberOfMins.toInt() + val numberOfSeconds = floor((millisUntilFinished / 1000.0) % 60) + val numberOfSecondsInt = numberOfSeconds.toInt() + val finalNumberOfSecondsString = if (numberOfSecondsInt < 10) { + "0$numberOfSecondsInt" + } else { + "$numberOfSecondsInt" + } + + enter_pin_timer_value?.text = "$numberOfMinsInt:$finalNumberOfSecondsString" + } + + override fun onFinish() { + enter_pin_timer_value?.text = "0:00" + enter_pin_resend_pin.isEnabled = true + activity?.let { + enter_pin_resend_pin.setLinkTextColor(ContextCompat.getColor(it, R.color.hyperlink_enabled)) + } + } + } + stopWatch?.start() + enter_pin_resend_pin.isEnabled = false + activity?.let { + enter_pin_resend_pin.setLinkTextColor(ContextCompat.getColor(it, R.color.hyperlink_disabled)) + } + } + + fun resetTimer() { + stopWatch?.cancel() + startTimer() + } + + override fun onDestroyView() { + super.onDestroyView() + stopWatch?.cancel() + alertDialog?.dismiss() + enter_pin_resend_pin.setOnClickListener(null) + enter_pin_wrong_number.setOnClickListener(null) + root.removeAllViews() + } + + fun hideKeyboard() { + activity?.currentFocus?.let { view -> + SystemUtils.hideSoftKeyboard(view) + } + } + + fun showInvalidOtp() { + enter_pin_error_label.visibility = View.VISIBLE + } + + private fun hideInvalidOtp() { + enter_pin_error_label.visibility = View.GONE + } + + fun showGenericError() { + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } + + private fun isIncorrectPinFormat(): Boolean { + return requireView().pin.isIncomplete + } + + override fun updateButtonState() { + if (isIncorrectPinFormat()) { + disableContinueButton() + } else { + enableContinueButton() + } + } + + private fun validateOtp() { + presenter.validateOTP(requireView().pin.value) + } + + fun showErrorOtpMustBeSixDigits() { + + } + + fun navigateToNextPage() { + navigateTo(destinationId ?: R.id.action_otpFragment_to_permissionFragment) + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.enter_pin_button) { + validateOtp() + } + + fun showCheckInternetError() { + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_internet_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinPresenter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinPresenter.kt new file mode 100644 index 0000000..339e64c --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/enterpin/EnterPinPresenter.kt @@ -0,0 +1,112 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.enterpin + +import android.text.TextUtils +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.extensions.isInternetAvailable +import au.gov.health.covidsafe.factory.NetworkFactory +import au.gov.health.covidsafe.interactor.usecase.GetOnboardingOtp +import au.gov.health.covidsafe.interactor.usecase.GetOtpParams +import au.gov.health.covidsafe.logging.CentralLog +import au.gov.health.covidsafe.networking.request.AuthChallengeRequest +import au.gov.health.covidsafe.networking.response.AuthChallengeResponse +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +class EnterPinPresenter(private val enterPinFragment: EnterPinFragment, + private var session: String?, + private var challengeName: String?, + private val phoneNumber: String?) : LifecycleObserver { + + private val TAG = this.javaClass.simpleName + + private var awsClient = NetworkFactory.awsClient + private lateinit var getOtp: GetOnboardingOtp + + init { + enterPinFragment.lifecycle.addObserver(this) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) + private fun onCreate() { + getOtp = GetOnboardingOtp(awsClient, enterPinFragment.lifecycle) + } + + internal fun resendCode() { + enterPinFragment.activity?.let { + when { + !it.isInternetAvailable() -> { + enterPinFragment.showCheckInternetError() + } + phoneNumber == null -> { + enterPinFragment.showGenericError() + } + else -> { + getOtp.invoke(GetOtpParams(phoneNumber, + Preference.getDeviceID(enterPinFragment.requireContext()), + Preference.getPostCode(enterPinFragment.requireContext()), + Preference.getAge(enterPinFragment.requireContext()), + Preference.getName(enterPinFragment.requireContext())), + onSuccess = { + session = it.session + challengeName = it.challengeName + enterPinFragment.resetTimer() + }, + onFailure = { + enterPinFragment.showGenericError() + }) + } + } + } + } + + internal fun validateOTP(otp: String) { + if (TextUtils.isEmpty(otp) || otp.length != 6) { + enterPinFragment.showErrorOtpMustBeSixDigits() + return + } + if (enterPinFragment.activity?.isInternetAvailable() == false) { + enterPinFragment.showCheckInternetError() + return + } + enterPinFragment.disableContinueButton() + enterPinFragment.showLoading() + val authChallengeCall: Call = awsClient.respondToAuthChallenge(AuthChallengeRequest(session, otp)) + authChallengeCall.enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + if (response.code() == 200) { + CentralLog.d(TAG, "code received") + + val authChallengeResponse = response.body() + + val handShakePin = authChallengeResponse?.pin + handShakePin?.let { + Preference.putHandShakePin(enterPinFragment.context, handShakePin) + } + val jwtToken = authChallengeResponse?.token + jwtToken.let { + Preference.putEncrypterJWTToken(enterPinFragment.requireContext(), jwtToken) + } + enterPinFragment.hideKeyboard() + enterPinFragment.navigateToNextPage() + } else { + onError() + } + } + + override fun onFailure(call: Call, t: Throwable) { + onError() + } + }) + } + + private fun onError() { + enterPinFragment.enableContinueButton() + enterPinFragment.hideLoading() + enterPinFragment.hideKeyboard() + enterPinFragment.showInvalidOtp() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/howitworks/HowItWorksFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/howitworks/HowItWorksFragment.kt new file mode 100644 index 0000000..14688d0 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/howitworks/HowItWorksFragment.kt @@ -0,0 +1,39 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.howitworks + +import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_how_it_works.* +import kotlinx.android.synthetic.main.fragment_how_it_works.view.* + +class HowItWorksFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_how_it_works, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + view.how_it_works_content.movementMethod = LinkMovementMethod.getInstance() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.how_it_works_button) { + navigateTo(R.id.action_howItWorksFragment_to_dataPrivacy) + } + + override fun updateButtonState() { + enableContinueButton() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/introduction/IntroductionFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/introduction/IntroductionFragment.kt new file mode 100644 index 0000000..26bc4f6 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/introduction/IntroductionFragment.kt @@ -0,0 +1,32 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.introduction + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_intro.* + +class IntroductionFragment : PagerChildFragment() { + + override val navigationIcon: Int? = null + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_intro, container, false) + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.intro_button) { + navigateTo(R.id.action_introFragment_to_howItWorksFragment) + } + + override fun updateButtonState() { + enableContinueButton() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permission/PermissionFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permission/PermissionFragment.kt new file mode 100644 index 0000000..7c58d15 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permission/PermissionFragment.kt @@ -0,0 +1,121 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.permission + +import android.Manifest +import android.app.Activity +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Bundle +import android.os.Handler +import android.os.PowerManager +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import au.gov.health.covidsafe.HomeActivity +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.TracerApp +import au.gov.health.covidsafe.extensions.* +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_permission.* +import pub.devrel.easypermissions.EasyPermissions + +class PermissionFragment : PagerChildFragment(), EasyPermissions.PermissionCallbacks { + + companion object { + + val requiredPermissions = arrayOf( + Manifest.permission.BLUETOOTH, + Manifest.permission.BLUETOOTH_ADMIN, + Manifest.permission.ACCESS_FINE_LOCATION + ) + } + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = 5 + + private var navigationStarted = false + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_permission, container, false) + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (requestCode == REQUEST_ENABLE_BT) { + if (resultCode == Activity.RESULT_CANCELED) { + excludeFromBatteryOptimization { navigateToNextPage() } + return + } else { + requestAllPermissions { navigateToNextPage() } + } + } else if (requestCode == BATTERY_OPTIMISER) { + Handler().postDelayed({ + navigateToNextPage() + }, 1000) + } else super.onActivityResult(requestCode, resultCode, data) + } + + private fun navigateToNextPage() { + navigationStarted = false + if (hasAllPermissionsAndBluetoothOn()) { + navigateTo(R.id.action_permissionFragment_to_permissionSuccessFragment) + } else { + navigateToMainActivity() + } + } + + private fun hasAllPermissionsAndBluetoothOn(): Boolean { + val context = TracerApp.AppContext + return isBlueToothEnabled() == true + && requiredPermissions.all { ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED } + && ContextCompat.getSystemService(context, PowerManager::class.java)?.isIgnoringBatteryOptimizations(context.packageName) ?: true + } + + private fun navigateToMainActivity() { + val intent = Intent(context, HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + activity?.startActivity(intent) + activity?.finish() + } + + override fun onPermissionsDenied(requestCode: Int, perms: MutableList) { + if (requestCode == LOCATION) { + excludeFromBatteryOptimization { navigateToNextPage() } + } else { + requestAllPermissions { navigateToNextPage() } + } + } + + override fun onPermissionsGranted(requestCode: Int, perms: MutableList) { + requestAllPermissions { navigateToNextPage() } + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this) + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.permission_button) { + disableContinueButton() + navigationStarted = true + activity?.let { + Preference.putIsOnBoarded(it, true) + } + requestAllPermissions { + navigateToNextPage() + } + } + + override fun updateButtonState() { + if (navigationStarted) { + disableContinueButton() + } else { + enableContinueButton() + } + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt new file mode 100644 index 0000000..6b49e20 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/permissionsuccess/PermissionSuccessFragment.kt @@ -0,0 +1,41 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.permissionsuccess + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import kotlinx.android.synthetic.main.fragment_permission_success.* +import au.gov.health.covidsafe.HomeActivity +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout + +class PermissionSuccessFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = 5 + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_permission_success, container, false) + + private fun navigateToNextPage() { + val intent = Intent(context, HomeActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + activity?.startActivity(intent) + activity?.finish() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.permission_success_button) { + navigateToNextPage() + } + + override fun updateButtonState() { + enableContinueButton() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsFragment.kt new file mode 100644 index 0000000..362ce14 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsFragment.kt @@ -0,0 +1,182 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.personal + +import android.app.Activity +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager +import android.widget.NumberPicker +import androidx.appcompat.app.AlertDialog +import androidx.core.os.bundleOf +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import au.gov.health.covidsafe.ui.onboarding.fragment.enternumber.EnterNumberFragment +import kotlinx.android.synthetic.main.fragment_personal_details.* + +class PersonalDetailsFragment : PagerChildFragment() { + + private var picker: NumberPicker? = null + + private var alertDialog: AlertDialog? = null + override var stepProgress: Int? = 1 + override val navigationIcon: Int = R.drawable.ic_up + private var ageSelected: Pair? = null + + private val presenter = PersonalDetailsPresenter(this) + + private val nameTextWatcher: TextWatcher = object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + hideNameError() + updateButtonState() + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + } + + private val postCodeTextWatcher: TextWatcher = object : TextWatcher { + override fun afterTextChanged(s: Editable?) { + presenter.validateInlinePostCode(s.toString()) + updateButtonState() + } + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_personal_details, container, false) + + override fun onResume() { + super.onResume() + personal_details_name.addTextChangedListener(nameTextWatcher) + personal_details_post_code.addTextChangedListener(postCodeTextWatcher) + personal_details_age.setOnClickListener { + showAgePicker() + } + personal_details_age.text = ageSelected?.second + + } + + override fun onPause() { + super.onPause() + personal_details_name.removeTextChangedListener(nameTextWatcher) + personal_details_post_code.removeTextChangedListener(postCodeTextWatcher) + personal_details_age.setOnClickListener(null) + alertDialog?.dismiss() + } + + override fun getUploadButtonLayout(): UploadButtonLayout = UploadButtonLayout.ContinueLayout(R.string.personal_details_button) { + presenter.saveInfos(personal_details_name.text.toString(), personal_details_post_code.text.toString(), getMidAgeToSend()) + } + + override fun updateButtonState() { + if (presenter.validateInputsForButtonUpdate(personal_details_name.text.toString(), personal_details_post_code.text.toString(), getMidAgeToSend())) { + enableContinueButton() + } else { + disableContinueButton() + } + } + + fun showGenericError() { + activity?.let { activity -> + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } + } + + fun navigateToNextPage(minor: Boolean) { + if (minor) { + navigateTo(PersonalDetailsFragmentDirections.actionPersonalDetailsToUnderSixteenFragment().actionId) + } else { + val bundle = bundleOf( + EnterNumberFragment.ENTER_NUMBER_DESTINATION_ID to R.id.action_otpFragment_to_permissionFragment, + EnterNumberFragment.ENTER_NUMBER_PROGRESS to 2) + navigateTo(PersonalDetailsFragmentDirections.actionPersonalDetailsToEnterNumberFragment().actionId, bundle) + } + } + + fun showPostcodeError() { + personal_details_post_code_error.visibility = VISIBLE + } + + fun hidePostcodeError() { + personal_details_post_code_error.visibility = GONE + } + + fun showNameError() { + personal_details_name_error.visibility = VISIBLE + } + + fun hideNameError() { + personal_details_name_error.visibility = GONE + } + + fun showAgeError() { + personal_details_age_error.visibility = VISIBLE + } + + fun hideAgeError() { + personal_details_age_error.visibility = GONE + } + + private fun showAgePicker() { + activity?.let { activity -> + val ages = resources.getStringArray(R.array.personal_details_age_array).map { + it.split(":").let { it[0] to it[1] } + } + var selected = ages.firstOrNull { it == ageSelected }?.let { + ages.indexOf(it) + } ?: 0 + + picker = NumberPicker(activity) + picker?.minValue = 0 + picker?.maxValue = ages.size - 1 + picker?.displayedValues = ages.map { it.second }.toTypedArray() + picker?.setOnValueChangedListener { _, _, newVal -> + selected = newVal + } + picker?.value = selected + alertDialog?.dismiss() + alertDialog = AlertDialog.Builder(activity) + .setTitle(R.string.personal_details_age_dialog_title) + .setView(picker) + .setPositiveButton(R.string.personal_details_dialog_ok) { _, _ -> + ageSelected = ages[selected] + personal_details_age.text = ages[selected].second + hideAgeError() + updateButtonState() + } + .setNegativeButton(android.R.string.no, null) + .show() + } + } + + private fun getMidAgeToSend(): String? { + val ages = resources.getStringArray(R.array.personal_details_age_array).map { + it.split(":").let { it[0] to it[1] } + } + val selected = ages.firstOrNull { it == ageSelected }?.let { + ages.indexOf(it) + } + return selected?.let { + ages[selected].first + } + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsPresenter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsPresenter.kt new file mode 100644 index 0000000..7c60df8 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/personal/PersonalDetailsPresenter.kt @@ -0,0 +1,96 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.personal + +import au.gov.health.covidsafe.Preference +import java.util.regex.Pattern + +class PersonalDetailsPresenter(private val personalDetailsFragment: PersonalDetailsFragment) { + + private val TAG = this.javaClass.simpleName + + private val POST_CODE_REGEX = Pattern.compile("^(?:(?:[2-8]\\d|9[0-7]|0?[28]|0?9(?=09))(?:\\d{2}))$") + + fun saveInfos(name: String?, postCode: String?, age: String?) { + personalDetailsFragment.showLoading() + personalDetailsFragment.context?.let { context -> + val ageInt = age?.toIntOrNull() + val nameValid = name.isNullOrBlank().not() + val postCodeValid = postCode.isNullOrBlank().not() && isPostCodeValid(postCode) + val ageValid = age.isNullOrBlank().not() + + if (nameValid && postCodeValid && ageValid) { + val valid = (name?.let { name -> + Preference.putName(context, name) + } ?: false) && + (age?.let { age -> + Preference.putAge(context, age) + } ?: false) && + (postCode?.let { postCode -> + Preference.putPostCode(context, postCode) + } ?: false) + + if (valid) { + personalDetailsFragment.hideLoading() + personalDetailsFragment.navigateToNextPage(ageInt?.let { it < 16 } ?: false) + } else { + personalDetailsFragment.hideLoading() + personalDetailsFragment.showGenericError() + } + } else { + showFieldsError(name, postCode, age) + personalDetailsFragment.hideLoading() + } + } ?: run { + personalDetailsFragment.hideLoading() + personalDetailsFragment.showGenericError() + } + } + + private fun showFieldsError(name: String?, postCode: String?, age: String?) { + updateNameFieldError(name) + updateAgeFieldError(age) + updatePostcodeFieldError(postCode) + } + + private fun updateAgeFieldError(age: String?) { + return if (age.isNullOrBlank()) { + personalDetailsFragment.showAgeError() + } else { + personalDetailsFragment.hideAgeError() + } + } + + private fun updateNameFieldError(name: String?) { + return if (name.isNullOrBlank()) { + personalDetailsFragment.showNameError() + } else { + personalDetailsFragment.hideNameError() + } + } + + private fun updatePostcodeFieldError(postCode: String?) { + return if (postCode.isNullOrBlank()) { + personalDetailsFragment.showPostcodeError() + } else { + personalDetailsFragment.hidePostcodeError() + } + } + + fun validateInputsForButtonUpdate(name: String?, postCode: String?, age: String?): Boolean { + val nameValid = name.isNullOrBlank().not() + val postCodeValid = postCode.isNullOrBlank().not() && isPostCodeValid(postCode) + val ageValid = age.isNullOrBlank().not() + + return nameValid && postCodeValid && ageValid + } + + internal fun validateInlinePostCode(postCode: String?) { + if (!postCode.isNullOrEmpty() && postCode.length == 4 && !isPostCodeValid(postCode)) { + personalDetailsFragment.showPostcodeError() + } else { + personalDetailsFragment.hidePostcodeError() + } + } + + private fun isPostCodeValid(postCode: String?) = POST_CODE_REGEX.matcher(postCode.toString()).matches() + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/registrationcontent/RegistrationContentFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/registrationcontent/RegistrationContentFragment.kt new file mode 100644 index 0000000..11654d3 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/registrationcontent/RegistrationContentFragment.kt @@ -0,0 +1,44 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.registrationcontent + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.PagerContainer +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_registration_consent.* + +class RegistrationContentFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_registration_consent, container, false) + + override fun onResume() { + super.onResume() + registration_consent_checkbox.setOnCheckedChangeListener { buttonView, isChecked -> + updateButtonState() + } + } + + override fun updateButtonState() { + if (registration_consent_checkbox.isChecked) { + (activity as? PagerContainer)?.enableNextButton() + } else { + (activity as? PagerContainer)?.disableNextButton() + } + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.registration_consent_button) { + navigateTo(RegistrationContentFragmentDirections.actionRegistrationConsentFragmentToPersonalDetailsFragment().actionId) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/undersixteen/UnderSixteenFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/undersixteen/UnderSixteenFragment.kt new file mode 100644 index 0000000..f163647 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/onboarding/fragment/undersixteen/UnderSixteenFragment.kt @@ -0,0 +1,51 @@ +package au.gov.health.covidsafe.ui.onboarding.fragment.undersixteen + +import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.os.bundleOf +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import au.gov.health.covidsafe.ui.onboarding.fragment.enternumber.EnterNumberFragment +import kotlinx.android.synthetic.main.fragment_under_sixteen.* + +class UnderSixteenFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + + override var stepProgress: Int? = null + + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) + : View? = inflater.inflate(R.layout.fragment_under_sixteen, container, false) + + override fun onResume() { + super.onResume() + under_sixteen_checkbox.setOnCheckedChangeListener { buttonView, isChecked -> + updateButtonState() + } + } + + override fun onPause() { + super.onPause() + under_sixteen_checkbox.setOnCheckedChangeListener(null) + } + + override fun getUploadButtonLayout(): UploadButtonLayout = UploadButtonLayout.ContinueLayout(R.string.under_sixteen_button) { + val bundle = bundleOf( + EnterNumberFragment.ENTER_NUMBER_DESTINATION_ID to R.id.action_otpFragment_to_permissionFragment, + EnterNumberFragment.ENTER_NUMBER_PROGRESS to 2) + navigateTo(UnderSixteenFragmentDirections.actionUnderSixteenFragmentToEnterNumberFragment().actionId, bundle) + } + + override fun updateButtonState() { + if (under_sixteen_checkbox.isChecked) { + enableContinueButton() + } else { + disableContinueButton() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/UploadContainerFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/UploadContainerFragment.kt new file mode 100644 index 0000000..489b42f --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/UploadContainerFragment.kt @@ -0,0 +1,107 @@ +package au.gov.health.covidsafe.ui.upload + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.View.* +import android.view.ViewGroup +import androidx.annotation.StringRes +import androidx.core.content.ContextCompat +import androidx.fragment.app.Fragment +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerContainer +import au.gov.health.covidsafe.ui.UploadButtonLayout +import com.github.razir.progressbutton.hideProgress +import com.github.razir.progressbutton.showProgress +import kotlinx.android.synthetic.main.fragment_upload_master.* + +class UploadContainerFragment : Fragment(), PagerContainer { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.fragment_upload_master, container, false) + + override fun onResume() { + super.onResume() + toolbar.setNavigationOnClickListener { + activity?.onBackPressed() + } + } + + override fun onPause() { + super.onPause() + toolbar.setNavigationOnClickListener(null) + } + + override fun updateProgressBar(stepProgress: Int?) { + if (stepProgress == null) { + upload_progress.visibility = INVISIBLE + } else { + upload_progress.visibility = VISIBLE + upload_progress.progress = stepProgress + } + } + + override fun setNavigationIcon(navigationIcon: Int?) { + if (navigationIcon == null) { + toolbar.navigationIcon = null + } else { + activity?.let { + toolbar.navigationIcon = ContextCompat.getDrawable(it, navigationIcon) + } + } + } + + override fun refreshButton(uploadButtonLayout: UploadButtonLayout) { + when (uploadButtonLayout) { + is UploadButtonLayout.ContinueLayout -> { + upload_continue.setOnClickListener { + uploadButtonLayout.buttonListener?.invoke() + } + upload_continue.setText(uploadButtonLayout.buttonText) + upload_continue.visibility = VISIBLE + upload_answerNo.setOnClickListener(null) + upload_answerYes.setOnClickListener(null) + upload_answerNo.visibility = GONE + upload_answerYes.visibility = GONE + } + is UploadButtonLayout.QuestionLayout -> { + upload_continue.setOnClickListener(null) + upload_continue.visibility = GONE + upload_answerNo.setOnClickListener { + uploadButtonLayout.buttonNoListener.invoke() + } + upload_answerYes.setOnClickListener { + uploadButtonLayout.buttonYesListener.invoke() + } + upload_answerNo.visibility = VISIBLE + upload_answerYes.visibility = VISIBLE + } + } + } + + override fun enableNextButton() { + upload_continue.isEnabled = true + } + + override fun disableNextButton() { + upload_continue.isEnabled = false + } + + override fun showLoading() { + upload_continue.showProgress { + progressColorRes = R.color.slack_black_2 + } + } + + override fun hideLoading(@StringRes stringRes: Int?) { + if (stringRes == null) { + upload_continue.hideProgress() + } else { + upload_continue.hideProgress(newTextRes = stringRes) + } + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/DebugData.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/DebugData.kt new file mode 100644 index 0000000..39e97e8 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/DebugData.kt @@ -0,0 +1,5 @@ +package au.gov.health.covidsafe.ui.upload.model + +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord + +class DebugData constructor(var records: List) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/ExportData.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/ExportData.kt new file mode 100644 index 0000000..946deaf --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/model/ExportData.kt @@ -0,0 +1,6 @@ +package au.gov.health.covidsafe.ui.upload.model + +import androidx.annotation.Keep +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecord +@Keep +class ExportData constructor(var records: List) \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadFinishedFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadFinishedFragment.kt new file mode 100644 index 0000000..4f590d4 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadFinishedFragment.kt @@ -0,0 +1,32 @@ +package au.gov.health.covidsafe.ui.upload.presentation + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_upload_finished.* + +class UploadFinishedFragment : PagerChildFragment() { + + override val navigationIcon: Int? = null + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = + inflater.inflate(R.layout.fragment_upload_finished, container, false) + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.action_upload_done) { + activity?.onBackPressed() + } + + override fun updateButtonState() { + enableContinueButton() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadInitialFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadInitialFragment.kt new file mode 100644 index 0000000..0f1a0f6 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadInitialFragment.kt @@ -0,0 +1,39 @@ +package au.gov.health.covidsafe.ui.upload.presentation + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_upload_page_4.* + +class UploadInitialFragment : PagerChildFragment() { + + override val navigationIcon: Int? = R.drawable.ic_up + + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = + inflater.inflate(R.layout.fragment_upload_initial, container, false) + + + override fun updateButtonState() { + enableContinueButton() + } + + override fun getUploadButtonLayout() = UploadButtonLayout.QuestionLayout( + buttonYesListener = { + navigateTo(R.id.action_uploadInitial_to_uploadStepFourFragment) + }, + buttonNoListener = { + activity?.onBackPressed() + }) + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } + +} diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadStepFourFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadStepFourFragment.kt new file mode 100644 index 0000000..4aae617 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/UploadStepFourFragment.kt @@ -0,0 +1,59 @@ +package au.gov.health.covidsafe.ui.upload.presentation + +import android.app.AlertDialog +import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import kotlinx.android.synthetic.main.fragment_upload_page_4.* + +class UploadStepFourFragment : PagerChildFragment() { + + private var alertDialog: AlertDialog? = null + override var stepProgress: Int? = null + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = + inflater.inflate(R.layout.fragment_upload_page_4, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + subHeader.movementMethod = LinkMovementMethod.getInstance() + } + + + override fun onResume() { + super.onResume() + upload_consent_checkbox.setOnCheckedChangeListener { buttonView, isChecked -> + updateButtonState() + } + } + override fun updateButtonState() { + if (upload_consent_checkbox.isChecked) { + enableContinueButton() + } else { + disableContinueButton() + } + } + + override val navigationIcon: Int? = R.drawable.ic_up + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout( + R.string.action_agree) { + navigateToVerifyUploadPin() + } + + private fun navigateToVerifyUploadPin() { + navigateTo(R.id.action_uploadStepFourFragment_to_verifyUploadPinFragment) + } + + override fun onDestroyView() { + super.onDestroyView() + alertDialog?.dismiss() + root.removeAllViews() + } + +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinFragment.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinFragment.kt new file mode 100644 index 0000000..25c4301 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinFragment.kt @@ -0,0 +1,136 @@ +package au.gov.health.covidsafe.ui.upload.presentation + +import android.app.AlertDialog +import android.app.Dialog +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.os.bundleOf +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.PagerChildFragment +import au.gov.health.covidsafe.ui.UploadButtonLayout +import au.gov.health.covidsafe.ui.onboarding.fragment.enternumber.EnterNumberFragment +import au.gov.health.covidsafe.ui.view.UploadingDialog +import au.gov.health.covidsafe.ui.view.UploadingErrorDialog +import com.atlassian.mobilekit.module.core.utils.SystemUtils +import kotlinx.android.synthetic.main.fragment_verify_upload_pin.* +import kotlinx.android.synthetic.main.fragment_verify_upload_pin.view.* + + +class VerifyUploadPinFragment : PagerChildFragment() { + + interface OnUploadErrorInterface { + fun onPositiveClicked() + fun onNegativeClicked() + } + + private var dialog: Dialog? = null + + private lateinit var presenter : VerifyUploadPinPresenter + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = + inflater.inflate(R.layout.fragment_verify_upload_pin, container, false) + + override val navigationIcon: Int? = R.drawable.ic_up + override var stepProgress: Int? = null + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + presenter = VerifyUploadPinPresenter(this) + } + + override fun onResume() { + super.onResume() + pin.onPinChanged = { + updateButtonState() + hideInvalidOtp() + } + } + + override fun onPause() { + super.onPause() + pin.onPinChanged = null + } + + override fun getUploadButtonLayout() = UploadButtonLayout.ContinueLayout(R.string.action_verify_upload_pin) { + presenter.uploadData(requireView().pin.value) + } + + override fun updateButtonState() { + if (isIncorrectPinFormat()) { + disableContinueButton() + } else { + enableContinueButton() + } + } + + private fun isIncorrectPinFormat(): Boolean { + return requireView().pin.isIncomplete + } + + fun hideKeyboard() { + activity?.currentFocus?.let { view -> + SystemUtils.hideSoftKeyboard(view) + } + } + + fun showInvalidOtp() { + dialog?.dismiss() + enter_pin_error_label.visibility = View.VISIBLE + } + + private fun hideInvalidOtp() { + enter_pin_error_label.visibility = View.GONE + } + + fun showGenericError() { + dialog?.dismiss() + activity?.let { + dialog = UploadingErrorDialog(it, object : OnUploadErrorInterface { + override fun onPositiveClicked() { + presenter.uploadData(requireView().pin.value) + } + + override fun onNegativeClicked() { + dialog?.dismiss() + } + }) + dialog?.show() + } + } + + override fun onStop() { + super.onStop() + dialog?.dismiss() + } + + override fun onDestroyView() { + super.onDestroyView() + root.removeAllViews() + } + + fun navigateToRegister() { + val bundle = bundleOf( + EnterNumberFragment.ENTER_NUMBER_DESTINATION_ID to R.id.action_enterPinFragment_to_uploadStepFourFragment) + navigateTo(VerifyUploadPinFragmentDirections.actionVerifyUploadPinFragmentToEnterNumberFragment().actionId, bundle) + } + + fun navigateToNextPage() { + navigateTo(R.id.action_verifyUploadPinFragment_to_uploadFinishedFragment) + } + + fun showDialogLoading() { + dialog?.dismiss() + dialog = UploadingDialog(requireActivity()) + dialog?.show() + } + + fun showCheckInternetError() { + dialog?.dismiss() + dialog = AlertDialog.Builder(activity) + .setMessage(R.string.generic_internet_error) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(android.R.string.yes, null).show() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinPresenter.kt b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinPresenter.kt new file mode 100644 index 0000000..5a7a0e5 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/upload/presentation/VerifyUploadPinPresenter.kt @@ -0,0 +1,74 @@ +package au.gov.health.covidsafe.ui.upload.presentation + +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import au.gov.health.covidsafe.BuildConfig +import au.gov.health.covidsafe.Preference +import au.gov.health.covidsafe.extensions.isInternetAvailable +import au.gov.health.covidsafe.factory.NetworkFactory +import au.gov.health.covidsafe.interactor.usecase.UploadData +import au.gov.health.covidsafe.interactor.usecase.UploadDataException +import au.gov.health.covidsafe.streetpass.persistence.StreetPassRecordStorage +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + + +class VerifyUploadPinPresenter(private val fragment: VerifyUploadPinFragment) : LifecycleObserver { + + private val TAG = this.javaClass.simpleName + + private var awsClient = NetworkFactory.awsClient + private lateinit var uploadData: UploadData + + private lateinit var recordStorage: StreetPassRecordStorage + + init { + fragment.lifecycle.addObserver(this) + fragment.context?.let { context -> + recordStorage = StreetPassRecordStorage(context) + } + } + + @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) + private fun onCreate() { + uploadData = UploadData(awsClient, NetworkFactory.okHttpClient, fragment.context, fragment.lifecycle) + } + + internal fun uploadData(otp: String) { + if (fragment.activity?.isInternetAvailable() == false) { + fragment.showCheckInternetError() + } else { + fragment.disableContinueButton() + fragment.showDialogLoading() + uploadData.invoke(otp, + onSuccess = { + if (!BuildConfig.DEBUG) { + GlobalScope.launch { recordStorage.nukeDbAsync() } + } + fragment.context?.let { context -> + Preference.setDataIsUploaded(context, true) + } + fragment.navigateToNextPage() + }, + onFailure = { + when (it) { + is UploadDataException.UploadDataIncorrectPinException -> { + fragment.showInvalidOtp() + } + is UploadDataException.UploadDataJwtExpiredException -> { + fragment.navigateToRegister() + } + else -> { + fragment.showGenericError() + } + } + fragment.enableContinueButton() + fragment.hideKeyboard() + fragment.hideLoading() + } + ) + } + } +} + diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/view/PinInputView.kt b/app/src/main/java/au/gov/health/covidsafe/ui/view/PinInputView.kt new file mode 100644 index 0000000..59f9435 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/view/PinInputView.kt @@ -0,0 +1,76 @@ +package au.gov.health.covidsafe.ui.view + +import android.content.Context +import android.util.AttributeSet +import android.view.KeyEvent +import android.view.LayoutInflater +import android.widget.EditText +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.widget.doAfterTextChanged +import kotlinx.android.synthetic.main.view_pin.view.* +import au.gov.health.covidsafe.R + +class PinInputView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = -1) : ConstraintLayout(context, attrs, defStyle) { + + private val pinOne: EditText? by lazy { pin_1 } + private val pinTwo: EditText? by lazy { pin_2 } + private val pinThree: EditText? by lazy { pin_3 } + private val pinFour: EditText? by lazy { pin_4 } + private val pinFive: EditText? by lazy { pin_5 } + private val pinSix: EditText? by lazy { pin_6 } + var onPinChanged: (() -> Unit)? = null + + private val allInputs by lazy { + listOf(pinOne, pinTwo, pinThree, pinFour, pinFive, pinSix) + } + + val value: String + get() = allInputs.mapNotNull { it?.text }.joinToString("") + + val isIncomplete: Boolean + get() = allInputs.any { it?.text.isNullOrEmpty() } + + init { + LayoutInflater.from(context).inflate(R.layout.view_pin, this, true) + pinOne?.onDigitChanged(pinTwo) + pinOne?.onDeletePressed(null) + + pinTwo?.onDigitChanged(pinThree) + pinTwo?.onDeletePressed(pinOne) + + pinThree?.onDigitChanged(pinFour) + pinThree?.onDeletePressed(pinTwo) + + pinFour?.onDigitChanged(pinFive) + pinFour?.onDeletePressed(pinThree) + + pinFive?.onDigitChanged(pinSix) + pinFive?.onDeletePressed(pinFour) + + pinSix?.onDigitChanged(null) + pinSix?.onDeletePressed(pinFive) + } + + private fun EditText.onDigitChanged(next: EditText? = null) { + doAfterTextChanged { + if (it?.length == 1) { + next?.requestFocus() + onPinChanged?.invoke() + } else if (it.isNullOrBlank()) { + onPinChanged?.invoke() + } + } + } + + private fun EditText.onDeletePressed(prev: EditText? = null) { + setOnKeyListener { view, keyCode, keyEvent -> + if (keyCode == KeyEvent.KEYCODE_DEL && text.isNullOrEmpty()) { + prev?.requestFocus() + onPinChanged?.invoke() + true + } else { + false + } + } + } +} diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/view/SegmentedProgressBar.kt b/app/src/main/java/au/gov/health/covidsafe/ui/view/SegmentedProgressBar.kt new file mode 100644 index 0000000..97a2cf6 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/view/SegmentedProgressBar.kt @@ -0,0 +1,53 @@ +package au.gov.health.covidsafe.ui.view + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import android.widget.LinearLayout +import androidx.core.content.ContextCompat +import au.gov.health.covidsafe.R + +class SegmentedProgressBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = -1) : LinearLayout(context, attrs, defStyle) { + private val maxValue: Int + var progress: Int = DEFAULT_PROGRESS + set(value) { + field = value + for (i in 0..childCount) { + val segment = getChildAt(i) + segment?.isSelected = i + 1 <= progress + } + } + + private val segmentSpacing: Int + + init { + orientation = HORIZONTAL + val values = context.obtainStyledAttributes(attrs, R.styleable.SegmentedProgressBar, defStyle, 0) + maxValue = values.getInt(R.styleable.SegmentedProgressBar_progress_max_value, DEFAULT_MAX_VALUE) + segmentSpacing = values.getDimensionPixelSize(R.styleable.SegmentedProgressBar_segment_spacing, + DEFAULT_SEGMENT_SPACING_DP * resources.displayMetrics.density.toInt()) + progress = values.getInt(R.styleable.SegmentedProgressBar_progress_value, DEFAULT_PROGRESS) + drawProgress() + values.recycle() + } + + private fun drawProgress() { + repeat(maxValue) { index -> + val lp = generateDefaultLayoutParams() + lp.height = LayoutParams.WRAP_CONTENT + lp.width = 0 + lp.weight = 1.0f + lp.rightMargin = if (index in 1 until maxValue - 1) segmentSpacing else 0 + lp.leftMargin = if (index > 0) segmentSpacing else 0 + + val view = View(context) + view.background = ContextCompat.getDrawable(context, R.drawable.progress_segment) + view.isSelected = index + 1 <= progress + addView(view, lp) + } + } +} + +private const val DEFAULT_MAX_VALUE = 5 +private const val DEFAULT_PROGRESS = 0 +private const val DEFAULT_SEGMENT_SPACING_DP = 4 \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/view/UlView.kt b/app/src/main/java/au/gov/health/covidsafe/ui/view/UlView.kt new file mode 100644 index 0000000..648a737 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/view/UlView.kt @@ -0,0 +1,30 @@ +package au.gov.health.covidsafe.ui.view + +import android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.LinearLayout +import au.gov.health.covidsafe.R +import kotlinx.android.synthetic.main.view_ul.view.* + +class UlView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : LinearLayout(context, attrs, defStyleAttr) { + + init { + LayoutInflater.from(context).inflate(R.layout.view_ul, this, true) + + val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.UlView) + val title = a.getString(R.styleable.UlView_ul_view_text) + + ul_content.text = title + + layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + + a.recycle() + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingDialog.kt b/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingDialog.kt new file mode 100644 index 0000000..c524c47 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingDialog.kt @@ -0,0 +1,24 @@ +package au.gov.health.covidsafe.ui.view + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Window +import android.view.WindowManager +import au.gov.health.covidsafe.R + +class UploadingDialog(context: Context) : Dialog(context) { + + init { + setCancelable(false) + setCanceledOnTouchOutside(false) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requestWindowFeature(Window.FEATURE_NO_TITLE) + setContentView(R.layout.dialog_uploading) + val window: Window? = this.window + window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT) + } +} \ No newline at end of file diff --git a/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingErrorDialog.kt b/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingErrorDialog.kt new file mode 100644 index 0000000..38f6b84 --- /dev/null +++ b/app/src/main/java/au/gov/health/covidsafe/ui/view/UploadingErrorDialog.kt @@ -0,0 +1,32 @@ +package au.gov.health.covidsafe.ui.view + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Window +import android.view.WindowManager +import au.gov.health.covidsafe.R +import au.gov.health.covidsafe.ui.upload.presentation.VerifyUploadPinFragment +import kotlinx.android.synthetic.main.dialog_error_uploading.* + +class UploadingErrorDialog(context: Context, private val listener: VerifyUploadPinFragment.OnUploadErrorInterface) : Dialog(context) { + + init { + setCancelable(false) + setCanceledOnTouchOutside(false) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requestWindowFeature(Window.FEATURE_NO_TITLE) + setContentView(R.layout.dialog_error_uploading) + val window: Window? = this.window + window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT) + dialog_error_positive.setOnClickListener { + listener.onPositiveClicked() + } + dialog_error_negative.setOnClickListener { + listener.onNegativeClicked() + } + } +} \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_left.xml b/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..b5eb2cd --- /dev/null +++ b/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..95c1e58 --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..c764ede --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/slide_out_right.xml b/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..20db00c --- /dev/null +++ b/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/default_button_text_color.xml b/app/src/main/res/color/default_button_text_color.xml new file mode 100644 index 0000000..2e8bf89 --- /dev/null +++ b/app/src/main/res/color/default_button_text_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/color/progress_segment.xml b/app/src/main/res/color/progress_segment.xml new file mode 100644 index 0000000..f780887 --- /dev/null +++ b/app/src/main/res/color/progress_segment.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi-v24/ic_notification_setting.xml b/app/src/main/res/drawable-anydpi-v24/ic_notification_setting.xml new file mode 100644 index 0000000..3914c01 --- /dev/null +++ b/app/src/main/res/drawable-anydpi-v24/ic_notification_setting.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/app/src/main/res/drawable-hdpi/australian_government_stacked_white.png b/app/src/main/res/drawable-hdpi/australian_government_stacked_white.png new file mode 100644 index 0000000000000000000000000000000000000000..281714e70281022eef143a590bfb3455fc93b80a GIT binary patch literal 35097 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/ic_notification_warning.png b/app/src/main/res/drawable-hdpi/ic_notification_warning.png new file mode 100755 index 0000000000000000000000000000000000000000..deed9a0119d60a3fb515d7939e51f30117f9d226 GIT binary patch literal 567 zcmV-70?7S|P)`@=)lR<2LL67Tz`V`5;R?_M+TcjuNYBFC~hM{5a#voi%wPE^l$yW-de!Y@e4Fn*>dL^BQDS~1hI;<#5$r3zqXprILxk03c>Wx&CAXb;C6@iF_5*1NU0&6Tz!get_4zR4!ZO3QuPKq z7wFrIFmWW02GdpNUAZr0Jr36Q{-MLAfIbPvA*19;A-^15e?Hht_74C6002ovPDHLk FV1gMX`7Qte literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/small_green_tick.png b/app/src/main/res/drawable-hdpi/small_green_tick.png new file mode 100644 index 0000000000000000000000000000000000000000..a0121f8d339fd8de0decafec56290001e750a5a3 GIT binary patch literal 910 zcmV;919AL`P)hP@~d;DIor=Nmc|REFjcYsbGgrtrP-H zRe{7rGPFyJ6t-rmkQx?9V(wjH%Q1;##|}R!u`fRReSY`e-McW@!2jOwgNzZBFu=eD z6ewQx8gFM6resmXciv1T-z8J90c+I37x#6_kVD+~Ja2ZwA|$McV)Xd!@h5BjO&I$y zHYqV_L;vP>u_~yhkct<=6)(7hgjh0|T!2*}LWClJgMtCL4MV!X3NKT^)D`aOG|(~; z1b;3)pI#PbLi}<6M$1I##n7-D(1vF8!-d zB!rMRoTO+i`XBe3UMG8UL7uM?;r8)^gikp-cZT>&EVkIL8IGzWg#BEh`B&lM;D_0DB9cF zMLUDq7f##vF?y2rH zkCoRvf=#yzG!!S7C*s&lh8RR-d1W6|+rlHFm{qV~tI`m6G1dd()?7A3$c1$uq{NTQt0~lT_dzm k8vh>=3ut-mvi<+a9jQxPm75qObN~PV07*qoM6N<$f)xamxBvhE literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/small_red_cross.png b/app/src/main/res/drawable-hdpi/small_red_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..71bcefd9049320337a55ef57b1b5c485a20bdbb6 GIT binary patch literal 838 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_notification_icon.png b/app/src/main/res/drawable-mdpi/ic_notification_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..91c38caa3aa4e1a75f51b3030aa8e7e25ec80566 GIT binary patch literal 664 zcmV;J0%!e+P)E!osoys)#25PY_*Nr3FiuEL}ilwr*rx zp=D;iuX{2Rh9r;yiYi{!RQK=S^ZxJt{knlWf$iEdHXkpJbIn}(bKCbYtJeWFBv?Ie z6y}I(Ly|-G8s!4K^L-fIEs#SF3v=Ewb4ffX1lW2M;MLJVp4bC;`V#W}BDsa~vAwY5 z{1*4)Aa^CQ?po`gGbb=+UyUVyztDunE(9JfM##*)e4cQ1Ms<*2FSADj*n%aTR2G(8 znLRF}liR0BqZnYTw!?zGL|IHAM>~wtBHMz@n=Y3cpe)9br?xX^@?r{nl*MH74(7Gb zkrjo_TF;$~^GNW41w3G{$#$s}d4@QyYA6+s{!C&mCnWAdNsso&(&QG}>{18v8Dp2P zf2SR)^lXr6$y4|WJ1lVD^hVFTQ2wf#Z;#+P`*o((o08mKAsYr?qCa?AndMdmMX$Am zS*xEUUgX#0;17?;0I+9MfIsi$!rbLXy%X~;n}zdmlIchO214Ngpk z$S%*3Q!Kbg(PWogCL)P17GxZ6*k*Xy_2bqc$R|4MSUqYx@+<)xMDQ$AC=zQ+h)LP6 zh0dpN9axcSZl6*@KIY*lJn5cnSxL{nm*Fd9D}iv>++YD9@OTnLEY0P%Go&I96U zK>P!X1wVnf2dW07_A3y}5@W&C|Kx*3gbddQ;y*Yve+S~zQ2ZT-n!iA7jL(8B92(C8 zu@aIxC8!uSP(sKTsnGC+0Z{lWV^OD!7B{~@@j+}vBgex@JnBv&shdVhGMz@G1qYGT zO(oXwJg9dG1(6I|P=eU0gbXhsGLk`tpTeOw3!eqX(4>YhnI1-SIWhnxaeYF*SVTca zn@UU^$U?I{tf=V0;o=|A!~iQQK*fs?u@Nnb#&5!6K|a0$lGM^Q8jA&i)T|Fwu~axJ dqg63g005x>B9&U0cL4wZ002ovPDHLkV1f&ne=-07 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_notification_warning.png b/app/src/main/res/drawable-mdpi/ic_notification_warning.png new file mode 100755 index 0000000000000000000000000000000000000000..c3993f101f6e9426802dae12e6438ba45d778946 GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9GG!XV7ZFl!D-1!HlL zyA#8@b22Z19F}xPUq=Rpjs4tz5?O(Afu1goAr*{QLmLYZEASkd*&ryPsJuivg}MJh z&IBNQP|_5m?qQ}NJ%RU<-vTewCn=IVrFZWeIjfuEj&s@?Z;d-_t)~Ez7?p zo^EYT{;upS&)ME9kXi5OXW;0dE;DDo^c{EBC%O6&7uGX#N&cOhCcU92#@TLbuZTh1 z6PAh57bdTp`6A-)mMp%Wju{Uo*A{rWY>3>rP}5_%d7)6&lUf%KB j|Eqk%I*#5dvwe)LxkjGMU4fp!z-I7t^>bP0l+XkKx2CC? literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/small_green_tick.png b/app/src/main/res/drawable-mdpi/small_green_tick.png new file mode 100644 index 0000000000000000000000000000000000000000..7ebb055418a43c325a14ac7461628e211465e455 GIT binary patch literal 654 zcmV;90&)F`P)Y6jdEEwGw0|S&@+11%?h3*clm6P+V0+ zVoHV7sX{fK%2H(ri*fFH?<7;pIDg!HOYZL7{q*kLmuG<#?VV@}!an(wDAVcD!IeP_3`mYkk2QYG-7o5oR~6_!f8mT`8Kq z7!}$JPGMjaD2vZ#vY7^#@*eE$J6oebqj3G;{5B9=0!vyyky81oJjS!*X#Q%(L+yZq z86rtVq|{_?5|tMf)SMdTrsm>dV^bnQYe*r6?!4MDzs>6=E`MJ>+$2yWp@fYT;w%|@ z)49R+*X_hTLWn%2d9?DgGG-sm8tBH!25$Y^#C^=9UXZ0HOUPw&_w&{HRV+VUHZX=V zyq}1T9baTX<$1+q$Xb|Qz{>oJ8Sh@~4umq((#_?_hCy(ZG+tALFQXgkdCwJfOe|KI>w)li-^tn+AUM=L&ll zdl**SPE8YXJ~>tW=iW-%#4cd?pt}B}qE>%fuNp8njxjmb(nYs1g7nS3vo~imJT`W7 z*WGrPx+M`_T2eM o(Hi?a`Y|=$*EVHG#et#z0?lCpjyTO2r2qf`07*qoM6N<$f(3vg`2YX_ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/small_red_cross.png b/app/src/main/res/drawable-mdpi/small_red_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..065929ab62a31fb2319fffd94da507a1c2d93e75 GIT binary patch literal 564 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 ?8h$-^#F-!>kO6T0 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

clKazZ>O+ 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 E zSv2D^f>lSd+Of23;+f6_3xRy0q`cv;_sfV|ho83v%m1ONzQeTt-!cj@E^cjzIu?Zwgu!_L<59{+D)6^}&s?(y;M+p%87D;{8 z<*FyfDNg-pwINuLy$3WOQ%bP<)OVW%jGk(+4@&0!5U{i%1zQ2X!?YVolLlANG1rj4V$Wva1ZQE zsnZC2NYmMR52PW#dj)m&Eh^lWn$OFEg8S#Gmg-#>i0B_mYFiw_|3veQS#5nL@4d!k z^6`Cc&7}y$^Cc~YChaUZ3&i?u%@-~M^mE3J%NVa;KM~*?B)yhTH0i!Gtx)i10XQ8(2dEb>TV7oj&ug|2eab~YNrQ-lg59sxrLa|uoD+|P7OVrV*)hYe> zvFy#cwyDgPG?ZNhU~#^GlM7qL@zz*$KTE0?-;CwcrFu-)<)3>Ol>F8{tXt~m$aX!I zl%rNonuckg{QdejTGfa3drW%BoD-$IJU&j}!x+`HQu_qtnq#UM8_bbB8&??m{6kLu zyXX%h#eT2M?aY;RvF6&vDyb(3-#QzsSfYv+M7RR68SPt=`WEDhK;erd9V4|JGjbUu z(~us#`p=g%S?8VBUO)k?vfH<{bKAh-JyU^V&-G5#q(bIez7W1QvkOs@J zp8zUNyy0FP*;@Ey;txMv|60!e)qa(uVFk3f_sm29nd;1huF z7bNs)O9(84Z{4PX_G$2$dpFr9?E=v{TIw-s_u)YN6-jLbfugUJ2|e-!0rH()5LiN% zxN|6d@!*>GA`BOr$$GPNe237oHt~g_u7@=(MNm$Gvpx$1`Z8rj+ecqSMr7p%W9Q|T zFUADz@Py{Ci~!Qk`&%j+J9!Q9W4cf)bM*Frr7U{rzl<}+bhZuYCuk^tpm}03#o`bD zlrydWW*4W7d-Bg@;~Rf^0TUqB04G?q(;9o`UD6xa?TgH1@k^VyHlheKwH$|N;yT90 z0!xsq#g+%iRXc#I%>#Q`I#OzU616=}RvEEc?_XM`AgC{cIiN=3G<})o}g)=l?Rze9nv?^0;3UQ&e)RC zGLm=d>PV?}-Pqg8f?V2Ur-2|BnfuR@a-y0Aa%8#9bJ;}|d4*dbTb?Dw!H_98ZNYqt zY^BYaZ*R4-jkz$30qK|pS#i+0@&xOANkZc)=?JGLW-O4^qELZ!Y9_EI8ZioTqz<-M z>tOTP92;8cC=wctO1{bRd$E*j7f!L{z`S^yk&xN>6=oKC&5@c;(f5;=jkfyCV{c0k ztnXTx@3FGd@DQxS$3C`ArN3dva22q_>MC^I=p`}`v|D>N6X*n?;RuL@f%wzgcChBTf`vZfx&cuk| zq0Q*q2oBo(XnSTINukY-%G|rz26SVBrPsP<0HX9cN%iZi;wpkgLVLAL?_ZIbnAq@f zq<&YIcYdc$C_9URQG4IX(wtyXcFa11HQJpCL!W)Cz5;TEUlszCSI)J-R6d?rISxx& zMFJ*p#>ZpQ>8IK8LHiJ&4KrW49h=6kk`l{HLejBzG7 zCRzkGZH@n7o=EUK`Vn&CetrIG=?zY>vd?|Wp1D|h1B){j1#h+gt0q%7e~$5yHSP3W z$TrNBnV;x`OiC;OYRQj{??>#uZs(g*q#40tjPRazV9i#FN$Yv6BUsE|ZGvU@xZKPh zc7Lo?;}DgF8}0gbz*ozI6D;?IuEKVLB}x9b>>2x6*)FKLf1ddvb3d|ejf@R3^JPi> z>TG-FkW??GPssh>viTZ~>-GA1kA3OdHQLDuRu!mY6b5LEn5W|MH!2b z?PWyktogyD4#A@BkC0-5#e(g<_J5m0NRpG+mA+9Qd^HnCD`BK0jamZNYWf#VZ_!li zAg$ zyrxT9Nh|UKO`qYJiYGZ{L({fgUh^2W>$&bfG`&e0K(G6h<$0u}Jfv$heb~yx^5r#} z9@4a>)x3@Y6Z#@++k+eAjn&V2ntrBfO+g+E9pK^ukPC zp;dZ?{Bp=l=h%I;<==Oicgp*ewIfdAsO=x`vg|Bm?rwFofKvji-#1yG zT2|5~Sg{I>Qo{QYR$?BwOAEX~6 zS3a%j4Gr@ChE_)obt4~`16{V?&_y2oexH{<&`NSD+wM)Dfr<8AmIutu-OQ8T|1Qlu zqnA9;K9?5ME7mLKmM^x(_xrMWmOepT!2fEc@jN&8%%5*1xwN6xom`?`F5?*^BO_nZ z=dbAEe!yJA-1wT3KJ>O$8sBC8e#GkFi&iJ&EOB{Z!paO5#!9bhh2V^i6*(&l*lv?^ z<fgBwRhq7#cCZ*pp$O;2BhX;t(#Srf3EdoIcO6m z&`b39W9;79_ROaT(m8M|EU{v_!|tUIbfZzBT(d0I#dayWmpm`A|9u-f8aPzbyA?CCunQN2K5BVN250^9TOCCYM$0JEAQF*xu>}Zv?pZq?Rd)a zPohrSv7YqzrKYK(KOze-3*=YqRoEsSlP{WLv}Eo}>Lk?bewIC#cBk&?$Bg6Kq<>NV zDJyNuf)lwwpPT6MOyrq1xXM0XARTjSUZ!~+ePB-1)ZmqKznNe1@4_U;3NFu1sVo|jcwTqA>bjL;V4?PGx|0xrgE;|V z{VS4o%6vf5U?AZuHk?UWI9a$v)0%;jbH|FH?}D&l*T!iu8xDd2jaq+k);Fw`Z0fy6 zhi}K)A+KHRY~r2d4K=T8z7YPD7pL3DO4`eJbUxqm3t52>P?z|;tkU~7+O^%bRTleN z>Sb#%Deszr+|Dm+OZR{1 z7Oo2C8FQt(b4UTi3gW)8#P@Jg(Ms`_$ou)y8B-i$OdlidZGL#kaV3!_g!>Zd_}$Sa z^g}1T>js+duB*zMk1_f^`7AOAWyb(==f~1Vw2}n@zcu<2V+R+7zP6RVgI!W5SQ^g# z>~*|I(jpIk*mWh(VIE)s)l2+4o{21YM5^=JtK362F%FS?n98~h-Q)9;%eY=*JTaeA zPUZz<-9FMi==(kfPLu92PS)j-sbl6?#$eHA0-u+dZ&w$MH=ENaXO+uD8E_f7&H7ZY z@dfYBnXt2YV{rtDM80Pu&Qp$StL_a10)apv5C{YUfj}S-2m}IwKp+qZ1OmGq{y#Oy VlzJpAEGGZ}002ovPDHLkV1gM*M{fWC literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_home_news.png b/app/src/main/res/drawable-xhdpi/ic_home_news.png new file mode 100644 index 0000000000000000000000000000000000000000..a3fb468f6573909f9c557467ffca7d273a0fa71e GIT binary patch literal 10124 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 Hu0mjfkqPnk literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/australian_government_stacked_white.png b/app/src/main/res/drawable-xxhdpi/australian_government_stacked_white.png new file mode 100644 index 0000000000000000000000000000000000000000..ca519eb20dfb3e75ba6ba1f5c5d19003d63b3157 GIT binary patch literal 89307 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

qUt0jN@l~PYx<5E*%>Tfuk8r5YBg18onSL*e&oQ z!o31CRmNYH2c8GdPlb_dg4MfxpdwpW2 zeEZ=?_xT}}@f0FUX98eZl5@Du_f;PO*RNFTNcocSekN-_>Cb0>rZ?`l)O?%qX&;Dv zq6FKtI^g*x>NRoyW59x>oYP_M0&q2R%JxT{)==I`R+p7h!iLBI(2M)9IG+)vOhXAa!eHbF%xgeVbS}%ciVKH@b)1uHa7Ss+Bc}5_o5Jh%Cq0H*$e?q z6FOSvO7b;NhfNGYBUB z?k!2`<6A`0a@zSc=i&X>D4EWoYmdB#;azCzdd9sYrxko^JE-LNQBwps(IHhZqT=}Z zMoVm+v}3+MI2RQ+F6ZtMH`#KCuXf=psUhfu@oPcoOuCoQxf5SMy9~%abi)J*Sd`0K z6qkUxw271Nz_5wkUi!?P6WDfI0XjS8VYfsNC+Y)u_U;k5YtfnZkUqxwh7r3eCrHiH z5Op?KS{Poe49K-Uuf1>uZjo>-6l~H!`6yLR{8#tJL3@8KHCh zdN^*|C}&YSRM}iT<#>7ZdK5l;h#3nbSg;!Tn*F+vkkFg{Yqbb!WC-d73cqV5tMQ(+ zw8{J7lsT&N#011Q>i+w!?j%>TPG!38?ER48=tck3(2D_DH$bOf$24uBBJJ{I82wik zai4e*(g)>V_d8f3HmmFobX+rm^q_9pFC(cuRDZ(i*^yN;UGd<7&Qrk&|CtNb4|is6 zTFJ~T69H3whOmkaz&2n2|gj_lSI_0-t8(V-d_WVuFzE0H4|I7Q}$@R|F{52K6q@@j~~ zft&nNR$O1_{(Cs-VTY^6m;l=y2xM|Nu>JE?%h_YVxArtVm&dGC1l^&)7^e`s-qx=g zzhd_1p*QLD`Ko5IZ4qi+A(xNY8}o?NpIl0cwOq!2c+OQq>yGEn863Eg9@C?sIq7w& za2o8uDqm)7^MSmWh0)~ApNrF&h2 zm1%8JGr+V#jf?BAPVc}|Cp{nSKZO<4MNzEYfND6MJMfC!BQ+~a=Uanp7836_xs1Io9jIk-6V*N^4B6U>(QUh;4vGq~C`1qyCK{^no zKO*2qeMKX3AY)N9=B2Id#_5nOl|qOoXK)&1QdEmn-A?(ClW8=Q=a!BHNOz}E3=-qZ z3ZZ61a3#e)(N20A;DIQXz^kyS8nObk`1kHv$rFUGuAJGL^Xez0qEtK#uoG^7-{-x` z-~53s9|Tv^hcIo2`#XpEOvzoqa&I5_oDD|Gmm0FK+jf zZ9Na4g!f#ph%a(JWyG1|)D zFjY^aBveP|+l(Xdsparf-ObgLHHJJh%G_(b221u&;;rdiEUe3F9_cvG*$0 z=^7II3tcd>wqyXcP4C3nOIbqsmtjf@^MbgW?5eKdfIG_dR0~Gicl^A z&!j{dRu`%p^046Vy29e>L$aG!4-d!ArSK;3xP^)re9hiPPUZ#7$+9Vwg&iwZ1`Sxs z#(C)Fi2-xdScbdPrMcLhHUjLInN@h4?WHLsnMt;F+TRYx!z7j_q9U1OH1*1&Ax$~f9^*QZ{g79!+=(lN~m<(kA%TKvb*od z*VgQfQ)KPbc2xnvN}Z)V@BY*k4`qufFs}Z&cnLA~WXK!8dz&^(_hn;b?6&v-n~`}t z=y8#n_3a-^#-xC_tVGO1JCjys>dUur4>`ofh$I;AndZ(&hGR-{${W%Lh>3SPa>_*; z`zNAtA7+2OhumvEreM2k%?2r;eGC3>AXQX;^?fUL>)p~FP-cjeIs+}0U<!kkE{=Fn6(rfgbpOLa^I2LFpT^u=#)060j~-4}z0IE`Wc*SI5u)witmV_h z2u9?mT3;7m!p7aS(Y99uDC_ymv(gNQ8a{W-!^xE}DX!YO_SF3s^{h|)fE9n-2jPDjR1L(|5V4`z3njXuYD zR{D&l^Xj~xsk0=ZH1bu`#XQRBD3hurQSmyFbr2OU2qi2l|08`N(%~6f(aMYC zkmP|cKCs*12e6++aOvH55IbLTFuy-i0LtR2JB@VDg*rS=!^A&3btF`?(v9RXm+w9_ zQPxni*%&+%c*xGsnOeh$ogfE^2?hC8a>z;F<==Gp#8nsiBWo*Y=U`*WYph|2=OoRt zr+1v^(Gks`>f6?PkH`k6Z`k7#b7TRUHm~X|e@Tph-VO#I)q**+h(j84<>y|4q-Fqw z(!UQpV=zN>g%w2(w~2MwGA!@z-*C6 z03Ynq zM(*Dip*NCJ>RvJ67uz3Z5VqL^UP8RiFsTH2&!ejoqD!M;LnyL+=qzJwfGIARCsWCA zFtI1AUt?Tx0fBD(RYf0J+14=qA})Pj{&voSTU*Upz#wD0;20RrU>jKau2(SqZy2AA zqjFnlJoG6@nK+V2k_iAO5YiCXtq8PjG@$r#0>mc#C;w1lUU04rPC>4n_Vwm%-QRZa zdApq8jB*w0usAMQu^)h32B4$7#+aeM-;Qi{hlm0bJX4wyws{AvrZWXC>CO0LYKuyg zT5H32q)?fBw&@vTO^Wj@{Hj!-8)E3TlGQDhi6%>~r+ZO5;P}3%_p5vg-m7 zx9V#k@_ydR^B{8fLlULX5gX6*#$R}SXGx#VToSN2Xp@LVMm+A#9JaEFW2i6kHqH3- z)E|un{XNCpvE_lTiw(l}e@~)eP5Ym-knkd>B#0tdJkx#pcgteTEi#qrsZR?rh+V9G zhXq=|wKW*!+68YSy~=3`m+{caY(cBV?s0o)FTMr#-~25*5p82%{hnA$DjA~1LQ&7M z=0CT4)UG=eXjNnv4JXiVmw6p`o(6x;(hr4jdRStkO6XEnfTk}L2&^ zt8@?ShS7qAR}TEM=CAZ{db6ReXK$x+n+d)8+0YsQMp``EVC&L$#R8LC5#sf=?(*W^ z@a3b8a+KsSYbrG+=!MJtG1@{nIno8ZWU~!^!~RMfZR^S{j@f4d>rD3FK-8?)U079Pee=Y4j4CwFnORt>As&EHZSU>hH9WE_uWgjlB^RJ|wMAkJanyhC5*fPZ9ojfvRO!qaqq*N6Y{H2i&+Qi0 z=2u7vpkxys8Lodm^q)g}x$>X8^z~DE#jgv8uNrz+fsl{3jrRjdE@P6`kp!k^i_zH=oDzDtrVilUVho zrBBMT>VTcSrGq+~F6LN=1&zOV(}0EG+F8P^IZaaQWRdTQD6U*Yus+>zEdDl-iSlO_ z`uGvt*r#7q)iYva3of#0_HAKF)V z*Ln16mnd}cet6;FhZODG$wNX&0P5TwU!Sz~Gv$@?{qXLbd$abQ6IONYI~~u)`Bw2J zmzLkCDZo;oE^~%Ffr&Sgo9GaH+ePc)@d?%No{P(8pYa8*R{Sr$;gffMW4^Eet;P~L zOQ2GBQ9T%cAtdSC9t@y5FDT&ucLRC;e{LY^Hu{m;?w1#=Mt?OT5HMng2&Y`JjA+CXG)0gf}rhsSttM*}B=hY}zG9a;3W_da{^d=qd&XwYY>iA|mu9w=1gVL>UARZNu zi)q{RCM+p5LB1y@igA_Vo1Eftu_6Y?5o1jsU7L~k(BY?;62mJk`ZqObgvLt0g6(w{ z+|;ZJ1zg8QeDhwE559C2$EW7XhX&WqMsynigtcnRAgN!in6;J6vV@283!Yo`m|qZd zNc;UKNW(@AHo;4~H~_4$d$6f3TET7$9k0FG>e@AkjlUIr_c+kHh<8i9AtEvtBs^0E zrg!qFpLN2WQHDQQ=Dl(*qVY)fZys*Y!e&$JEEMmfYrCa}!`ZX!-nYJ&i|!W7y};MS z#C8{1!~8j$IMXpo`v-e@4#}SG-n$iENxi{`d zeecjMY3~dm6_m{gqwNO=32u8 zi_KYXX+>2wA1AeUsSUrwYjDBC=^qb|C9g>u(22I!afpN=;S;cU0qe(X+iN9pe3ds2 zP%qm%*(6geDR|Rf{DjVkhVGKuVrJ=M4;ENZ z#rV6UyKf+noHmD@3*(BDT|cqBzv(!9aYKw(%dVfIU4FVjkBzJ5kt`4O@U*#`QO;%f z$HqtW(K)wDGReA2E`pZer?tm>-75Eh7W+Kq%Cw6Q+v{)fO*?QDyZApYMD+mw zryjZJt*BnJ^j;Bye{7QfCno=ItDxQ=5hC>16F%1mFfd=SCIgS1I{$LJ;+`~}8Q+4u zMM|gign=hXE-~)`K{0otvUlyw>lgK}gN^jLVNP)ODMELkp;crD{Cc6-+45cYmtXvU zh*PF6d~?EYcp4ono42(8K%&xJL$iWcsKk%+)L^6Gzz@6L&^ZKeI+*LKciuT}eIOO+ zIp5?2NxQa5Z;{ljFB`=>1}ht1D5tHm{lO-$q(*?+OhHe#m3+0Wq1$gJk#((6Yx0n^2S-6&bPMoP=~A1NUq&kXYpWj zi-M7Zm=!M>7M=POAA%kOBXK=D>XLYvwZI-eP8z<_JYT#`fNvFxoz}A*o*gXq zhA$8BhY=L7zZd?0Uxk;&e=oVy%z1V+)t55+?QhL$U=j|{=xUECAF-G_38s!)Mto(W zIR|Iyg8{=%M|Zubf$!bw+l=vSxt|>DQu|(21y^$>hNY1Yo_+~GUk>9d(%gP$r4RdOl^2U+?y7l~}`;8QKmi4-;+qBO&u6jP8t zu3VLipSP56n}a05%exP(h&|GP(f+zwA{EQ%&}F-G-|IyD$~r`NR9g|blk7=YKNLSY z3GG?&&#JK#KY^Enalp{{TUApbS9Zhs9dNGPgd#;b=qZ-Vi+n*g4EPOdY+*Y!jF`7#rN!75K5c&a0bbg z2OgR)m7cY+{flX zDe?VH$(TJ6gUy1A&rWt!JUliomQR7xWh#8*x((@TJUv=&?|PI?K2r%T`euNK!B^CY z%5+7T8gkXnD*Z1}6#zjzDiM`U$xb2PhGN2muV$VUw=5T>g#Xwi-@#nueiT%*jz;#i z`SqX~2N2jFL8aW^#5f{MV$Z*|M>HvVk6^g`&Y5F)m0@)e-i8k$C|Euuiq` z@PNZy*Foj!y$sCy%&o(cM(Lu&ih_g2-ak6gAWL*G9;v?tKfKbgf+)G#*p{3(h6{Q` zIQf#!KH$#oe;yUa2C^KCl3e{~JzRI=Ck(zF&G{zhg-afKaXGWxSzDo_{x8>XnQlUPR1{H!&QrAU)mT1UR9P-ZUtWDShKJTZE>iUWSpaw1k>@+2w+V9(qOR<>*HJ_| zjAp*@=~)D-+AnkCKbW$?*Pp+IP+whA<_wJa;@Sg41e0Skw#|kt5gsEK=xTM+u~!)?192H5F1i z`G!auGdA9$OWw+~sYvlUMfFZMF=XpLFT|5w*jBjNAr88xnn*F9PdVr&JP71v&-5@< zdN`|wJ3G55+{007z8_0?I}x3>PHCHn=iVw?w&^Wmx-Ju6M*^>jTOR99rsH14;?;h6 z5yi{q^@{Jl;mC-Pkt+%_O&jB#-(3DG*WeGNtC$G1GN^D1iq$P8I6?F@?eA?S8Qlw- zk2^2B!wZ~T+hpir>{sA&s}=@xM%@Cv4T@Rd1U`}!=k~=^yi;(mC@NIy{zR5-p(+Fx{Rw>y~+Pm z$BHojD=Au{7kNqe`gNZGUeD?Ao@v9XM8*LJYnjJ_z!LVGx)(?EYOJDIOu?iVh+MT~ zYQ_fUt)voI-$T@7!?rE zVH<$M-s32y?fx|!h`mI56r!OyTQuu;jOZMQTxC`7M}df3xLO;A>O4E}=|`DxQoB1X z&r&Pk1iY&C!IoXZ47V%vLnbwom3qa-DHH3h72f>Zn7B1fh{VilF#FZH(ial^`t`0g z41ZDH-B%ueKu|Q_GOAInURT2y0`>NOgtW?XP*))v+H)Sr05nN8lw#j+d0^(7HZu$5 zx~yjg*k4jfQd#68GJkf`{c~wruK#y6{vS90sB&GNtIL+|Lukw{q!C{iE%xKpF=1d# z$)JP;S{F6go0NLKdkcE*uEcxOx2%P~JutC*sqeduK1g(la* zuR~5H4BpXl?TTIecv#KhEor8%s^hx$t^)6nIc>Vmx1qh?b|j%*C#K4ydx-h;Yvcst z`mScV`t5}Nt(xMqBCwjeesLOEH}vbC`KFJ1llW<`<&Foh9XZTjDq>x@X|$7TdEF4% z?t(>mwu)pId3~fdewzlg+RO z-TL(R#vxayDoBn$k`B5i$={IejAwKSSX$RDGa4w`DzoUx5JXeyH(EAPf z1?_@CUT?~F%t32UQj(IBudJ#=PHjz9HuOq?@j3hv4~pGNTiUcC#{{HT6@f)UFwYJ?!7!qBRaf>1 zElhGpzhXagCsg+H>7FY7Q0>=1h3pIL55>3Q`Zbpl5n?lc$dq|3A)O4eiI=|=6RHwB zh8BKe+H18q>V9mf<+l*zm;c+)``@v^LgHUw08!7M8Vn^FleD3R9vV^+?eDZ-1ZI%) z6b)>xcH!j9MreKk;yE)k_t(>xdVcKv7AKAurZa4LfNWoASYytpI1CjrKr?WYCEsk@ z2Rd5b9`w>(Zfw>GN%5mCxJa#VOaBR+5*CjwF~Aa7+#jRPiw+PwguUYCj47;aO|Q|; z6VF%%zk<;NRLm;i$uDZ3wxR~C0?)>rI1L)7t zzbyP(mB4YCm&4$QYW)e#AXV}f63DBLl7=G;d6#M+rhtxvM9}9_v0_G7x_0XZkMI%So1n=uVJ~V$_HQJ!TutpWwU~fN#{~*K z{rMU%`%QpfjG&PLiN~X?N9M!GcZG_$$IohuIKJpO{FwWj7mW5gcPPTzOypkNXcXv~ zI+6BK&H`_BhF;C(r`WaB*=x|FrG~E!MxL*bpfVek&DcqJmwlHO9|7@d$MhaQ(RV0E z0Tm7%TV#sApj*r4EHhV@ql;=PnlDU?>4@N|)Yd77{xJyeBan%d*EW6FCjwCcjZTLgzw5hcM$)3yqtwKn#G6In;Wf0^jP6uk?X(7etXaX(KhZG#9qHEV$DoWFtQn zo|BYC6mcN8-L#bC?v->nx6f)^Wttc4yeV9R)T7!`EUCXy5bHQyBe+GYyNk`P@w(pE z`VnnIH7Z5a1UgNU$iO+QQ^za?x6JOWFivD^f+^J0MyDS5$t_uw-P=N))LlL{Ft61} zeoSFsN9Q|DXOuWH7W@n-;VIL`l}|Nqc+1hC+=HxpX^)I_*$+bM@0sG{c`{8Q%;rQt zZDHBraSLAtw^sIDv(8XcUy-p8G8I2ZD(dvhRnP>v8-|E!4s%v z0K(B?=pTl@I-gyNrhSXt`ra6$X>D76-}WLKc;D}puMvt{k@8sn%YRTtX(cTSWfm?t z2*Nl+A_lzZ&F>pdmHPV-I%EXi`}_Y0SX*NE=O@CxDsY!N_yPizoSPmtb0>U#PWq|q zs>|+pFYS#6%^;_xWo6^2^JAWQ7l#!G*@l&jO|>GXQt1`am1%#8+d{iNSyS12QJ31M6I)~NmQ9oyb9 zgTn!fhtS1~sF{uf$OfKjm->iEJpHxCLtc-qj$`>Uz@HnBA@Z{KUa7LA(o94+1{YqZ zOm~RtZ$@3V{(SxFOdH~YD*Bl106sZPs}Rqkj#HD7;lr*Ix+Wh0njKb~5cEm>%i>b* zOSfT%)xF8CQe&iUzCMr5u@dx?;WqibI6rNmafL6Z-dA@o`erv~rh z)k6acuq_hc2xx;&^A9V-3b_?=1@jNSaL?c`CxvxCN(d^15`O1HVCezVeJ(eeWvYk2gv*jt7$)(gIt@B3IWpQ5ZfQ9<{U zO2a7!)*gM_%a5*FLB1E8Jvcq5*8Et7VxfmcOX&2`=!QNpg?K*E1-ag6$KrKZtx8Uo ziCi=D*FBpaR@e61bN*1u+8j@4lUSLx3akgI&bQ{)083*1;IU#v&0OcFlJH7iB$ ziX!CEpv|>0ihfeb)s{I^r4=M9xp{VMO8@{|t89=R%%BY1%KP5w;JQrf85QdUQ|R)2 z>52;v&paFRkVW1C$s-eMU_u4M`ETwz&Y2K!>Mb6z&}0|QLv!W6(4wGIWdU>z&aCAz zwj2|qj5L#E;P8na^hDp%T}T5_^wM9Ve^oUCX^qb2nUJf`x(R?F`2jPF)GW z**SN5?8L+UEpM*hVZF2dT{?d{$1vFYGLPWA$IlKa@<#m}Un#@?ID4V22obTc?*v;0 z5hkATW%DE1il>PAu%o>(3D7(Wu3GGbm+bcZvLa@~`xR9zWesIYIG;%uv=^NpEuk@i zzM~7G2XkJ*mnGdsJPdY=5Apfh3f5us28cAS+l)v`QBI`3p$ak{Z3IW*5<~_p6kjdN zN^CSX@-0U^NS;Nw8WJSsHst4ykxvZEq~23&##N!){w$7S7uL?|+VbsnbiY4T-=mQJ zIvHL`iUCmI2d?s&tY`WP_n_gKgohDsaN`}4iVjbGS*pr_vf>!Yo&wg^%gz5pI}RBb zmWt`~s|t?LWBejY3bl-m*f+Lb9)yi!|H?%i8V7X=Wj6Z(Hkt1-U->srvr=QuIgx-F zl`!B;$W=>XM}YO~S+8#|LDjP;9q^bcJ_YPD@|U*>hD{0$AKLu1LzucP|69Nrr;B;k zE){=5>dCIVYR*W8O7LyJ_|ZRd3-UZ;#kRe1WB8v z{*%0Khesj@e+pRBT=&Y--y~Tb#PV#u?wB5%&kX3sKfb?>6WsGU@gKQME&vO+wlYYY zyo|-cH4dYiS6-vUSD9%QxM=70di4iq9sBs=z4Y^_Wfzndv7Di{5d6BFZy{!=MM62PDb$e~COQ-_$mG!HyhT#hDBv7el=~`8_|=N@Sl7w* z^pY`pHtZ=@(eg)O6fdULb1bcDXRU3g+7WO4d;5ZK|RS zosTI;4u~wi7A8@A>RmR@m8_{0DRZsrpM%YKvupr6E(b5etvP->KlzRmyv_VQmNfo& z6bzilmJ@|!x9_-`yXp76RZH?{$q(+7w@KuKSj)MrNW#o8>%V85I7G{=JYp_ZRqnpd zpZY{yX33f&K%{7=aOd+Ui=AE|!eb7G=teK#{`%VP23N*E0q%AP-)f^q5gox_rKF?Z zd8Y{27x>?o$%BA6?iz7MB{d#FYGh+yD#90RJk~Y&dNbk0L*VL} zF9&j`=lasBA*!%>8ZO3K|+6{iZU0_tix`*4c4L}mYKZ~Mbitv!@*b4 zt%EFtskU<}VPz+BUW4_v$4Z7k%B2g>qxv`RdR!r5I?nU9!7v_O+*`Yh?rR;OMvGfiIDF@AUL#g~#(#c6Zb;JNYnPubCL z7GD4HnzVgkm|o_Tj5+h*vGsq)%)0uCLwuC8HUEcNX7g{Tk|ROet3P602}A3lF0O>t ztNm4Zo|I#%+4}U`q(bR9ALW{`G}D7sN8l}&>QNHK4}xR&x}|rcC+hm)y2xl>R)>re zG)nR_u1N%HFL@%tnSEI{4GYtxSf8ZW zX+6%ol^F^!`HW1g+81PlDqs?-;y_Rs1Kt0Y;+;)5lC5E_N?d-p^AT;PLg^P z@dlXfTX#O2rk&%^HN96yDq6mx`r-SPs{B1YFOP}mnZC4)g!$n0zdf)ID&R>2_n7$# z{O={dzT=WGU!8YD{g_)Wd}#~KtBo~H3T3o^m9_RSHHHhmNKtzEPBKWczY0iGZwkIv z#w$rb>SINq)pjX}EF_fxn)My1ig-$ew?d&z4&e9OFfSirF?8YEajF7{*QTx;h`q zzEiA-j^_Fc8M=C&If^evc>yIno9lb9zy?&eD0{w!^`y7{Yrp}|?)1de=e>O3R0L%7^<-UWkNd0E z_9#?*evI*GEKc#-1$_MxJwIz@3$GBogtsUyqp?r_Ea6!pWP1#5um*y%><9V(XeZDm zNNl8RnT@?q=ZVn56dQ4X0(Me z*IBcQkKTMsB#)B8buSKRhoD}+;)XL~K3rEJv)$Bbzi&V!*OE%VL@BHmasAGLK0@{C zT=fdq$+7Lc&IM9u;9|7f2W_(3Tpb@OaBp((^wp=V&73_e*nyWfE_y(-j7jqEelXb- z>H9+NsTEO6tjbqb+&EZR(xP}mcQ$MvZZ>ZV9d26Qd#MaHC+S~uNkR2$FFSfPL{!JQ zX|C90en>M_dBymF0Q^MfedHLqcPZ;?o5~24{a-|VWmuHo7p;VZB8>vl-7O76hagBu zOQ#Ab-9t%t4=pJ_N~ENvn_=i4I)$MJn1Q*Y|9hYNl`p_~&)Ko|UTZluUUclni2P?S z9N3f{Sox~T&rn8$^!#X(YTy0NTq479Sq0E^(^9^mIbId&^64BZw$$T9i50@m`_IQE zfy+%B7uO8*u6opt>d$>U)KyhzKRx1>g5{5=~5xUqJDwL%Jlf#jt`nb z=AF?%Cb?k{^QGe9qy8~|?)t(KxO?6K=!s+;r50Pee;@4w zbhZ8s36lGRUP_-N7of`uyLleieNJPYCnuSh@wMeEYKXCbUFnNLQuj^UAPjtq!Y?J3mO-i^Um95KFyNDS7d6N(zd+SA6jPKXym#GHA>tnUNYXj~b+l$7y zXZ=%m3LWVYvmY44bGHYPaIld~WUG^UGvb~#{B22_4jiNH_j3IJY_P3u;6p_AZw8j-mNj%|_E_DVOVdfvCOS+-Cmah1D|WuAgEL@29o2&d+B}ZCH>%?H%DWbRQdf zL2T9jLK1pw**nSw@f62Yji6iS63Bx6Rqmfx6aO{xH##*VJRCc@4hyoF@!d)&p0n^Q zd=!2)@V9&U=iR_U4yj(V1|8gd8C4=^8ecNfC~OHXyip!ak=DfZ1J$pCKiA9;4%}IZ zUEJx7zC3wa?X_-Od@rUIXQ<;ibtWeIG*obwQJu|GkDgRDD~Yz|c41reLhU7lx{zY= z!{G9WVo4(V!Ra-+h5RV^f+3_o=zX$JiMp@J2XLZf@u@E$@w>Rv!5x+BizNm;8kQb4 zM~nUA0sb9~pUUh^DX@53F`VYf@ z1T^=4n3ku3pw?h;9sa-az0V(^2@;sSkCmQ;)7MvB52@;q0?DPr~Bx3-H|VU~$|BrIsoD7F{>) zHusvy1LGKMt!D2=mH>c>9I5**0W8M1__iORi~VcXz>zKHs6<_AbDjgOXtnV@@W1gf zy4roiDPoTB=9D<02r&d~un@^0szHAHW}Ai&Ri{%~Jm)0y?G5o!BBH*wSu)@X<0!eS zuazC^{f?)A1*H^v3m%o`ThWkaht2E6(>S5uEpCR_<2f?w(TV`l{E$SeM(EU@6pM2I zHy4D)6`w}@ttus$oIP&Hen1#QY_ODchj7}4fwiKY4G=~u+lziN%%X^2*J`B6t)}$5 zSaNuBNoeZT>!((|Yzg6{5s#u7a`wHAG6ZD7%W~vdIiIe-=~}ohmSaYR9C*0iJy2voA$sizwe^y@ zhpPwKfYXaJjI8Wp&TQW{TS*oUn^pySF`b9CL<#iP<+z&C2zpu(O=VKse;5D@7XWK} zh}>F!Is>Q0JsrTxezLZ>6SU@y*t1ag{7iW9-uKI+t#J73Abh6Ic+=}Bgu!%|nKD8ZV2aCOEje(Oz&=s3@<%&9tSH#gF*>g5!Mt!5th z9N~adk!m{>Ek#s7MAinXmB+^VClD*q?t_|(mV;M&1FAlG}`H! z=5GhyeFlD6`ysG&W1%i6B}kca=xy`%^}a;*6kJzwwH;+0QF3H=$)#Ml3Czc}&NwSn zbDb)J7>;Z~#)yg}91S#%b~NN^r-nG83D^`$2{~GQjYYERsf%1&w>*V-UMBo$nx12T zX;CNP5?0RCx1#gG1{_6x!=H3D>zBH_k-?mR&0!4+#v}y4cHE%7c2q?tg$OQt^&HbH zd4KI@NtiBL7)JhIeJ>?YYniHa{tPRW_pA;{?NlGo2Owiq*D>J0wUT|*g0Y|AK6W|c#bjZVoSpG_u=&3SBTb@7vGWO0kU?Aw2_k-#gZ;~~2Rmq&bQ zqvhv~{2>Ki?!GNA_p&&gpH%gi+<|0aDcO$r1~mhROX$b>T-w+#K%fBuph zjRSI%xFvmHu2VL7fbo(^ydxwB+Lw%=28F(b?|!ZOecK-E-XT4@91g~V?ZB$f%vUm_ z9?W-~Up8iolW#QlAF^cFta-WB=I+kwYpOEMO>oz^T7%%qFVS+_YfCDoz!g+r4*;-o zb1#T8EFCjT%8r%CUas~^u$TQa1H&3i?EK8`bocZPjtL)0gGYiIynKyP@|;sL0M8{dx0if}>= z8m*Rh>QA3l9Gw`zx^S89^vmPUz?>j&8u>oSUcqaZ7>iiCvMNmGHmR^A{-+>rie>D6 znukR=0DA$avJ^UH2AW->+p!jZn|67@m$~Eu|LEn*>CUGfG=B$)|4n|u0;IDmG`D%h zETkK-w!M?F*>a#KD3GV=dvovcaWEL~4cm3vz~1gJgRb-kg*&s|&`I}<7MI=F8w0?U zL%GR#aCUR_?bF_oHoY?c{EukE)TaLcIdP#4HkDODY=sgfg75BT(!dpPQD`=clV16K zP{T34t3_#PZ@>g-W5*yzEE?lLba1&SuCRY$OZM`mdpw$1aVWunBHwu>~r$@-N`YiaSKr1^J7wLQA9qA_C3#)WO0nM{nld?;}wYW>1BBGA? zXOKehX}_El``~`tJ#eYl-@ka?Jp?szQGNXzt8Jvb$IEc3M!Rb zhxFhwn7Yp=pa6{lKK|!WyrKh2=1J?VW*Yz1pgm>80*xVHj>kR@EzGG-(}f>BcYfW) zT`Rx5m&q3H#VwiCz|b4Y(kAp?G9yr85IYN!@LFm!VYsr|zG2%eXbAsh(6Y5~F%Bo9 z6>t5?#AL7yN$ra9`^7Rbqr8twu(yj@=_D_!=bS3|7OO8@t`bURl7~}71lye1Y?xG( z_FhpXG54eFT9y-FU@arl%hJWOPPUKj(xp5d{A{@)$uq!_4^S+b#G-aiw`5Af9q+d# zKbxq@NYv)J8buP0|1PKN#B*BtJX!P>tYC}OsnXxuMa^@kw(l$CgY|DWqb}L4E;j$5ZgapVvGUy0hdK@Fe3GJsA(6+k>3uqKum+aS(F=-9;6I zm{P6aAXTGUv{`{`9HF2XzD;F)f${EjXRrtA#qDjme~xT!!m|U!3)773uE`@+p@e~> z<__L>SvGD(Hyvru^8Ltl(@871I|VX*IPqJeR);r13BQc-H$Yw1o)cL4s4x7ZG$g4H z9VyUgl90((=m$MsknM1{AvN~r;>?swv1qMhDr&t%f8W|xhz6)JZ#U3C0@&FH;I7!c zK(5G`JER|V2O6rhLo@w@9|y1y8jXK`V_Hqp0xh_ZXE$hG)QtFg#t@Mhbn_l~UF-K= z8gS1y+^H~gDADz2{+qfDlK55p*=>wRmxD<{S@;a?@#9W~S${2P^{FVwl72r=DYRwK z%RxV}OhO~Asl05jZ4B0X(^|d{wNhj=Qms}T`b0!umDJb%bnf}u86>oY4#&qeMpUIl zaA5Q)&qq9n=1T5T=b%`$-{ZW z6_k18zq2x_NXSPV{$9qKVj22kGIbr~^@kWh>=0R%p`x3}G9&OR?@v7|l>s>&iB8NA z^X7+AdZ7vv$S;1~AiS6AVPb7fs=7XQ(HUL}SF}7Q>a=<_j1XZB;nH?ep(|a~{-U@R zf4&BFY_GZ4)gSNpc?{sLjDdq!`O5Bmg3)+k6iBc#FW1|cc0+9`2eR2ZGQ++adsO;O zK+62$-JNsRESrM0rN`>wfUmVCd5!njVXhE!^rKoPKxthiLQPm#xrA$=E`V>&xH_-! z4WdfRo_(4}eUOvlt0p|1e}F9Lm~VdDxOi2e^qt2*NUOsQ_N^3Gy{|?+L)Y`$m-y!) z73bz9dloXHqD}n;u6-X0l5bAn)Pj(YZ((SOa94&HnWk42O+1`)I`YB1BN#jR!;ZD3m5;&yc8E&;#E{t!GZm9b*Ew!^g_;!TeLGokG*Ny%594 z>IrUL6|zcXNIQUn%b=6d&p^=3EDQ&;sP$atOZn%oNurf-Y*1%9HFf<`xnk!t2a$=& z8t?dEihFTpYJ(4zZq7r`QPCdbT3{lbgqNU(cWh2;KQ>{>Q&DH5vdT&ofpw519kC^bwkZ}qcI%Sn|%ETkU@4QFP&%&{4HEA*KskO-(ff1 z$_X>QFGupl{2XvUUzuu}FifjCHc)-S^U5^`xi-Z%j^DpPP_4@F8S~#mxqKx5XhYR3 z2+s^jweYKsDihT|xqkhJctK4udA(CS5I)n8?Cu)HrXC5fTFgKc@FKKDmP0_J9a=oG zKg^P&(09>Wsjmk+29dVQUFat2IlQA)8;OE7Np@j+Z3^M~%`86(Idek=RL)Lx6JHpX zY@O?~lkWHOjmylw!secGi1K1WOKnaaxa-}1Dmiv}3G}m8p>_S@)RaZXTDx^y zp_d#-clMA(CRtG0ouvL;>GWh1bO3j~3|d%+%KX_2s-FF(aeIQer$L5VS|_n_e|SDd zoMNY3y-A0PMfhWL4NSS-1;XGL5B0zY#hhqwe@?yJdB0mGezXdS#Sg;IyxG18%LwyB zXJpnMaSPZ!;(PkQwq|9Zd&aG=cwNC^f!%c^5a&LiZk&L(N}&IeggVv1crGjVF!@)> z0kO^J$;0nv=hYB|)FHfWxge(%d{I{?>wQp%d_EPd&Ma)wfV+!L{}t(j1oH9>x;{i1eQCn9s^q^ki*xT`s26O(?Zcofcd!9MlH zOR{s~Cqt;$l!c=pX!NgssL}b~Hqpp0i8JA+aQzoW%H#ZUHM5_O4Q;6@3#S==tqea; z!+wbk4=F>bGcBI zU*eG!yxn_FhqEh#k1^!Du`umA5HHn28^w)}`=QfA34Oi*PR94imo|nt5s#@g_XjkTL)ScmiW&zEP z4~gQB*Bgm?Eh`0qCBI-LfXs6{wXo9f#^i^|#J7K2;Ng zkgg;j-WQ@0sU{a6KFtt8z%2-*k9gzGMqQm?1Fo6^5qV_Kc&N-;ez{5Yt6x*#u+vEK z{?346)lSkdEHVXqTV>UVl!lEKkmZ7B^TSseL?hlv~9ZsizX7*qdyXmcUJ=vw8scN|Mb0Lkn#ICSl--A*9+1DvM6Ig6-Uzj`N*nzXW2l-uKU7S z34ITXH8A47b(se~zxvR&Mx~304?1Z`>>ddp{a~H@pdegGaOp;4xXm(h(Luj`5%OI5 z+kaLy@Y@C75I`{{8z^`clkANL+i2W{JiUcu!>N1AEaKG2qe)aQcI!B~K$D6sTXEMf zb;2wv+KymyFYbQNNM_H`BE4@0k{Cb&QXF$__|jglZA=Ss z?(8AOMOVHme|HE-6`2@zxkVhvh(W~ETL<~#4vGQk#>I?U4Eloip`Tl!dFyQ$p^uAj zHt|&KD|2jyH?pA&BL;|XYC8T%9|l2sVtb;}Bf66>^b%>YoFNQf&w|m8Njh$_S;6rx z4@`)2A@^1$f3z@U$utt|uD~PzM{#|1Z_mo@)$x?sEw0?8mDbmac??wko*t$79p$bT zNu;RB@sBas>kQnDyQn?x7I1Cq^D!haYM9oMOFGuGToXJ}5;U}|j>w7Y)j1+yIYV`EEvqnVY?c10@L3A)9PtnfCJ zOK3r59E&+D1$I$O=ETCqNX&*K>sp6OAW=83Q{9h|dy|q59dQd#AZXTJ18og-!=cA_ z*v3T5EnSpMNhEQ?%=-|CRyfEs%}YD2Dp~bqxq5Z1fRGnqUt%KTqfEnx=Oqh^+@odI z89x*G-s8qxUznz1B@x< z?RwxJdEh(r;))`W$s(Cg!onU;m25-nkZ&cgB`+ZOH+*rX)%fyys`Rp(#|%BBHaBdQ z#f9nLVyv)z>0`uJ%)+zM8v24gzu+j3oJHM=I}pup9;4vM-VN=d!;>C-HU$+ky|g3`@39Qh`%_>eAV73bb;}$LJdGH zLad+FB1bO0tF>|e=nEcWOAXS^_EhswWf5Q?|S?kSGWx9ny?+92@ z9{7VE(i7ER1w*%@i;nHWf5xvRycV#!*ye%R2>(pO#bjsvI|IgiLkz-;7BT*hQG`LE z$wU+s`deuvzFJ0in`_ja$xGlx%3LTk4MdHJ$@JLzF+L|YF*cFzc%JB^6_1LU1kFop z0vYRv-vmE?6q>3!h&)>-$k8$r%UB zf~)fP)Z_pl&yeb1lmUtdr{d)nV|y$h`ZT?3#O9!d;@6|0swZzKuwTVF4;L1;BsFyP zp);|t--avFuR-I5pE|HwBQVllLHC-f^M#WC#nEXP6X`t6gl$LyICiIKqefl7>!ZB& z8H8rB?f5FbY`p?xD`s)*vM-T2$%^n>nq*Sge;xS~6iFY)DO7Xu0RG(F{enk$XAG>- zuEZTGdcx=`b$s{TuKstX@i9=vzY_w!4@ct?a{mf<>}>H-vYBf5k7_0@hD%EZ2GRcn z+SE8!dGHjJ@Yhf3B^_}3GE16>{cvSc(uMqpFiB*r=js{q9YZj-qmCFkun%0haVzs$3Ld#=%CF;a4Z z9z1)gE3pKJ%GL1|TeOlFEiJ8>tls(z#_+KN7)3a;DxF(Vip5LzU0++|FH zbca~CY8(uY!g*~TALp!@4$tJCfNNwlmY4>1nq;#D9@TYDQ11fqfk`#Wl^5?^w_JdP zcKJY4>j8fCJ+oal4gTu@`ewM`?IAw>(Uj5#G;A&@%Jv@5ccM74+2q8A^~B6IPmuxb zv0~7barQMMx|8(-E%=dp{|%zb&Vq6vDvNkv8x%xmBAq4Ez~A0=RYMg}C(ME7?oU$x z%U*0lA2D>|IPsKtsfn@(f4=ih(Te>}!a&YwYemhV|ARAfNVlP&+CY_;i}6?mvd9YoCgh2-0<~Ae7pMdS?Bfik2OD4@nH0XSa&K0*I0Y?#WT*Ij-8wE~ z<#^*kE`d+RFEMU7jLm2wOr#q)S2tH{DkUVG>UHrjQ~N-|JT?4D-CjATb%wRRC6am% z&^tQap2oI8!{5(9!&#H#<-D+wY~y>wH5??|$N%<$jQgEuLDNdiqgk7vlPHM8=$|I-!5a!(NAAhSkcX(Qg_KQy(%@UST?K zV(Fg7^dqE67T_-V3o|e6#e4qZxJ|Fg<)M3D2R~T4v9$@m0lK-sBMAOGWR)W;&>GC- z(YR*RPh)M(8J=+9A>(*`8kt73`cU}g+O~HSr^hOw~!I+jd2Ff_bK+Skf z?$$v6iyxaN9MG30WXD}+^|E|JYaK-XCCVYhDCoaeBGg~mN?r>XBKuwmFs%kq{BkMJ zEcfB0&*TDs6@F*4M!3Z6aLfgW-FXDQJSxJPwA9}|1CtEJ?}z&^xHcP6lp#c;%@qWO?s=oy3O|)IKkF;Y*`B* zE7;>s^*jISUM8=w$B1c2hwO$yY4UGiAt;xmh>9sY2=U#5XhU{GlWhqrYQ3Tdj>gU{ zDql)APz|D3rkn2o6m?~wV&|NY@a?b2-^zMDZKgZ$ zWc{w<`heEmcMqS4N83L}9b8n|_eC8x%u_Rhrag(*E+6|U4uQ`|TybF-yH5sEz5NU% zUkqN$@FKM( zsiKbY%|y;r7q2hE+#|D-1kik51f!JSw{&mcCmMVBN zfaSYTu}&vJ)JjLtgUv%*)Q(m{leJuivGV|HDzB4Vu#hr5HlLM4*mru(V#;S}ZurDp zYsWgn@rCB1$q_;RtsLZ9r%SAl343$PK=pM>mzwfv3(;fU0KA1V^&}S53_NOV;(%cw%}zrA6sUvtkLj5JV+>-`{{K!*<{WW zwzu})tDnm(P+7B!;~LNK;CggPq%mB|{)`J$z39UF`w&n;7p0R!OZhYo|F~N~y*`>? z{&|CEUgo9n1*Uyk=dQ8Hi}^c=ba1-VD8I&7WcX77v&1r(l@~q7lC0zIwH(7K%RhRX zrIFmBrqR#M&IbW40mjOHvR)~VG;qQ(iG4$dkKq1$t{T~V?5@PI>YCC zoJ>Hk#Q_05T| z+?5MkVbK)Fi-(?SXtsYY*xmX=S-78LFCF~jPJu^Djt%FBS&4@~P$y8-19Yva{Fad| zsqU(fwjeF#yZH-paGw;(mV*J=DHz^)Q*s3knZg%P8zW&-r`5W!9b8zT)U*PB9>~WJ zOq~s(q=Od=v2uq$(qk4D9-dAdlUT!jkZMMR*lR+%EVUpd8(2O53n#Lom)*{5^i!LH z7C>;pmeT`T3=*&5Z`&_tX%uW3`FqfHiz=Ej#iI8?X^2CKSBYGSiJFu|L#PteBq^ke zc92%gYh9e6{zyb}l!~yrLUN+gF0~OuAl7`FXR^8JCMNWpjU9oJ`9u@*vc->0F?l!3lf7DDrAj&p74WtKuq4?u} zhitZz`gu8t*p7HLX9__`zx~%a=P%tmieKyB-272{D`?M8iu+AQ&KPe!=vGtQ@PU`R zicov3zI&4MQ7AHT$&p4RB3&k+$Nsw8@eEnM{3nop|Ke&wK$CSBOSms+m^{Sokb{d7 ztm71ogePxuERP#S-0rkk(hc1tbdeG;!(1Zi;pH&zJGd!tB338xmx$>$&8Sr_+{Af` z0!_!Q{tIsrQ$Dw(VbHY{jY_B=FP$UHH^e9+9loDOgwSIp`(#h-t3_C3B`6+9M*TEJ zejkgklF_e?vH-rX>m)eD^6UNs-6-i*SEJ^ypne$c z1!nS-v!`{)+Ubz%Fh?Vyaozp*c-AFjOl($k4>JV_7Ze?n+t^Y5DeNE>c74ZJCs{|g z^SV;FaM~R7HoZ*Ita+`V!&>f%UO5{U6O(b-XKSOiDRI}|CbTDPrUHkWr?%*kyPl{QBZcG|;;k{xS~pL2S<-8g2ER^3h!{8vGfE_+?nav(&pF z13s!*>)P=q+6u<8Meak29rx)PGC0nGlXOh^yxtcrSiF^Tqfx*ysvx9|5 zWB=YWxx2V%^4$a>8(X?lT3NbLX^gUz*w<2=I4NIPj~Bu{y>A@Ggv1c6MFf8Vl7Eqt z;3;bzru;i00^)dLAL5i7e7PY{4T7lf7e%li^dr_X2a6-Pp-~?K8@8ekwbp}1P$4Z7 zZmv(m8*&Rq3HG-PgbAmD<%qeg*8Bi3hNbU6XU=oR<2aYpUQ-;Wx=UVJi8hTbGarav z^_%aM(B&x9AIiWa$Ynu02!SMf1Qv6BB2R>{@XnKZ{%L(>n)3& z5pWw+QHsz|-HonFBAZ;_(f63rbe` zSh6r&4WZki2h!t^zhw>HzY^RkWNb|Bp|*}EPnir;9>4BFbadi?h8RNZLR_k5L+?6+ z1tF|cO~C)jSL__T&?-TqwY`|-ve4Z8IGoKSDriH4QHlT59d_;Td*(^RqhV>2CrlVt zIA7n(XwI7QI`|FhYv@`{ASgzact~ODz$Tq8t%*b8U`Hi}lHstrrFv~ehWuk_F^Mjv zIml#~u|sI<4CZ|+{O20cy`3zzvdg$)4}Dr(j1$hC`^<^Sc?o0cPJ%vY#4@Wp7kQx2{QHsTcSqza7NVmk%ER_dog( zp>Pc-dR@8USp^zv`QW+v`*_Vl`o$RTePjmq8??7nQ+HqY_dllyi~%wm1@}X%`9Ad3 z`yGn*enC&m$cbqqr^YoIsu=%c2)1OhWJn`1(nR6k&zf3F76oS4S*$d%;=nyqpdfH=qTu zy<$ibv&4>s0Xq}HPpM1xk8>t-qvqtur#V)8@%R@>Y)?1mSFkHY zW=Xe`R^#{@+rK;rxh7&hMvp!}33Lr_KMAEJlci*kFgT)(Gpe@J>uXdruMJSx9^$tT zb+^JZG;zj^gp!zG5r*P^=ErkW_T9v$EPZG2v1L29q5BXi>RkBeYUB+wu)HaGal5TZ zk>Gpol&|@~T*Vrna&T%_Y!*uvhX`k!)SbO~4+?GIF87aKfgSOzq{>l@uW?L{*cdOA zqKGbZUmkFBdch`TmiVkIcMuX@_&DTyHb;$X?1%-XDaxaLGEiC;xT3xYzz9u?GKRW( zda#vjs!cNPGk!*oSYN_Lr^>?ezuvR1iGsAg$%lOYYWY0mJGMu_fE9hk-8{nksQTKO zxLeKNipP?s^OGm~hIM5!MZOU|&xvB#%XchHxT_ELtmtsF2Sj+>Pq*`zR7`5qpPidL zXliN6Zgh2xYml^_3v!O<1>>2qwkRz>Z2KnJm`|&y|IZCto^Oi_L#p8%{fly&(~m1l|E5^L4y= z7J{UC4ekeG6Cog$0(_YN3eY+rVC`_<>OL4s?&~dTL~DQZ1?`4Cuv*@3K8EajOV=bh zLKEB_*s}8lIeu_6IHS_wM^t)EB-D&PW=n(rg+U6Y&{f!@%@@{tp_}9^DB>UfFM}Ro zVz2X6(pseB)4H>;G>56I=qxP03%Wn#+Z(>bM-_fdX{ev6myleCre+KS*jz_9lQId37m&TE}A z4`^oVwFkd8{3vZ+i8|%A&1Ux#weL5D4x*V&3iy2e+fgJNv}b&Lmu_uPMB!|5)3$37 zO0^^5e35+4kUG=FXv4W^)xoqHR7jr|SNDwW+)FK0CAza2 zCG!}qO_r=uegDF$6&j)V@#z1aSTto%Vu+f-!uaR_9S6zAAg?N{rA>n(rbL+&ld9** zIJVNfMY+HJeADIQkgN`wJgJO?c_TJ`0PM;z#f^Q1@d=}c@r!1YV^xN-?cip51tJB~ zh;{xBT04EtCA5Kc_{Bg)MTO^qH)Y(;3F6Tza3&Cs@b*jmJgTr+Lno7A(oX2rK^Ld7 zjj?ENKi8)-B4aili6OBs^>9TBb?$VF50|r*NZ$#^0HFKUg**TjghG1o7tD)mQ)d$S zajK(oc!b0FFM?V}3(lH($+qWj_l}UrXXY_C&`p%Ph0sc3x!cbE{{HjISL|soQeFF} z7u<;@ufON$(`xNa7hH1Rw-0LMKZ}0~Gb13#CRvj)X*+)}++^r)EJ*QKZ}5KZ7PdVo zU)j47%os_6$lZZ!EplZ>UBv0F4NUpoJ3=M~@5Pod!*p;67LIW*V!i#c>D#?EC)Z%v zxiWTmfBxnn(SP7?FV3#uRz~UQ3ks;>TPC#UV0UeCP6LIt2^%vjLm5L#+GtTVf0V+C zf}^~?!i_?je0w@I=7WWkrw6Bc&((c0;hubO;+;b}ajt{EZxE9k{&I|yo}KlMuU7tV z-^Di(3~sC;k#+x3mU+bZCp@l_92R$gNK1vegpPFu~aR3xxPZ|1{%3j zH$3r?LPgx`!3`z?_M_DB8nmvUtQGA#2(mL>$8=SI{ zQsxn30>jWyCPqjC4h9qTfhe1TS_=475)tvFQPZ}IUmeB&CY%fVMc;a@aROnucE1Z4 z#2^J+y27X&cV*Czo@y9#zSTZ!(x)aI)u~L%vYGS9e)=227xnoo~yj0XV$9Qt;ufBp{j?q)tbeXY#m=gQz4f7En)`;W8xd7st!o4xplmMI*M z&njJ0qZa47pr6W)s2V#3_#RK!X!#8sx_68)u4ESV3@y13^QlOh_!xT~kB+G3;-aDh z-dh>t30mGjiZ!cJ#<~?TaI;B0qcvSxcIkmgL{saW(%Xg_4WzVk^X46=YvNe(4ecA; zrF^()f>1apFw&8^HVke5oDu zH#4{YFEf9VLt0@Ln=z>Q*LkWwA^djZSX%}DY3Th1qYp%rtvpnH23vaVlzh2XfHzpL znnO_@I>;PU! zD_}t!AubGaS4RfOJ+L?!9p^Au;M|et0BOn`!sWD_PwbzReD0WvtKvNTgFWl6;i-EP zc`oa{sHuA8X>M-2nz}|C_EGhBf=b05cf7u}tmShbS5+jP^^+2cO))&!xBz6*c>yY!<1a+D%$kHNjn!D?ns29{xLxHbc}YV^Zq<7Pt`4T@@J= zH}CL#54r<37wpa0+i9?3aA6)TNmOfFcyBbf9IEw$=UCAi(+k1*+_2Dg*DmI=(w2weI+pu`b4f6r& z_+fR9B@mE=w_a@^CGTD>LhI(0Pb3#!R2O_3yzmYk=?4ppgK(v)>Syjj?+?*xJx?A9 zOwhxf55l46KTUn+O*>Y0kG~3(YeTeNrQ%HBSiiMA^?7KkCJfU=yRD96z)7)u%TR0) znB&j;0{f%Hdv&gJD1YEr3O7TKz(N~fRr)kpmUc1`7k5a2nkk$IFm%){h5AW<>Ds?; zbloP=Pqa%I_e23BOOaB;E@|(#5&_$`M$K`~J}b{(>7+%bf0f)Pxp4W*C=3Z94Nm@f zfK}saD?<*#;3$*qEpDFU^7ef9FS#W7xazv>Zcf%ax09N6Y7mxI_z3>5k%#;S?ipMw zqBHzrPgQH#UA0R<4;p;}kW$V|C}KYm~8sAj_)6p00kwPwf(`tS?fPRM9d9 zxVV;oJ~jS&wfoCt}kytN~5Hm_tgu#^bn}-uq7DH~DoYoFQ@KDF_QE9l3 zV$ZX>uQ04WLn=W$>+>wK2Gx+D)aceQ&VM3>W*?R_&(nM^e(HAoALjh9`itJ$nu;C4i`K}Ci2H|KzJ(~Z%5pHA)EP&L zOGfq9OO1|**?1(4n30_)(Kq|Duto_*jS0uFh$~lS80<&0LuBUQSF(IC_<=wg)QXe_iocg!22iDpq?V4%VxhK9-a(Z@_GStuMe*GBn)4>oC0gy^VYD#}8TqW8kVI zVo=ru!*B%T_lvI&Og#Jq_~G1Rv}Fzgk1eK4Yw&Yu$p;LnDV!)v)I&CmkB+z7%5ORZ zs8aAP)_u^FL;P;5_8Aqy1S>i^t*zFvMa)!Hz(u~*62);$osRwMOg5z@WlCxg8M@>6 zJ^2rJG5V8aq^KW6`&n)n=L4Kns`va^1OeOTr-$T=!>`duCtXz8BW zYQK}1yauUwfVJHUzk2mf&@Vc9CUD}ab+}q+2cOD`on(gmr|7y`U^oCLjyjt;YiRnu z+*v%O`~hKmhuSh=4`^1sXcKP&Z zs-B^6h9>3sN<7B+(f8|mEqYZmmR8asQV-WJu{m&x8uBU${p5@PbBPd0LBvq&BmYeETa2{k*rSG z_g_#Xqi?<4@#9@_))$O}+x-5wDz$ARJ1KZe&0d1p1siUaK|eP!*`+NvX;jsE;|0zW(A?{|*>ii?DDw_~18u z%bFj;r;puX#~#$c*i zJlxnBI((o2Ljt;4cvbpw43QV69iN04rhKYC1?>8vMT2OrzwMQ^8kF5ptj2kr0@zfo_-wBW?FP15 zXH>=h4n%pr{F~WhvJ*$2Mlc4;MN&ovJG?jFDS&+V?HG6aZC`J8ucCr;EMtxZ|MsYZ zkoD0@c0#m1+y!3B@MSgTk_yLmBvm>ax@UQZltm$DHW8#i*Ss@Mekg3G>)fq66F2r6 z6ZG!AB}gz-K3ffrR<4XU8p7lD}-v%W#&SwJ?iCw&hT%7Kou4EmKEhS9+m850uV zqYWuMpD14^F-y|UZ4@96a6k<*ub9ZG((7Fn(a28H?_BMAf#ueq6XUzyVyS|MOAuB! zj(7wm&#H-^5bs_metjL}ib@rNYaGV@%W7Io|2v}Nr}pPn25 zqBj|SGmaT&&ZDEaxTWaCrCX{Y(S<-B-t@gW`vV3soOmDYq-Q)AY}qQj*(VJT$eHy8 zd{6945D$kQUOlMR+YHlJ|FQto(>p2DTXcPLWa-6`(wfl?eA z+(O8c{_gwC^B&He8D=uW9|_reuPI$Fi{^k-x9G$N|8^!SFeneveT2%V=`slGS0iIMDivLP7-upsNHAOv4JyCGd2Ru9q9J5bj<$Hs#!%M@W`*_DCnDO+m*-d9g zEi5>56=0{~8<#;q%ML~|8}A#=+gY67ICIGc)^zn( zqt&Qs%zUKDde&@nMuiliTp7xQeL!2`_e+Y^0>4gU z8&<&_#7id~hGqWCtc=eGuiKdUn4g`#kCSM2nTnw!GwBdX`V&9k)V-ydDbB*@ZqV#W!6_L$k*+Yg_04)xrv0{f8hl0eFNBdL-GePMG!D}up+T!#K zHn$hs#)G>9yN({fugsDfUvRMHNA6&8sOS5C0)f#H+m~2BHYnDL4;|;lmco=NmIJBe z4Z@o+wRbF;Sagu8#THvOtkO=2zegbpjl%O5FnSotUOwmbSzRl6QpWQ`nLnzFp~5Ol z9lKj=#>75#;+H{7m2@#G##r)dmx#A_*_@|7dJit&Xdv$0d+h$L^$szlb44J-iGgI z1uAqY-{$EEbg%UVRpU-8A%>5Jr=fFt(#F5CM}d@L199<=q3$MGJK+A|a#2dVSp>pS z_Ip{!A>DT9LV$P4}1I0ztGiPYsTF8aNVX9Zw$v&BHVwISW&i8uNBw_*Ah3F;yJ370Qon(i7`nS;Mj0q;!O64C{UCkP-G^&f=uRva^}@t2mG|wmzUl$ciZBx$B?w2)6UC z|GV?(bk{hq*z_`wPy+^EKo}a_i-3TDH>_KRngNnIC^2Q{qr{Z@W6>BX@Y~%ZQBh9P_;h_vwEtF|H3?7OX7JlN@ zE0(d`ngQRlx@dM46%~C1H@J2l*{qMYig$)|9BgN9yn%M34i-t&EoWb^Uu%n`H{pg_ zM(oQyRma}_&IH%5*4%5Uj+&wWn<+q4NB!^qE$j)Y7g^}5?C}uBlupw;zWh=Z`w0}( zsG0)uTC7E9V|?sd*c_t%ZTQ3^v^Vs+J=yc3$oXS_?e~F7_cx7EVO~Rz^BYWK5EycE z(=&_~G=+WX?J|^Dc_DNTu+3`QPuoGh{$5`&kib+I>zBvVG6)sn8=s`vwkX$~NTj6KY~bHTqCuTQK-$Xn5<`B%~{&Dy}n(k9a@$ z6}iqLs07w&Vpf~rH?F9YNBGT&7f%buX+* zzRcl$JU#F4Oy(*S84Tm1?>=$<8Z$D>(i{{HoZ7^4eIKL$96qfs+As=|2Co6R)(3|j zYC;ZurW(EV{`)lI|5@!c1Xzpk5t^wtz_lCLJKjQB&_J0T<%tz3nGmH~&taGAUY8-4 zH~6s60DUPQ@e}k9YWrqV=6^8Mu*^d%XXr-5_;V!_hzyB8Tgu>=P z&qW|>=uy;07Hzj=tkVl?=~$K#%e z8J*{(&hi)P^P)`pb+l(Xa_{rW1w{)i_E2+|{!iA+R0Kd2Q{T%p9SAIh8z9=RV3)wj zdpnJSfx)0R5#zr0@9%b9pjq1b_lnm)bjgANvm76%aZ&iUUhwhA|HJ!9LwMVTju2j{ zO}G9p>HPN@|L^7ht|iFhGXHO1rx41@%M~YQX=!P-1>{Pf6}xxr{_S~x>cBq)7c5Z= z=CVju#u(C^pyt8g5~8i#88?;r_xqFGNCzn+83A)ILvva*M8}b>O!g$@oPcTO44Pzb zAqGh1eP@}4GqP0C`ms)uUq_|eNiZjNPBQZ+yI(?05*F;+Ass-6M4*GNNXX#7Lsm~$ zPs~SE#oiX7hA3m}Bl7QEr*sVRiOl7Y>0gr{`4yjY+h{0oJRM%3EhlsEBo0M?HWqJ>w)frvSm~K%kOJ+awRd zRi>4KPfm^lMT-op){;jVaKAD=E8n3;a`8X(p?vtS{?Kk_3XP`jqJhYlj~l+uhr(h$hyU40N0ob_7AcI(CZJ&f4hcHHjfbBiOsn6=> zOr77XFv(LGU?t`@9T&H3+e^t+mfePG5w{&A;XiX4d$-@NlGW&9Rf3lp!pw_xmH~>`iKCul+hX zD{)F1*#_B2&x;u+aQ&>fnVMT*Ef(uhSMc$nYvLxg%qimFD(K5W&#n>lMRgL~{{XHm zXmB*RQ=T+PxeMOOVdtGQY2FC=j{<`J23szCF13Zo-_+CqB*#OABZ#A|WU4Z8ri+{EH1B+|lrlEUnh)I*vZhI;JYPO(r&AvLE1gYv zf2e|tp|Irki1X5ERS?0c=WT?AY)PnO0VA}4Ol}ybV}Po^4o=#aPMKtT`ojykI`b~! zCpF_{>ItVC9FH`DLR{AA7+kMm1DLg!*KIvUt0#Z>7=HNo%}zp34Cv)wa}h+2T6{>w-3;|8ZF&(Kx^WPai!TACWT43OX`Pn4IH%_ylNFVucN0NL%E z-ifZZRJ|#1fW>8 zujJ}~^FlTpuD*%J`X~MLAT=BLvpiJf$V9~Hk)O?#Y!){TLVYZ(yh&4;HhW8Wa_2Nr zD(ck6b4Gh?LA6MS=-FgL@YL$udF#Jp&P8%?_QQ~)=eqZDyi)s*I6+1?_u=Uo6O}It zIRGvJG`OI0s~b)}noQfuo_~*jJ*r1z>LPm5>qW;TAzTbpO$~K5RTT9^G7-6*uY81H z&rBRXD(Oo$L>LR3S!bGGxPo0z6TvfUgI>C`Il8hV`pL?dmr~e z&1L()m`b@CX%43u_ZPe=wrP1$7$ma1>Ib3?vkbFp)^RlUYeh6>(>gJnk{htaYTC(I zu8xCH;bSMfh6n48Ea7K%x^K!`#Y_%;d@gO^RxJ5;<<>f9p*DE~f^^OQ)%3GWw&FCo zc$T)dFdqC!=sUBnos^^_Luf*WiA@&VQ|Q49f?0G+dw=LKAACsUgMl?uj2-2>OdGo2 z4RLy34;h~1Db+?N*%)&zKJR`mK9K@n;Z8o0_omjaTZPeM>y{7s2F6>d-G~|*$JB6I z9O*j3Q329Cfs)PLaIe)?YTGc_!@os8#+di#0!Uh9t&mM@bfu8uSap9sQ#x{ew(Y43Y(5eR< zS*Cz$PMq#(OvDkgt@XZxjmU`XE_e_`WJpuCI?%5Y7!hiN=IKY zIWiB5^=CXNg)&9!QL@3Vob32OzH=5?G)`s{uh#A`HEtTzC|DgGn?)yf0Yzrt?V7sB z#L-Vbrs2rx;D$OODJeLUCovxBbNqK*x)usd5%|hg!~eNEF*%ky`)n^eEW<1%?>x&u*}+hWgo2f8z{bqX9Be#b9KPPBI&SU-<)t04aK zz)xO1>J%doLYz#|;tL`Bn*{ThJ8`dudy@jUdOe`{O$NW;hfmM4-saM_-cM15l{p!~ zPTU+s7rtV+whe?FQBSNUi%6Kf#^)-$^>Y`;F%q}(UK5TxSAol2A2;U-gH|f^L89o& zXVanxTAmAJ>>e66>!!Xx4p3D98eV%$q6FyBt4n!R@A-p(yn73lJX!dzlaawPC83w# zrA`eV`9kX1nD#v)!vgDdFB&l10Ug!8J7}qZGCy z3G43|4XXxnP_@(m^9H90tR09ur^=$%4nG#S*>5MSLqI7=2|TBl>J~Uh&b1riZGJVH zKKfR(Yh^PR-;_l8|{W=>*BY4-!l5$uv}4 zRGaQYoz85_4c)&wcqwO*rB2I}hCes-S4j@PP~HIn$6i628tbde^ueas6JHd?V78jRW;GWbeIOJ^o#=P?n68OMge-O67+{db zJ8gMS_6Q!6NB9G_i2izDlE1#faj`_cE`rsZzn=oGeh)D_JBDK>1|Fd%c~t$jWS`Jc z>}t%kz|1hlSU~)<@PjD3C;-}25Mbg4$Ty2vg#aMNoDHwLPr6`;V4Dz;s^Elxskyjj zu%;u|S$AM3Oh%`*f27fU&Uod*!xIO8MN^e_ZHtipt_G20>Li9!Z)d4hzo(F$uDO4< ztN>2+P5j1iC|M}s<3Vu9AxhBrMt^(Idy$d&o1BXcdq35mrP%8U42JJfT1*{!v7fhS z3K_b|Z~TSk7)%+SwfaU$etG$?Cd|$nSQlo-$gWGFAdQ=_+tmJ;EwG3v%I2-yW?VvK z-7a|jqc3660rVrhZ&=5>F^^vL6{pj-LI|!scp4F$lrauL?occFlRNU@mGRgPu0{=`Rj!bzX)&96K)McOAk< z6-1o}9mXN}31lO);>LZ)B^}{CvHZC)O2z#uM|Eu#<^TjpYfDJ2s09t`L%uZ$d(SgSsE{pQ$Q{ajKkLalRfCPIBG|DO9CU zeh@@QfQcBXOi1!o)b~;)G>PIlK&CMVN1q@^egPSVxcX&duIfQJtos6)6uT^SIcFvt zM_cQ*afrxwF=RlyE8nsV_gw$DjJU(w#?!LJ#qavcD9TyHv`!U71b2%XI380)ZdJ71 zUZjf?c|~{%De_JZohSz~m7aEW`BnlCu&#s&YP`A0VP(o2=Dsm&$#-GO4nrito`%@( zkW;QkNiXXG0gK{t#1H z9SVi?P-ZXhU2|>jIyuZrY?+ecD6?~O#he@+F+}P%Vzh!3J8fI#(d~ON-p+@o)jsL= zGE57jf#~$`eE~cz%h|(5$3m-b4U(TZuL3YmZ|0*{M3Z2)iO8i?-?F+fjGU$n`m@fR zE|LeT*pG7Cg_j|ZIH&>}NJkJtPLyBECy%*SHPR&V$8k%&KBewrEpA)Lqmn=Nb=k51 zs%KN$NgOZMHC2ClZpAv{-qWwp;#GLxL>8+^%qRd~>Z>Y6CuMR60=0F!vJO3YXp4i? zye^+S9g-L0ydkCq9_8^iWbX{8QM{Ejg zl$|#BG%g)0_(jaE9KTm1P81}A)exrlrRqROKibzr!c~n&g+P^TMM)b!S*f3GbLxqX zOhEgd>Fv%v6GykblJuip2R6ysLhoxHOlz^mT1f0Nq9!9iWcsR1nedExAEd#K@2W&j zU7ZEULp}2;-w$x|ZT~4GvAy@uR=$7q0u{J<{i%LOa0tM$slGTD1)BLKw|BQ2FBl}A zmHDA=U`NKD7lfoF1%1B1xw?e};1!|FOXNVZTEcpxW4mTf*=FXb*IIb3jTir|iFYHB z%pXY2G^RQ7l1AUr!BbG}qQM<5XW!5yM0}>aFL+AC0q=RQjeU{4@8ICUU;JAH&fGb! zZO|C@h!M{8XrR^1z^=5|5SZk3|=~D!wBl z!8s7>SY4YKgQ=>BJmH2QM;<=mIJo+@Qz=8E=UVlX|2q_z1)Ei-Wa7;X*p-oZ>ICC;WE7^t-ZXXFqJVZ3ZH+B#Vc{gOt+Ak>rRDNlo@s67R5-NtWplSTH zLE18j0dq4F<7?cAID7QvJ~1enky{GB9|zlbkVjIVY)aT5W>823K5l(y)#Z`+`jg98 z;|4qdIQg)zXVHTA$w9Wf^{RJ`D|3i|H}7vplOm8h@Avk#@!!^$DVvQetfp-$nz*MM z_{se}au>xMVQK;~hc%BLb{w;WJfy2iCPbNT@H!V&JUdDPYGCO}wM`9q3_3Ggs_d^e z$!U8@jyrs>8|U>$tG5GS^9!q&F-18C1~MTKaSfcq8RW#c+h&SDg$8Z>BBN#nxwdhj zbeVKN*?*I2Vr{h3Zs{1H>MP)zlLMYF&Eb)8b>G_jA(8)GB3wTp->T-CuxVW`JJ>|>s-K+k_qP7#4(hzlG^b7gM+a1fIBFOPG$I*O7w_t4W4uM0Rss@Vw zeim8v{B7F{Z?=O&-Lsr_Y;4ae64w%A;wZ^$-~EOF45C=vAiJFa9jy`90lS5@Aw7TT zUG^XImDfYuj_g}7oAoJm`;c`}4ocThQ>#(2NDDT{0NVRetWw7kS{h5k=+|xRmanx9 zP`0Wgqny`N>xiH;9v2NOthF^(`Ljerc0TgR72YblZsX=1x2fNOJXG$79fS7R{)9|) z@@-{FkH0=jOcIp|U_Uu>Qd{Z`7u0uHDJsI>Jb8+lXW_gkOfI})R;oG0rY@A04S%xh z4;pV=dLc+J$g{v1{G9tR1-L#O|KrzVg|^ftSc~B34^7PvQ$wu$5h#=Cm`Q%6t|z5& z144Xq9NWo~c!GKQzH5O!YScka`TI(m-Ut`+jYEUiAhzV3w)Jx=<*Y`&&l&K5=Ie51VsDp@Xt`g?h^g4`3i`|HG# zY(Ie(eob}?{3po5`*#*Hz8MbqH&?QioO26#8PCP4-ad5zLkJExy-5nuBQ@hLgYhX! zssN$&Gc;aZ$;;qP2hrg>Ta~q3Gx*+ddoVD#5R*&`Vp1?sp!#4cYf6hVPjBNnXO}e8 z?E#1t7-2wU(m#F(*d&DiPGabfO!xZv@ppdvC?T#EcsXAbx$8Rf9Sqx?z`b9QhQ^V= z?m>DYC@1y+L&rxTQcpb3h_J}CE=2x#wF0bXp?-sAl|JYiFr>UcOys|-W3Th8-m4~w zkc(d031#>@+wF87vrRY948RlzeGZuCPNNaLkV2(NeDw-eeFUYFHktHSH+a9uY4#zi zfg$?q;MWCv0QSlXK>e;-8I<4^CLzinR95Sv4h&-Z4&8PKY}dSB+-Tq@kaWq){4tGF zBWZULg}k9C{4g~>K0dkF`*L;ywK~Z^YHkm%kz}2Xx+Rvm1heBu)U^yyv7glWGb zS-07yu3zx*XmJ*GHAK86J_ygug_mWY+hEpyHTJ3SE~&)jFb%FU7N_ch!;Ba!Kwp_% zJEp&;4p2{l@g^1vdD4g&$Bt`P9iU1!(#ofof7v=U60DUH#O2jsH^5c@)r+=lgTEE4 ziFI?ciL@_AW#d?zZktO-wUFg)@^TQ;yr?rTg|+CDX+5=($;-^sEyO5vU_dPNFt6Z*nP_nRUu%F0d=xV3VOX$K@j7!(=ZX|D87!U4y_)DUpSkQk zMlW4Y#R8mZC@X5iL>~T}Dypc10=1g`h)+rN3_Q*P{-PrCRi}|dJ6J0KJ6ut_-$?R# z{)3wmL+|KX?8@7s_ND9Esx<;;NM5JZ7BTEZOfRWjov(X;!V8x6uH_#>b+rMP3FYq| zDBKJKpK(UW(+HmphD&4VkUs1^2k9u9oyJ(;1}y{#@%Nx?^eiBk@Hg9luJ7v$W~1T0 z7HR~;$2HQ6?B^Cw_Y^{u98^8j<48)O`WcjW0nW|dqyRg3m`*V}HL_;`=RNvb-Sk3a zzt{ve2*ZWe!aZi$`r~a~pvp7uG1<%3ba1dT&{O7s7DnN4dxfRX`B@{YSqVLZd_C`W zcC54Xi$UJcHeQ9A6-yjg`At#dv*mI#9%@=LVm^y*@upsgy7I~M zG_uPz?n=5pep5)Q$HXDaVo1Fq(I!OkoxNK#mE#8tEW$3<>X4-}<2#-`;S{FN7x8T5 zmt`GG4lS}m3sF8BS9lIGL6k}lN4=m1tfJLG{Pe>}Gz?v!T5%-b>8MwwmDk^#p1`y_ zlz8-4w(gR?V>ik&PnZnzdM$zG;E}`u`&l>5^22n@9C?W3?!j4SF7znM@kYLMuC2yp)(^Q5-3Jk$OgGIg|CMm0`)&P);|}` zjg!0Y`>}tl6oWH%Vn7$nHSc&^cjl&I_ue{DRuGQ;S|;lT>eMLfBHZ5ktap0DIKw4Y$jI!bn1zUq#OSwcm~B}$X0N>pS?c*7 zKAiM$`zfEmkG-M$=WNe&X0?hGSA(6|l=nO~dW$N|ds$z04`G~}Rc?vbst!wjit5>9 zfAPM3r{5B9DHo!ZB7Nmq0Aj*sAq^%0Y;+;dkmbriHx{T5se>W=Y)sIvURlw;+~Am<@L(&9 zHZ!UGz0uOuA#m?R!JVo7?BarWEmL#+c7OXIc9eLi4+h0+*zbpq1^;U98rz;jB3T=$ zx61ewgNQ3Kg0do6A}+}eQpi!~L+oHQ%xP=m)LgTe(T~La9j$57bWN@MbcnwK7hFcS zInnceR;V~CDBW zvEue#HE_A4^yhvXk*%d1*EE-M8lY#<+Zdza5kQZjC(>EN$rDrz6cuk9+-~*a`Y3cN zaB9BHIXc#AT779uj~h58+0<~om5f=aUuc5-ePo8fDQL6PY+wi(nR8bqaX5= z$F%3;XKV3*mt%&HKTA{XII5N9#u@6`I;>p*Bf@g`EDnlvlw_g^e?xfimx$+j<+^_6 z!ts&{c(99!iw|X=WUbF2*)ew>SbROas`qMT&A27BP7*&U^xEMpbE=0(zrq_3wU@8p z_pBOQr&*6~-U3?I52zOTQ$=9fqI;6W_|`LBL+ZgoaOJaE9h7sh*F2xSZ^%mLXvmgT zNN3DlJ}vwWAw}a5G=r1gLh4EAxv2Du$lxfO#o5Q^Mez}?8>wIu?a#qSPiV4z-E;X$ zIgB+U$W<-5qx_@D^7xS8EPG} z;o<$7Mc0J(z`8pc26~gash*1BcF>4^PE5jdN5FEOqt#b*uY>wK!&@jhxLv;Bb1KsO zvW`~p((LHc-<4oSutFT6%^Xs`&7oe%*IFFVO+ig>@^0}nit z5F{*Klv9N+vK$R}>30a9z029j_2!6kh}K>EyM*YcodVsAxAw*OIDpprtj|BN`kEB# zb(#}{BM=Eh9Y(@!ClUtiQ)x?|`pA5%>GLLB@@0jtR;;&tv_?&s&wV)-B(%BlUR z_wSkP{`MaxBBeK@rCYJ{oektv-!q;gzI3hq0jPp*+vkRAHFxt$&meLAI9n&mJHBq&soy#lP124WB(? zarSLIex9%It+D!UVCZu0K?%kN`x-LHO)>Y2r|D+qOcGq0zj4}XauOoqEQMH5H`uL8xeH)>hg9_%C?FFjh4 zPo56npQ&xUX*T}yWGeLy-E7LK*iXo+nqAO{QVTt~^t}@mTAYv-eK!fAwFRID=T3lL zZ+k|QhH2?<&+qw36sfGk44&q&F*=YL=P%PSjGrWlsz>oB^O0wQg!CO+A2T{0X~Oiu z$kVu~1{f-xHG01xbbeK-mc$A_a!5N3BRiaN_P1AVYYP(H@KZy%jWe~?Mx?c9vp~01 zhStdu*>7i%oaoOPS-(Mg0MGQh_?E`=*r^K(57%zlj$6rYKaAc&Rw&W3GhtP3r+{_N z0-k-1nb>4ZDgHY@`g^SggZIbn-sIx`o|fy4VPgdJ=%2{GheUc= z6|_YJr5{3i4t|~V^X=_?%_;q(M@mZsV&!R1zHPjJoU{cv zNdbyrsg?Z^fKpe#^-g{Q{BbfzU$BoQ%rEYbYZ^PoT5LlWrQG7ya3GrXA;F^8pfsQ5 z+Hmqi2Opk-FL=Qp_`ksv8w!w9P3b8k8R*$YSu3?{kqJ|CO*~gvsimO zlWDQ|W7qNN+I|yYi6P@ze3I%yd^`F8c3B!S^36CHbCvrv$QcUaYN&Ki{1Jo*jFFz= z6Qx-OUl@CP%t4AXfDRXP3jPvgyB7ThBN9Iy@3v`HY}xddMJ!Oo$;C?jBq>JDFyow!DjFTDJNn!v?_>&VG3wI;3xD(p^@$x%xfGD(_{ zRc`5)th;)Nt@oA@o#2q+d*sCQ^28ST?-v41M`b(`9Tz;c8+vY}iQ`Qp)9lj&>4FgT zuhWFM(U2YRa`~_Kq@`ua--=_{2>TFP$^qOoInTk_6Zm0iK|$xp@@5}LZi7?4HBI|P zNS$3@b38;`Zk|cQZwOVeWN4cd<$=tddU#vumHa9-hqFobZ zp1qX2_$dgB2m(ol>1JWxBmp6(ti(96pwXI;@Ws|+#$3`Rs7vo*A{)^HT@TsZGM&|de^J}RMB!sNb#bt^A zI8X{fvB0TiU6?W7b}DA2j+1vE&zRoIJa5ga#iDFy(mOeD5ji5;5%VpbuiWa!%5SmK zc`m3E&oT!cGButCLm`s9%=_Usn>HZ;ysR<`*bIl!-Z52`GP4D<= zq*qU9>Gz{STmq+&kL8eAeyPTFs5KNIjoHhgq#-I?;DOVCnkXk}jXH=4XD*qR8w}4E zC1eGX5$#;v6f$J$8}3P8h4x_D@qu;)f8v*yhpdA_ut2nS5`UYhi(?LD+ZU0C0&6@H zXjk^c<>hMB`!lTjS{~2?`p+Qt1-&WEPKIHbFJF>2+k(hT?tE+RW}6Tqe%5dH^m{b* z4vk6H41wPMNMs%KS41ml{LmeWXxyl*i3%>;Ay+d-fRHu;%d+96ZqOrTsr)-0gZ>2cm8_66+R%WW%{ z>ox}aaM%=w z`mMCNAXEnTi~-!e+4_n)S>4tXY*_JG#Q!2Eo2)6(-HXS}Qt4>w;6=EItLx)Zd9deS zZeXm0MSIQD(wA8GHDtyX=NKK~%U@u_PMZKE)KK8ca8==bQ5w{lnDEnX_`f zH*lHQfyS2cKmuAX$^_@Wkd%cIw@_`!4G%PEVUl7dGH`{~GP9r@>8C}-A4a%2Yhx=v z@}lW#!Y-MgEIDg+&u-c=uVk!AzbtoFtZ(cb82o7JnPAO8v`J~lqN8wKz54)L2SMO_ z?QbJa-(46I*SA-&9zX8JxYZn>N~xJLhZdk_qukF0OTV3|7ZIi!jabod9M7M)u|N;W z1{Un6f2CQKhND*yn|uZj!mWHPezn^^LxxQr?FfT$HYftEHsqSmkek2W-eCR!*)b+8 zDephqu^ghuM^XKuXfb<1Ue3in1*|hqTQFh^sVOyPNAfj;HDZq z*T)s7J;%lR3i+{EupeThGGg)3saI7et;h*y)Hj4>rC{EFiC#I0@^6cHw!!wYCp7itnf=D|j|OhnY%5B{Gm{mq)5^Q)ySLKtdlk?bktveR?~wls*>& z)x47hQe44@=B!(2z}ot$2AyWIf> zQ^%0`MxD1{L&w>+QlK7Dt3eW?oMiDdYzU`XDCOn1=#`P=^ZH-p4LBN%#M^og@@eD= zvrG3$nB1eJ!+FI3o&Mw3&`>u-v-uSa^e^<@t6h%mDI?}V<%P`oIpINus-TcP#PAtVGx(9Ej|(XSjMoeKX4FiUiGQRI?Pv(Lw?ED0TNThN zWQ;C?)1+WyW4mU1!5N#N+0aQHh%dl|WBZcWIHaD0!N|R5F8dv_aGH=S_TZ@cQI3nY z#heC)b=ZfrehjkRh<0#7$K^CguuP>dmTMiX>Y;nL7n?yE&)B6_s`qO)Y(>qF+-~-}gHul`3eh|xRskXPD}-@k z1J-k&5HX4_@rcJ;yhR!cj;07K1o`__pu;x;Ey?jw1hAHX&UMmUx!k&$to42gc7}mm zLlM;-;P4Z9$i|7!L*<@tKEO7!wqAtwT0(LV(LpG*BB=k6u+&0ts&In}Y|Zzssyi2b zkt6(j(3?dQ^J89Y+~!=Ti>a*s!mqx_NK^0*Nc&xByOH9qRR`i1`YR@j5I)J+)}i38 zZR~t96D%IVK5h!1az8&W78l)}5)RWDv*OL@$~TYxiH0F%(gw^ELEeLmo zIm-g6#=C#u!UqJ<+>k~twQKqcjK;|yNQW%G%mW=Y{tnmGaA6=@T9i;K3#u@?k}*fd z;>}oHk$m$_OO_>2m{B*bm)iHlE>e)3wrct#B9P5noi2kVs`HSlXl7mE2D7pxA;mTy z3y8JMG$s7$hRz4BTke-5f&%>tV@e|W~jvuxR%`dEfV)~8D zuo4aP6`R!3AAL28rKRxU5sHJX8l(mYI?)dPptujK%s4FuN72D-XR5`0Q~u;fpcb|l zT-)7l2);jhHBNXNKn8NIJq*90$QG^lo#&MG$3GXI!hB-#ju_FFw9etj40GG$`lVqo z7jpydxn*ch1{O*9`sbQS6Z*}vno3gpJ^kaQF_ zewj5qY&7fMc#cH9#*|*T&q(K|hVESd4rxMqKenXS(07#=<_eR_xPHziih&L41A83T zdHCMg-XUMvi0D((;4m*D={ShZ+#{sn9!hE%n3qFMBww2jda{JSsurlA05N`X&_2xc9RRqyT>F_}q%_;~3*lb=o|%tt z6vgry)vQ2Xw&NtZMsL%cIB~mSk!ud4v)`^@TDhUthD|AQP-y1u2rk{ZikoJ6D)&Jh+Mlm&=A2~soo9wG2j@d3go!boZs z1N}2h1s*k@-gH~A;Gn?59Vou>pG+k+rb4eO&JE0)#%jd>UZSyygqTEx#xKyXl#Hz3 zoq=JL?I+~KBWF%ihXR2vrnh`hnzS_B?tDK1@I{&_F{+J)T#gk@7Od%{SMuk{CFni#4NhMR;rtsh1Gs?^TcI8b=lm-dIu7w0ot z9R7VmoI()}rBVe7t^N332Mqi@%U<^sVK2qy6I$_VnWe38$sIZL@Zkn$in^#cocne& zN5V-s9Dn1lfWgN=+cgC4m`-ollicqlt8cwT)wxA%RKj8iC7kshYh|G0k60!);?32c z$iacOZOKbN8I_5xj%gUExr2*}P3(Q@V3-pqc3Ge|A{!Bn#$QlRjl3 z#Qiwp_~5CbG6whC%_0?~?xErZJvCGO^`5g z6`cBHPHMx%i_GJFynEEan}4Gs7^*+cME&{+hbH#KWsBHMJj96VVJ4MQNL`tVh6D3V z)uB5cQu-sufqZT?+u%Kq_=oPxA(D1-UxVX=|3cxnPQQvh+7nSat6SlD_1+=(*3ZSf z%(>=f0(A7lhA0!bZ0(^Ur2;afJxxkw0IG1`G?DFFpD*~>FvQ#KS zh)kd!#7=Xz}Nx3EFS8QkM5&FjdM|k795cz z`K?0>4)ks|qxVEpP8Hyj(J+KrI4E})i1ZGvB{NQ`7ABUIc{2adacJ|#0u_7egi}0m zPogDg0Z0N5Yde#4H8slQh-j)nBi?xq`Pcz4D<|i%hlD{Zi)A(VP;7nR(Xtw1DbhRM zDOzqXky@Eq;gxJ?y7P5}X=*fPfpp+y$NmW-)^czV_vYapCz1Sc$yf4+&ehInQw(6r z(b}8kRw0xo8C8r;1^Z!8gj`od^kMhH^@|iMu=n7n8}G5Xh=mx)r(GlY0);)Fc*$n?nD=eF)f*hk{bQM?5dYW#^Y@x5@LM67>HWXOkT-wUch_#05hT| z+3SL{JNfImB`6?3=(b8k$pw(}v`~BMd;PrGvwLC8K@eb9yg`-lWKgBX8UUxvgxlwA z@Aj8!L2cwIPoTXuS&YmiGdtVg&0y1HNgzAp=ubare}#whJ^EZPt#PZe0kb4=u`9QL z??{#7oAxDQm<4lsl+D^D=&ln!EG%UNtgC&s%vVc1%M=(_*% z2y=w}5Ps!*m=GSgxeOkw>1S~3f8NAX@#g{w?A#p8iJ)MRGTZzh2-1H{!HC#1iu;g$ zlOK%aJR2zq+~~CS1t> zsa64SbV{uU2hLcPi9Sh#S^a8^jCn3dTuO^*aJuU3ad+X!TfO(o=EmM%FCBHJWZ;C5 z!pqxdxJ380Xm_0R?$t24%9v z*dHjbnYt>NZsOm+2(duUk-b_a_t^=Lto`W}LU!nFKNEw5jgD#kks8Z5;A7_>f2_85V##i&+=$t&s#@It3kVi5%1-c%Yai_4x zG@R{J<%Eyn0q7z#YmBt2zkJA#8Bb+;mxAdh?fsrQ^(*kMdw)}-M+LY^{zOi)3V&sC zyN4?#btv^n$S=;hAZTb57Sg0=97D`E?u;jGIsj>tLJ93F4|B`+t`BNcEoS4wikF$( zYduGv&Ll3Rlj73_*Tp#52Za$xu9PceQ54hQ@$QeuE!i?|3=@LtHwTV!hspux0g>yJ z=QDH-IS~iKz6H}v3mIZLZ%sXS$N@^} zT#LP7d4;JKDQnjx?z`uw23hu%Rw#YY&_X@XWh`T*jZE_DBE5U2XP2C%f-t@_0(7X( zFl2mJ_f4jn>30&JnQ9dTFd?Oht8M*g{mw#vd|%V$>XYuLtL*p7hRMEOjWTo*gMQjk zL;!;GECg-GwD&$;SPK(TY*H+UJ!FL8FgIOqLIRqjCCFs&hoNSB7uEA~jzTJ+01ua7 zikSixVJ+I9T{TwjqTAU};bA zJ5x3{aV&o{t}gL0q|6FJPDxFz@tNP)aevR@k%5MYCFy34s+4xrG|ntdthbGYqSMTo zot7g{SALMg=0;^GCcvArUR=`=l$j-TOtfB|ooCSJTQN+Yj#DX_HXmW=I(P9`Xp}aZ zv=vVou&9{F_`bLhUoljt3d`>q^i^|FJae5Fu@X)UE0(Be**SA0KwK(-y*~W9xmSEA zArc7N-nM0h6B+VU0BIOpS4w;;-t@FU_)BGlDfN%<97XlFrZBy`+K2SrqJ@$ZV$%OM z`9H4L0lQzw#9h3UsF6`?En$O-lln%sG|HX&ST#JgWTW2|T{lL~XtMgKfwJ>N2L7`HBqqEWXFByb{T|CqX>HrP3|^yv%=(xW zwcEybGU?AEQ`G6gXg=J8pNGm=^zqZjXW`_pA8vkS-Tdl2!~aVWgI`7kjKUdbTp|kq z39Bvlf*z!#98{oDe;HViAua%RJ#EUk>h>rLyAfkFo83D#V7Xs50t0QC5!|4;*dE{C z)kPNb!8j0Mp)X}!Y%tNy@4SBPy&mAO7mJF=toP-|n^uvWQy2AUTY)6!c!1b#^(fE~ zL)BR&pH@45=iH?+K((>-hrXjhe)`Hu1pEvvD_mXWJm4SF(LdOMlWywGtL5!-kKWf4 z6B}b1^_)Wz9)Axz&Vwc`154otL>i45_aDUCh&__XusAH+xTQzS!a_{e{h4 zf=csmbFsdTao8TLXB{n`+lv=w^br1iSEmuHtz5LF=70yhHN9iPuqO$9}3q<0LQE1IIq5uf{(;iG&KDY?7TIFEc1gHbVu9e5)u3j^wzo5giGIwSM` z*2N9XzG#0XnlEY4VpI>VF93Fcp9Sql{d=~E`9ng5;uY&PN6qr!KeGtX z^OaZQjLDr8rfhxm4`vq;^Q)w3p%dLiMpnnNgJJ*p%l_}GU%dTGB}B*M-hyKN@7Uj4 zvW8-Q*(PF(Zx^Z;qII!t?~Ol5k25opJshH?3xREi?JM?jvjYfnRw~76v$I40F6#qy zUFslrRjX!;Gi2^WQ3JSU^C^hNQG=W#wPvlE!Ju^@7L>?RG2y9ve_i>RZaN8nk4YeH zVrQp?%rZ^7JG*q;%$qWe-F}eItw*&X)X$99tg+^QCGDkuy#eE@0~CY?imj`vHVVUi zudD)3tBxnvvk~?XBO}%{*Qt!5V~Rr86(yV|PQWq>-&ol z3<7v%8Jc2?W8CM@4D|3v1=?e;t#F~E4SbK7e48REP5%J-h| zNvlojsu$;DY1+M9=qJ@6U`hC9L*$?SU@T9Adacn;>Ra>^A%%S-_N=<+kXzXaVxg{ z<+o2;55M=0gu4k0O{A3-&%+X$z$q>kS%6y!RVam5AOu@kVt9Uf5naTb7A*8_qy!oA z;!m7m#z-~g3+cm3J7HJN6!&)&1(P43G!l$~Cy zy=yj(re3s^y-(kv!!Pxul8voX)-P1+Xt5bridSGdI&6?8O}#D7LD;pKgbVcq^OJS2_h~J ziJ=l|=iZ6!t2xd@Bx00009a7bBm001mY z001mY0i`{bsQ>@~0drDELIAGL9O(c600d`2O+f$vv5yPb%1#}*ZrrU)Vm zs0ac}lMd3$vU~sU=bra4zq#C*o!Olk7Ixm}InSNB_g7AN&-;Gga?UAbp5|$u=4ll5 z`~9uUJk8S$k%D;_Mfq@)P0BpY(+!P+aUUGzq$n>b^E7L;QJJT8reMdWHuj3`(2$LPE$XZtc~+EOnWq_{c?>*rbZV5JM!9B^YyK4FC%s;;U*>6^))xwixx%e1 zAj-qx(kS0f40}RZONx6x)M47A6EdKq$~?_DZK#2a)1zD#-heIQ^Py305#@JL9uozw zJ)^8Wk*ZfmSsvwsQT{f{KSa4{nWuT02}(77bVpLI?np}X>9Up-_wE~#U9jS|aCVfN zq*T75%n-%1c1N6Wf&YLq8L*gHiVBF`%J!glM z6?$Wo1zBHS6CREyb$(wN?_E_kFxt==__kBH zMjuhpQXsEoU>f3!?lv|epzi%XwN21P$qkJqcU7f}EuPkE|hF5~W`I0gPiuYaX z#YjoJY3FAXbzt%q5vj59$05qpx-F<%Ucf zIs>ns;QOyeIXeG7G0KrqPATgFr8nahQ8w>WMUv10GzRW!3tUfX)vbA8(HOY}xr5 z)HzgL%LYgrYC0v~?B7pv$vw+@Mp5U@L-IZ^{=9b??>RX)%D2iqZ8#Ln@Q^6S^(UqS z%X&spr$_YbV$osx-ueV_=9;b-BaSqQ52|^pKG2zbw>*WXMOiY*Ww(y&wvGCoo%iro z>{P1X)pB_foUivgQI3e~E-tf3@&2t!^#cztMPh`0^ZJ4~*)Jl52Sy$KQmzNOzPu2R z2zAI%+BX`0ZkbyWiWNlIc#>-j3@OdJhm$d_RT`MMg`FQ1<*8BrFRuH3e4ZbLTWuzp zsRcitU8>t`SkelF{GeQaL=Z_*+9vwoQ!$oTl{u#Cg@GeP+h4F?!E58sbEDy(ovR2^ zs@j)Dxz!pj6-C=KuHPo=CdwvoFzhqdcXr$%fiM@3##J3@=#z%obb@yXOqdMAOzA$1 zyHVETYf+w2t~=peM+00~u3xgE?f$``TYIjSr0CCRWY^smtgMO z#dr6Jvb0VZDc?m=&)1iVd({^MeXu$VZWOUFzs8S>>mYIGb!PKL{H+WRBj?ri{_a4zv`>d;UN#=zg|Gi9)dELu6 z`a=A9|4A;hga_{X?TFuQA7!(E1jmI`g$ai}5jHpBhO@be32~En-$A8D)w;x24rktc z=zGj5A%6cRDbu&kpyVbr88G6V@_MP3$6j;IHOGY!dt}`6hcbD)UKr&CrMd=7KA-kt zl!AcE^K1B>KOCd8174eLqj5epqCGQCbIHIMbX9&z{aaD06wzR_mUO_(q|@ihy5l>~ zd4H+7ywjo>;BS_y-Y1(xm~tc}2}U_K80D?Oyre(Xdh*aEw9$%E8QuGW*H@n)8Ggj$ zM%4lK{<|oL1!I{&eAFhyT}x$J5*rj~<7?H)qoPjw_>U%Ne10k3d+fLuRrp{(WA!!} ze%bliX5G)uXEpB!H=Y$G@6GqpJXg(SU}Y{Dn1uLasZ#d?r7{RfytLGP6Ku!-)QoD8 z)@#MUiFvJp*r!yBcx?!t-E8Q)f#;xKcUy;LTOJ8!;f>fbuPF-`Et!RBc=a>$sW zW%z($Y7A_!FAwGg3tpekUK4={u=0PEiibrPH=X4AjiL_5+Jqw{XeO(&jm4XzoD{#4 znv1gS`jGps%fP%UTVjrybXIlj2Sp{ zlh79W;mi5GiMzB^?}KstNSQ;L%WO0Q3RhxM-Utz-6Y@J!gc{UoaMxL7?TG5bymv0^ zMg~{r*Up{qFf?hiC>YN^5ATS-UlW6QK&cXtMC}?aGz{!L9Kqv-xhB=O1)A_F97*Gl zh!>T)BaCbU{&T5Ipg;ibIqe)?>V!GD%&rM-F_<|0y3o}mCB=>DXG>juJuRDKU1(Mr zI2y89ziz}~mQ%G~ELB>ex0cEzIuX8Ne86a5O~Yk6@39>esUYeF2d-Gck57Yfl)8E9hqVyw*4JZy8rC zYU&+U8G|{mDHR?Gy!<>9di2AbC-uw<_3O^%kMGxmP3(zaOQa8A z%ziy?>Vf^bWJhM&Por?5k!a7%-yas`>;1YCVWM|9;_8e2dVtEhkV9B(R!#cZV?m;k z=omHs+$dk^*Q2zYh4G%w`*;E#n(h2@ziy%WZ&CK>*WGl~PiC9#RQFl6YSqW$^Qry1 z6DEsZz(RBn4t-LT|L)g4Bpk_gLVx0APqRhbdf$(7n@%6w*J97C-%b0eP2%&#{W?xt zN4q}PukEmZ#pY#>XtpshDFRdR3Bru<-4mkxQ3IwU8+iCsF^&ZEm$M^_2*z}c(qAK>hzSAD_5Qx-&4P^@5f73 z%cM7nBx*OnjiF(<)ohjmds5%VfFu{y`@d49*VVb=*>`7^IS99RNPQn0ZE@<-AZst` z0#1;!x6O9g2bq^erW|a{Whkft%m3FD112*U(DU zZqcGe?R)f`Qp3*FF6QG}>S9VpqA)XK>4Lll{MmM>P9_I$&5AO|6m8+nv2#)LMu1ja zYit7tHL_nAYc_r{zQ*l+Q7-D&Q%dK=!!@ff;h>L(ke+Q*4+90$n%S4;WhAf8!Jsw? zA?aX1adk{Z9X%|s8}Nj$6%3Y(hUuuhz-g6-TWME z<&=ZP&4$Te6@O!zr^TmmUYE>ZaO|%QigiRtTY2$+9V~$V?fdd zCg}1qmITu;<0UGUx}uCF!;GSdj-i$Fz+jayW75wF#*BX1WWj<3#^Km}w~1@-HwGO; zciXHRhW%5fff{GUM|9uu-2oiVTiYirtQBzyQGY%|u zmSf<<@^?m{*}twvs7b^4m~7i9l4q-YClyHo!GbOE#sL0v{*I9``>CD#o0ma9z=I|X z2@6(`))<04urRNaekn(K+%E6ApD_=~ic*b2R{ySL4pJ6N&B}v$`KtdV>cSoBy)Zn# zF(aI(1@4uf0UFA#JGIO*&H0+Rmf)NNqyx^(ogU={FpNZZKng|`rXa=PQ&xMk?lI3j z%DNL{nOq`5?~~1FDW&DfI%a8fhh$fxbXxpXol6@=k;segx^id201YOOG|}8 z0tSLR(h-6}IV3?B)53je){nD80TBh(Y6-*V|`xf)cT00}Ibs&q`uT!{pSmZNtTq_1V zzxzeM9s|2a8A~dH-x*^96uajtWeg3&(;TEHPsL7U%(K!ZhKz`n$%*kT>BnS}`$gd7 zgTRoOqwTPcNifD6%4kwQICQV54AT;S%E z!(s9cGV975()zSJB{j4x2H?vv07vF`X1Hh`h9$8v8}&pY!_e!JafbTky5U+&k1Rp@ z*ZkkafphNy59W6y4m`Ug@7Ir*5d(|3vBIy&!N#0$AO^*}m>u&suLaD@KHx4}kca8yAlrx)$0j7eHZ<{%_EprXF;(}UN2KLNrH-=7JC-8#Fy5Z1f zjJY18jxw~UeK12t7fdV!PGgW<7?egK$@kCupONppf3!^|7>RjNzN??GYQ$^G4jCP6 ziBHX4cWFM4H^q9xrDZIq`O<|87YbD$l-DgQqv`xI#-NPWjXUjcn|H5QG~0e)l7L(2 z$SGu)QGo`rr7()ny*6!5z1 z#EQHQ^S8BPU=bIcN!K?i$yeQ%<29hz+kOo~#MAi=xVaIH?% zQ8!CT2s6GrKe^QYoW9pGfn-`6^1Lnsw^aw2k{ZV-gOi6!WtPvED!~|X&4_f3TwvC> zltf`xOlI&MUn|PSuoI!eASzE4V+J^u#3$`wM-p(5ET0K63$l)Fv8M52z&4eAosQ_& z3_dQdCViJj`AOcdE{}`4bp6ks_n}f37hJoHDwvlr0ZTT|@6Yb7hi7oiHUpCcI^nI+ zfsCQ=PU3InAC??l*OFI^HxbPg2mdTB=0+G7!%)GbC#)^_@QwVNHsSkZv`E;&c)Sak zmsbJi&0DiaQ(e7uDyG&ZXcu`O(UF<{V;sS#ua6Ht3$4(e%)-l zC1d@iH;cOm%{Bv*Vyxt)rK(<%`1Da1<}w@(a#Cqg#rVm_PinfC!h+l=G%{9b*mY~}?yJeS(H z5cucv8PqxHwM#x%+~44B*LfEy$_v5Wh50ZKYC)_$M0s0urp&P?r6sI!l0-0Z%Wg7D zG5e?Ud0Sp{%{6xm>v{LQ4mQ0wuV?h!Yz-48pX3J#o*mzP zO|EjOQ8g|z%#BgMoX=ZUYUbPzvUDdLX2F2ec8kD)1af6D*v0W|hZLHKu(Z6|b9;5S zpOZr(TbcdD+$Z8Q+1~GGdzO~Uoa#kWh=ScEp2ekTHHDyypay2-^*A~2Yq*$XH(>_* zGnb07JyXURTVO@0Q0S;Kw!rj~;XqGZD?fVg_~= zWN{>{ds)`O#KyQX`*;N|ihj9g^b5@)fIIe|W#Hy`owt%8wRdYyv}^IjA8Nm*C00JHug z`$>CwNl0uk>t9OEm!Qpfe~ycBcukChvzZU>*F~o$@RCvmi_e3~*yeno$$w=3?$F80 zuz%gI*?%+_#=JP&Pgrc4{n9oqgxR%~!3n3+IwtX-dNZ{7$xKS%@AT?YaSTT~Es3&e zbQ*(#!9)r(ct{k#nUNZK$1FP4pi!60OI3f1^127bJ)ex{GXn1zpQIucwao-|*{_qr zxAV|%Iuz5Km?@gS>(@OTNEHSU$nxDxN+E@=NM<5c4FaFE$@!^lt9q&riE1g%KgD$d z6LJDpX8thDFVA^thJHVr{R3*eDu2glKaAhUVaA+*q@DzSxD#&QyHsX7D<$;C`8#NZ zx%jIwxa=_!c1_8XOcN_(s*RXc)ta!>?fKA+FnJnr2t-whVoMQGy~S9XrN!uJFL zsVi^z#Hf#nbm#0VlM8d3F#8Tq%yp$1W8id09g~uRs!?eThpk96MuZt_ute8%cFO|u zJB&n?pPAOIfnQqcdbIsAEe~^1quw=9D&-~loJPaZI`H6kz47_Qo&~33EVz`Eg;zzd ztR^@&+h`#t%x9v)teDmSwbcrwm<6c}L5HuHw0DUCe?km6DfZ4%lk@efcE%eSG$#$-`A=!q6tPhJ^&eU$e*1jS z67>rkNWn8+sZAj1x>O=J5jS#Nc^M;SXPQd+>u4y4lW z+h%=ETN^*~v>7-h0;6hiHukvQ*amYu#bCW68c33nd|*LSbu4cc$3W-BwU3Hx_mB9z z!N=^>{7*WAXkfg{Kp&IO!X#9e9O0WzP(>>B_|E^sE-je&sI0GN?w;>?Pd<~RV5q&I zROxsx5;f{I*u*c}O3Ijw@(oBotBpS#ZTU{L-Q+QNEOfyOXDI)qRA_KoT(?JD$Cxp2 zq}PYjAKdy^yGbve4{*WYzoS%XcHxLY#xNp(AR4SpyDW+KoE`6>!DyldL$HRbH=&Hp zUpoDU5ltKzeVbrjkcu{CADo{PnAc%xss3>I83Z%Ydf9g-lgSMe;}PR|Ro+80fEbsi zC+bx>KHBih`0fX(p{7hzX5j2t;n7!TCEbe|KE#qwOtWrY>?QPj!lIs)cqyACm9?+u?h_<#3?iNK`44R1zPLSjzGl+l* zsAZF7&$v!MU@}s2*D}6;F&4&ueyOnPvss^2`D~EHTckRjB;xcA2_#P z_YhzNygdqs{5$d*`#szzpJ9pl9_bWsdk{P^%KOa7C}4^Bz37#lzbD%#;fJXqTAgnl z<;bCHKGyl&o)mTtvLD2z`HlzX1ZvmZIm-K^oyUe$`)FP(Bkb5HXZCBdQOP!d95D6E z^4mv=L(;-ZB{SH=aJC=UaIP(;@~Ul_op$C3?PzXvUPBu=#AeTyCsNs z>DqL_ls+eS>iezyzKf5!h~5$3!OaXuxysTQx6FInUc1XnbyuB!lFTIBer4)=$~`DQC&Qep zvTmT1-PZR?$v7~4OU2XtyF3z*YzG_S)V%K6M5uVC{EDM{H312{mXSd6*lGYOr76W9k&IT3p#D+W`wCTD8uW(korK@ z%W|Wxy2EG&&m=Su@F5KQ)@Td7rwybPI0Sq0Wixbcll5^9$8XBmZtsXY%zz5y?2zAE zox4|cQ!K$4GcyhEl3&8{aci=eHk!IGZGB|X#>AuCXRa%FhQ0@(Jt>HSq;Pk@}2Jg z*HWeNIZ-dL=XF_^=2JBx%GE$c|?f37!_uG$|9 zy$=%HU8&`^0^=ykc}-neQO=jayf%>8~HhZ~VzGh|eA4 zyFIgSMID>A!1UX6?xm4Ta0dI7lYgee!0^gjqB6V1=TFkd$v`0yi2nzcu`ne9)G^;p z-BYTh>2==Q@=-U+dzuuSF0p*&E1Wd+{i-rrMQ)yTVQI6_H_rMjE@KkDN##audA)$c zPfK;sJCsGzib&OGhuXA5`a6&7JcGo&x{Relf+i(Hv3reRUV|&LNn$T4RpM`z5UT4! zyfW+5y_baMKBECVXR}%>SoMLJ6@BC3&MfFa9Szn`g=I$4_!Q;}-0~lputO z20E@zL8Dxf^`(6o%d{68Wy+faPKSa2m?2Ix>&l#c7iC4LdW~(HLSL3J;M!#C{`eeT z6&ws?uj;b%%G9YHqyl;vxV9DOCPVM=57!W>(-tKTlR9Ip;j}@LtIH(*ZYrEdgx3O$ z;Ldw}-v7hS^`llfpP2PLEeC8_*6(dytGi#l5sR}9w1qyUWk8G-z3WD>j;goyySBmh zS;v+WF-)toKHnd@Zz2-T=UpL1dsDneJG7T?oFLQx#(6=&u&`Lj@jz4(H z3@lL5uSp{sFY3eBspDZ;k_J;6WXy7TZ;EGxIbSV0XJMK826ls^xk~L2jTbf@mfW6Y zpzTlm*Hmkx2C_-k;kuqv#xuOU+B>r73zG^C{r-q|nJ6Z@Ac!zF7$A&0 z@GtjkG;OB{9^5+ouQV24@D};rE%Ln#;o(RYDE5UB^)(I?B|Lc+7=e+diZ|P`qJ>kq zrwcV3ZIbWoe&4jOcInG+_NIAu_Ot>SjH>8pRyfJ=Vj_;+1fD~Jm60S+Pjq)D#)A_Uu=^(1e z;N;_$-ylTFZ!7}EXL{0z_o$o6t{$W~4feCNz?)I_nDE~+{tW6>W&D0>XtQ$NWd7DB z*OPc%K`_}8ptiB~DAI@B6IG{6?wv}=xb4zE*ruSj7KeqeRWeV1%;}ElMjco^t;dzh zAXMH|{eKg6EQ#{Gkm}p^>arOFAw~sEdq<_i>>lEooNuLHaPyIdZnNTa#L*y;$%}^BZAhosO^p1Orw}5RRswfz8R%nM`hIZg} zIH)%VXBf{F-5?nl1};@m&XAEo{;Y#bstiyBOZhDfOx081yUD8z|fN1KQBBQb&}3VqVHX5dg6bT zns33E%*7=y1fCY)p*cuaQ7+h;v?W0wpMR?lxA_j~k6fMHpC-Vo~1xj9-@5N-` zj!A{7O&S3d8C)$V7^IPgsNU)i8e#a|vtM7B?`x~W+kS6s1O_N=(u`ftr%8l)r?tTI zMnw!M*-GKhd}1>5WY@|}b1IP44zQhUx96mnV{p7vlvhW2@XD1d9}#N*YiXzrmcjSy z2{{&uKDl2{KN7ze8I!T~oBZvjYp4V1{L!rUZh8Nb&hN6pWVG$h0pG6~bhqx;j5Mb! z$;RsEeaoWAwYZ{RPi6Xb6p1_Xhp)`GF)nRZD4#?iVTVpVT>tZa&DN5EXD6L~vR)t0 zHcMY!Hc5K~3S^SWDfyCj$0X6Ovge$xBx`Q_7$5a`Zq~^%ttI^t=UU{m?$@uGXUc8L zjhV8O_l!=n^48Y)w;1|;X)=N1v=;a4QB;z~zmo&@v+Ssi^LpF*JL2iS$iwe-*fqWmElw;jhN<#4Cg?&w3;THYk})Fg*{cS*)yqxQ_cdqYmF z7i7Jpd+r;>RtM5C7w5HBOS~=nPru$K+aiU4yU&Dl^w<+dyoW(dquhVQZ=N-4CwHzj zgy@g?f?*}hwj|2Qy}CgO$3CM+#7?6>+8bL7#cG$_L7h>>5^<V zf41$I&xrg*_Z>OmBq}jNUp4d_jJ`Dc;;UsAXk9QcTsAmmJ{o*nH25>oSjo?R)47Zi zxxxk%UOhPPV@PomVKNM8kTE<-$5L*YYM54sGD6_D?unMLZ(Fy9$=?;_s5ER$5K*n8 z%9@GcLOK|r=4(aWvz9+ss;~DoBv`3fRofq4DqdyPzb}Il7*hxEX7GkQDJI)l*+$PF ztY*%9;Q!73F>xKTD2zH-(3z9tMfslZ<)@^mJ7mQ0fb5$|890d)UlR9WV7_U|IRYgn zsXPwf!`cEUpNaD8MT-{cUxsx%=8XLzap&CL_;q{6%EVn(s!eck=QmnX_8I2>VCVb6 ztnAIus^qn%eq9mpl~g;oj`FGk1Y1{m|KRKYN=|E28>LzGAN>xrNrof8cH}WQG=G=zL~`CDDom;gPu?mz%tA-A zo%8-7@xRo>9kX*`vdzNC*eayDNEF82DWww?#*ceW-1Dlqhcp|`WFzfbG;KgB(ORCx z#hsXY3wdso>7l>EpuM_3*?=;!n`GshBDK^>T}Z8ihSMOExT0tm>J=Q~+WTa0Xi0he zk8ycDzzE)shh}}i29ojfy|L|5xz*YZ?%sdP;g{wF*|Cfrnsa8hRi+$Gz;(7w-ru%c zeP5}rz3=4vrNy>WLl&UCBw!r8s8{#*GAPswHx0+Ws1}^56VDIEyG5>E9%P~AR-W)Aca#C# zGQPubCIki%rZoY$sW8`LazW*BBdP|TU|^Ec^G&X$rTS_;AJcq0>WN8AE-s@M@p4`U z$$j!rTVX}#Js((VaDW=UXcA{XMx#;%H!uU}@XIo~A4&DLcyr5aKL$Iq*ZZ~j{RAg&>Df8u-m&fl0Q{+kq|6g?Avx4b=p3yVXjYJ%^ zaU5yK7mVroW?xWhXAN*rCs+ zz^N9wzU(7F+VMP4`z&#c{H?TxsUy)S#sHPffMSf;>)_Dg=f?GzNN5(rT9)(LU|!OA z)9B!xqk|9Vja~zWS$=%=)mLx5c=2L&!N?fCZC=eS^{}}2kx{;uIQ0$j_fEO=i6%LI z20Bl={DC=nazF#2aDfXF^H$Lg{igjQmR5XlrGagu z>Va`hI3AZ%<6bKxFtBl4QK}K!JWZejs9-GB3jx?uzC!X7m!vZr{*T+p{E%&RR+VfkI zHi#navSB+I)xc^$DX0A_d*j#bO_}<26$fbwuadyL1f&~=z;GrE+$&jL6!A$>_6)7~ zy_op#$i5kQf>7e@U*@whJ@{kd^T6o0&t_y5WCP9G38b#ajK&+2zAoPPhj^cRd6B?J zT7r;!d_L#+GJ`Zzq2wi{f_|6>)?Hr4_8uEhV!gdf9Z=T(OEORQhzXwA{GVWjS#C8$ zTRcgc@^aX>>(~kIAM6ZSs-K$le`2W^Q+SsIai30oPCSDzTF4gWHW^77(t}UAEmUpG z*fAza4liO}MqN9kuw{|8V`K-*oZ|U=hjbT)7NG-`F3I*##TQK7tC~Snc6rXmvsmCxGm4mKEj~m zq;{_!!b8G?h~R>-G{5=t<9)*2`jhJnv}6as$UISC<(tY3(wryrM8h!+oThQG(1BC9 zr=8V+2}mEfn|kJVq?Wo19ovaL{G`+?3G%}9E|3HyE(xQ98CM1fR^&DD9?aPod9YeJ z?zK5y+f&zsf}Kq;6AFWnY|XgCh}-0~`WG{sL<0yDjJ!i0p0YZhufFH!edlF8VBS;m zd(SpWXe6-gyZNa;{LQoqhHY7Ex5{V0{9wa#qwaRcxp$eok1-<&`QV(iCi{hxL7%ve zX8dA~%d@f%^o!Kaw#(9zQoS1>jzy_2E;C3op3E~DrKQaIe`Khd55{c$)g;#%e2jqM zcsVd1mrOsHfG6XV`P&;xWi}n&)~ktDkyPLSHG6e*9La#;xs4c{4~_Rz>kJWi^6~jR z>bUjGVC`G3l)zjVkt)R?24%47I_h(;sL!9`^KS8J8!DSr8%&dwR3nXf5sr`FG2T{L zXHwLFg9j}c$qqfv)@bVlF*9lXhpcN`eq|ErgInf(CN0UgB#IEWoZ%Nl(RUv&Yo<-h zm}g*cu1Tr(!hyYsm--x>?ILBtlqU>Br1*aYpLW)H$~*2%mFARzOJzt>@4#T5-%o@G z(^y#=4DpiOD3Fw7)t;BnU=W-hzrQkmhjn#0oM{<1j6FEQwp14n=_P4sVBjSF-6ZZ? zmFgX~rUo$*{7fT&L8RGM`J6kH>Ynm9_Yh-9wi|cTgX3AS{~h8}1d!^dju}ty5A>?fYT2~*#en1@Ua|^CuAQTGU7V-UQ}k` zxPduk;9lL~@wby*lLi9jcxPI}obYxo|6TrmQGAb~1wSwehBSB#q~A90K|aSlq?}v~ z;c3h~*vldVBMNm)Rf7f?299NDU}{WH!o0bR!IgHB5x11}a0X334vs7+6%w@Q)&2A6 zS8(T$tQRI*R;r{|Z*ZcWh{P~@lmJbs%gZqo#1$HaDm!Ldw$1{p{yy8PO(gD$ zQun^lo@Ur?mj8S2c6mK_7zugX?1$H7pX{IQd1pR<)K&o{b2vVh{^m(D|7L^cS^`gn zr0el$Y?8;$!n+F-qmeG8E#uGj`xxWe-DUbUmC#nAtJ2UQN$=dNCkvgN*N`yq8JxF8 zG6`wJBZBc(lp1sZ2`-5Dle#<(n4#fI((mWJx)UVECt+^cB6$7&wHs83ATl2LrGK8^ znMe}PX`*GN8jR}MwzC2SzSyhVY9Z2@ab{PZuV;Vo%)sf4!9k*b8H+r^%ok>4k4$W_8ROT(675n-aeh@BqqZ}Y99$ly6o6}c(3lbP6cC%z0y5JYLU9& zgiNnXg?aO61Q=G#AAEsZ!2rvGS}Y&Kd0so(YH=AmiuT}m4j5x%SQ$dm54J7G{QAm&j(`k-TsXdI*O;nMhNNwM~ zKXe#izvlLmPMDZP6#|v@MG9k55(rFS2vXs8P~`r(JS5di(_bth9ejb&1w#ZC)ElGA zfsh+QEnBt0)wL|2y=~Tai+n%kfT?epZTV#Vn-S|1_AC=y-cVBdD-%9VRATC|8H z!NlV3FxcnvnkH?d&j%ZyG`tFDb^{-Lrqm;;Ey+X_ilnD*Nwu4&#C5-Sk<144bHThA z9!53r-T?~yID-Tr1_%T)kec8MCg#dBX?P%9w`KmuCAMAG!$cvOugJtFIQ1!6Z_NFj ztowuWH-;JaA4oEafvuvj!{@2(i_|tIg*IH1#??02j-TY;u3yZEjJCG3LmpAqQ@Wur z@Zg}AD2s!6sW}qRph^hG6qp$!{cz|$5{QRjtM)}&;7dzAs_K9kBz{zwyBTVtU0iR1 z1Ef91q1H)%(h%d)2A~Wd@n*pYB6@B6(&mpItd=fgOnX&+cWJt~R+K8~j>%7xQAi!5 zV;Iu99T20fLdhnF0L!`gJ^U-%?OWYO_v>O1q>4$ny-Ssve2)f)RN=MY#(7@vx~KfC4xjImQl%@R zrb$Hx8rVSkkaRp2B;tzveX#RnsVkCU$rgbdY}lOV*EucA29L|FAR$2xo(kuLSYmHtwB<<{l81#$3kH5!%jrlzF#`=wCVesU zE?L*Mzb|dXh?J0iaWFO5A&7FbY!43yc=hLQofGp4q})8;dwSM~;l==cW-h%OOlS0pPzSWdsV4vgl$FigSs~aes#JJ z%-IfcY-jDQaTlCqrW4A#<en;orhG)xI=)MI+sa)ls|7Ob zufWwMawQ?&MkaRju^L6fcq4yf9Fxv2JKK~wpnlyz#pWm=)lU7f-H*0TCf=&t0O>}# zz3OaHMy>Q2BSsVx)lrB5))#`0#@Ko`>WP?J=d|PtXH&;b*od#9zuRQq-Lx zxGc&(y%}1Mwm#5215ZMk*T69BuD-yqdt{;d?L1^7?IoqU$SkK}90^be(P9=So4zeQ z5ttXAWt>Skx_7Ux2?QlhnJvSqUzb2_*&BZlFQK@+}PeqLUSBl36N zh;`b2e?y=fg%LM{)D8!KN2#tYQWC?qQ$@M*xSNj3bWPXud`Q_mJ9C!#g?U0q-dm&; zN6kz$r=Vg_q2yP*UZ=91ROTU|P&b;$a@)+-th3ykED$l9PMi{7M+xiSo9C zl7=Zj00w{tAP8>*hL=#I-!VOD`;Y05ZfTxiiUb`&i!<|j?zv~jbw4iiG>+yOcr7WI z?U|XUEX>TZ|4@D}*8((itW|$P8&hHp}U+fL-Xy30Zv3WNz{i?iX zy-ljQzG$9-*OG$4zE%@7Jk8TQ&C@*1(>%@7 jJk8TQ&C@*HIO+cbS{)R~qVw8700000NkvXXu0mjf+qO%i literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification_icon.png b/app/src/main/res/drawable-xxhdpi/ic_notification_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..95cc94cd49343ca18e4e62510744378603b4f2ef GIT binary patch literal 1773 zcmV*sf10Ax}3R-lv{{qYX2a*)9oph+x$*>i`^4Lx8Kj38Q z($wl7P(*v9h+Vo`S(+FTd3o<>N~HMnNQ$NueE{3CbRv0QzI*T9yCcAY1q&7|$c|?9 z3=XRt4wfH41~8Z>_HV6$%FizU8-QV~!ed>B6qF!u8d@1XQP)G;aO|9Ebfr6|n(K~x zUIta&!@paQf_w!!{AvZjIK@|5Xglhos_OW=0x~dm2gP+#hvuyl*nZi8geZ^~PpX^1 zOf-L{#r%dQtSv4_*p|bZ=Y5m!K??E_=x})tOlV^V;&&K$7aIB?cJsHT72o$6iq=Hm zl#uBQ)LcHot89QYtSi-A_@4l{c?1cWo(~evSUCgERuX-m8BgWfd;E{{!xa(scVD$2 zj3>+Y!Nj&Ee~qHHC`e2v%-FH7VPxevBV)b)YC;V%Nf(mI9a617fEs0 zFR=UaB)OBOv_XO2@kF*}d*wp>gy5r>EtD2ucqUosPi2=_r0sXkzFh+qq%0vFYA zW`|_rQ2T4>K1^fFuf*$bL3V*_c1SJ`wWp$*RloM&wxHQc8*I{v<7{u|X%5B~M9x@z z;R6+i@Tp&07BqX2ipW+Rn+YpYgg7PjMTX)GM8Tb5?S^w5ro(i^AttOy0kxD}+CUdV z1*x4^tFYaxVGXzf2Hufug_@o?1UYPq;G=(O9XlJW3nys)#7%9qIx1?$F)l9dIi@Af z7#(l)DpelQNoR6*+v37$xYFhUFkgs-R#p3A%J2|NoJ(d+487#!B@Us%HAUo{3J$Lm zNR4qU{wQk0o3CLRmX=&>k&+F!JjJ=ZY<8c%ufRvR{=;AZY1q*%%Lpo*Gj@bEq)j1` zDJ@d|;#ic)iWG6toM&J~0HH!N9EKzk`K0(FU6nYO*UUDpiK3xAg*4b}-yB1G=n0`E z9C$pDu2vlDpaV;w$2c)!5uFP?4!4HZ5+;1%ju@vCSgLi3LW*Nm>Ut6VTnW$k3{0iq)5dOhcJh2ce2{7o~N2L;yM!S_D)3S70QyC7SdV=!>9?7 z#KtO|8Wc$!YwEJ)E_ayx7}6l;h%x_DElb+@r;B1$3M3BtWkZZ8w*}FRcZid_bg75f z6(Kq;Ye_{B=hAxUh1-I%3HfeE%+!sDdDhsHiXqO(dI)btF>T1VAdyZ-!^i80C(%S& zQUr0xdK{%!uRv)-{usB98L|yXLq6iTtcUQgNv8|>PRf{{eIs6x@J7Nt%Xx`2VLgPu zK-8J^HJrAn4N=%19T%gNtVsEZQJ9K6R*vG(4Sm%21gPMJL-{O!V0EZh5f&H*b(%*EW9Oot%zo*lFy}stUvLYCu0P;$h47{4C9@Igi)c7e&3U(1OY~HYEz|PCa{wIXi|o!&YYIZzr#D+C|UK<3rX%H#mT3fo$wTJn_cpe5%*|wCJ=An!ozRV8(b4?~$JkJ{^!K P00000NkvXXu0mjfa9B1o literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification_setting.png b/app/src/main/res/drawable-xxhdpi/ic_notification_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..88f9121af3f92ca1ca7de0942fca20563b8ff518 GIT binary patch literal 873 zcmV-v1D5=WP)r3(!VO@( zjAITDEuTO0x!HbCd4MMPJ$MPhOo8jnygq@aF~$Ct3p+1mYI(vnF+F1JItq1k3z@Ct1>z4aPsQ z0VoSTHUUQ?2NRI4z@s)d>UE91s3!BxY4c60Y3z69v>MI^B)*A$Q%JC2Aa+4v z)qw3+{Z7DuN-oYqeRz!!EHLf2ky{1wj{B`+=p_0jg=q zqE=LOJR@})pyESbIbRk1SxX}S8o}c=93Pu&7yxsFOS~r~PTC0GhR=QwAC}~UlB-N$ zSQ3}!xdxnFiM)7D+d9RuFQ^9^fR>a0UAWX#H5&tuRl+T!00000NkvXXu0mjfymN_u literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_notification_warning.png b/app/src/main/res/drawable-xxhdpi/ic_notification_warning.png new file mode 100755 index 0000000000000000000000000000000000000000..c955ea9f26ccc958e58e3938cdb5cb5f7284cba4 GIT binary patch literal 1104 zcmV-W1h4yvP)WjdZDOkVAKzQyr z=YsM{eh~UYglJ)5VPPQ}04gYUv~Z4;lH#~rBw;jaF);jQ+ClHSzulD97e5Q*Fl0B zY0KMn>)B&oL(W+&(^E+!njn*CS4r2D!w9{n2_diJ{5GUJK8%A|(zWF=h=FrSW0BLpHiW<~zebnTZezL-uwQN&S`L$45)|54Hwg4M#J;4E zW3{qaAr1m3NulCX$YC-YL9uEP*P5*sw}2n1#}&jB%HXn-k80#RBdrdGRu@BQvQ z6lw$7f|ly(?a?f<2Ka7@6iO+UlH~iT+Vd1r3YKCO$)W<^Em)TIGc#G?(e$HDiWr3= zV&sPrjToKgn^XKJNg;qhCYgCI(CYe^>pxKhNEJd`(ozXZOp;08P{^Bi!xqIT8QJ_y zzCe)UBIpfDwnAa1v z@3p}mvnLmK5di8FUbo~>zj*zOCyRgx2{nbws*H_;nxKUORZH@EutH&;oQ(U zI^K7jCO(>=#nX#)=(+gVEQoH)*fQ z66Z`Y@a{mJ2sRL5aV(T&Bt?^%Y>QAtw>g&JCbJ`1*W)k#eL*jGUs6zbmu(F1Z106> z6hj~a%-=0jK!Dk`aG{MqN14RCQt35pPz-_D_rKlmcnl(3d~h+8HQ1PznPMtaQxrpH zKACY90l*Suh#)X21J}?fW*|c#MY@3+0+z>sPwCFa9g+^CK8B~#6a&0ui1}aUDGHzgi$fuWn{QSn+8N?i z=@mtRa1Dw92##(d;O1qe$!2t1h*lW_!7*wPfK(xn_eb9!^?W`AXm^HiBO#{iNQe^< zp*Gk({Oe)M^HDUp0RbY(5Dq{CCgv=K1i8OfgqdT_t3odWDH)9yuRsH4nO1>9F#5r$ z=o;0gy~DkS>DsAlj$(Mp5Mc*WzArCrD4wixz}+pRV?=AX>BT?By1Y3kAOquf7O;Mp%b|LxH8f1V2$aiUl4r4xN8 zgcxT&KI8g5$PoAcyic8gne1E9#U8#nyu-~SRH==$dHJ);6aQ@ZJgCOEb#iCWbRUh!ka1Wb_4<|$| z(F~cbwxHN@d2%HKMJBNIg? zi5ejSzjiMRSUk1!g&52j>Lxc4?f?<^wR<_=^K%XEUj;5krYpqYL0-fJk0JnH4|pnK z48=LMB1MYj2tJoS243!n8T>qeV$o}gVt|NYybuh!WIFI8KNKdyRV*uXn=dS|0)8#& zFzd$UEr~YNIX+mMq&5-uu+7Rft-*}VL1Ook{G|G$MM z^V(Nyd5VC@gs4SSr+d>FHU85FVYnMP|04~{DppeT7M{YDOXa-Gzq}j&0|egj2HXwQ Q=Kufz07*qoM6N<$g3?y{6aWAK literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/small_red_cross.png b/app/src/main/res/drawable-xxhdpi/small_red_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..4db4b69452e7a76c4047463c7fc6fe771a051def GIT binary patch literal 1561 zcmV+!2Il#RP)?er)1g>}4*?p-R!b48<8nQt|;ZXKhK#tbLNa4RKP>PZ2)aK z{rFPO5xkn}7{!y4->u66V&@D(gz zR0#Ftx8#OzqkQAj@I|=*dh3A&8NrAU6krk9Mey`1LvFrrN{~`QoXS%dAKq0K@X9bD z$izZC1~%nzANE|JD4sl&o^-5zOh92Fro{@|(?|6MhjO}#>Bf5w zbc(o&wh-S)<7mP${nO@m^l$bw8W@o{ZffA zijLMT4y|i&)I)Oy-S7 ztgRy<)Hu5hL%h4Y3-`Xc{&q#K#cP^^nX_nYu@Ih^vY7J>)g<@u{axlP;oeuszOP}OjlZNGqp(Dc6g9H2^f6EZQX*nv_ za0)}zRYR_2G=ySNG>R8x$#wC;;bE=_p17Jxr2THKW;lvu8^KUqfB+H-(I+kEs z1oA>=rF4xpEWjJi6XT=PQ(u5kgoYf`uq6T!5mp&TtiTfCji>eS4JAN$o`y{k2-jmN zgbR!4h>-<@r{5BWWRu9qu|n6do`$0sPxkjwlqy6ZB1E(Pr7Vb`0{(vR0FLAM@q`Xl ziJ=%OP2IXS_?@-p7Oc{B5U44;3!dlywwLxpg3Xl~>Ov5Zica{3O_R3=0iJ2W&J z7>*`Yia{YfSf+>wAytaOG9?O8Xw|qVI`fM(LNT(!brVP&F|cY8IwEj%$V#+SA%+NX z&VcG17SIvl7fG=E5lOJ5rQ*VgT;A+`-j7HJ}kT}MLlybO5W?6v@& zlvvtCTqTvWQ~ppAv$6#wOS|(t9f~h zrt?d?N77TG2+S`&o3OX1n=oq~?{f@I%6zxr$tc7YWs1*}<5!LOZCMcrEhC=at3EL#;_2p(GvmyCA5rqbJGpcykFd}cWK;WaNj z4<=yQ@+ZJf35zbM^TOgprOcp<72f0L@Fqg7bXWxgU3D{`+SW>js_4(60$ z%65jt43(-nn@1PfPus@eqd4w`29lG9u5aN z%y4CX2p{NL-gbrDEHmH9e*Hnh_D6yv$?Ei>gNp6*@^qP?!MuKWzM zAqF2@r^pWCLJK_Ws^`UY53T$4g8R8hZfBW>s^Fidx@|uYoOH|d#7llMbL-Rmh6d7n z2A~zR%Iq7T*dn5E)+#sBH8F)R!qjYujuR2&3)pj+0kdf@5@wKPFe*e8R`ZJ6Y#I`U z{(rzE^Jj+FVM4445k*C(E`ka^7O(L<^B-x*>zu1_T!31yV95Rt4VwKo!dcdW(JQE%u=(&`Xmii1GxnfyAy)mQR7@09H=z&GHjCITa`h z*m(lm=SGg6pm8oSikM_)mL~PJBzMVOiM00z2$n3868|&1J3IR!0E@+9u~;lqfq`Y5 zm$e!&XN5lx{5EX#dSD1^01-R&LkM8$>eV@X_U=QocMb+{z%tBkZFWF>VixXPl?DTp zw*)j%h_CVHW%&<1Rfm^u*B_xO2P6MI2hUqHQ5D^SGO{zjgq80BdZN4mX7JIPYr@*u z78HR6O9H=~1=rogzfVCk<*R~T%{_x4I8+iphBbM~DTMPd;f+S<7l~tM)j$WXe+Wfj?198V3$Q(>Ei9d082YOI1iikUudz+w zvv)Ul6+|V`bw5ZRt=2gUqqJn!z)Thl24t+`FCE;?GpFG^PZKa70m zjP5mz>Xvv(r*?$yy)}1CZQtY#(5mn8aM1)a&NIkQcKtsHW6v@}UJ^g?Ua=}eBTlXg zqAxqc>w6VX%R>(zN9b{H!S_z2d#|neD2B1iX8r$n!-xCuOpO9~aDbfM|`1*^_wu*_5#*-AEkTXCO>0EcX`0tzX>pbF< z@gnhQl2-=l9WiQbfBE)z{1VqY(jjz-KX^W4f56Z8dhplB)1=dq+kiN&V0-{&`j`;E ze|`_gj~A1wBykngk94f~ndfIV*tN9r#&JkW` zIeLi(s0UyY^74)MNAYX&06s?&4Kp}#iq>X*F%KRLN>E)FRWGi)l-ka4BT%*#^ckVN;)gJ{8P1NTq8|kM zOF;mi`X2^QGLL6iU5y$cuVa*5{1Dzb3;O|{^9FR|z{mKxFDWF0HXrmM$OwU>ZiH%x zAHvv^&;Zm>GORMRGBDNK31ru9VG0CC+#(~a{d1yZger-DML!pG$%-v-9s|QkzU&jZ z<#!b7^w0>=xnzV(Sj{}Eg5qP%aN0LOSPJwu#^LJnFvL`ASZ8^N8W~{&J8@phD)lOg zPq?f-oDKDZ*Pxe1f#{|-W`ux^mxQW{Piva7Gd64h6CtT6y2)#V_4jQqctmBzr_T=8 zO^gr7wC3;)R%Ef8n1Swhj_EDK!+P8EP5!sC;^Y0Sckk2FaRa=>T#XwPTktFf#lwh( z8dXBs2v}r4CrtOKlKA20H}La$-%C6wKfGgDMeCA;zwi+=$InI`w6)=AcE4sEM@mt-r%sO zg*-kBp1|`T;8*{IH+ZD9q4xIt3VwgB`+la7TK7k&8GvZj8$3K53QYs5Yxm*evTbUg zeQjhpkuF4AnF&xgz#tT5=-M`Zl9)Gwl=l`@w16dwSAB|#D2 z3`b)R0g(UVv3L+5%49N`OeV7k50tq9Kw*FO=Re;b9v;3?WD9=UTmjeZ2<9O?d`$${BzUW^F zBdET%;ZFl`mvqnA7kouHlMP_Q79(+2bdR8J_$q{Rq5y38XNNROipVdtFsOZQ7Otdl z{-H3Q9qxIhh%9OVEB=%H;bL7-973yz-yH6Fvd_JzwPRmmhiRV95R&zO6R*x0YOk)c zmpT9LXi4k?93Vr80bJ_;Cdx71Lr?esD5L2-_o+Zp2#?mMns zRF^hnZQ?T@)JimVV?5@D4#D>pjz&-`6rU;E22hAkhC2jI|E6tcj(20o8_%Bg}Y-7x@fgd~4 zjbQ|xkoX2uS4>03C1rQA97$JWIyxco8AVe;+)}`8it}z$m}Uf>nD_=BySDTR5u-8Y zNg3~A2)~sQx)rv7ydyD2_F~N9MWFWk~FKVZNm(joYz99TEQ7AHd zO`l)9!maRZoaFb}hx`!Bg@U9(T`jEcaDy3)u#KJ8L% + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_circular_dark_cerulean_1.xml b/app/src/main/res/drawable/background_circular_dark_cerulean_1.xml new file mode 100644 index 0000000..a7cf7e9 --- /dev/null +++ b/app/src/main/res/drawable/background_circular_dark_cerulean_1.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_circular_dark_cerulean_4.xml b/app/src/main/res/drawable/background_circular_dark_cerulean_4.xml new file mode 100644 index 0000000..21848e7 --- /dev/null +++ b/app/src/main/res/drawable/background_circular_dark_cerulean_4.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_circular_green.xml b/app/src/main/res/drawable/background_circular_green.xml new file mode 100644 index 0000000..c287a3d --- /dev/null +++ b/app/src/main/res/drawable/background_circular_green.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_light_green.xml b/app/src/main/res/drawable/background_light_green.xml new file mode 100644 index 0000000..c39b180 --- /dev/null +++ b/app/src/main/res/drawable/background_light_green.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/default_button_selector.xml b/app/src/main/res/drawable/default_button_selector.xml new file mode 100644 index 0000000..06ef114 --- /dev/null +++ b/app/src/main/res/drawable/default_button_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_text_black_background.xml b/app/src/main/res/drawable/edit_text_black_background.xml new file mode 100644 index 0000000..f814a20 --- /dev/null +++ b/app/src/main/res/drawable/edit_text_black_background.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edit_text_green_background.xml b/app/src/main/res/drawable/edit_text_green_background.xml new file mode 100644 index 0000000..9adef1a --- /dev/null +++ b/app/src/main/res/drawable/edit_text_green_background.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/edittext_modified_states.xml b/app/src/main/res/drawable/edittext_modified_states.xml new file mode 100644 index 0000000..3a677e1 --- /dev/null +++ b/app/src/main/res/drawable/edittext_modified_states.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/green_button_background.xml b/app/src/main/res/drawable/green_button_background.xml new file mode 100644 index 0000000..03cd68d --- /dev/null +++ b/app/src/main/res/drawable/green_button_background.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/grey_button_background.xml b/app/src/main/res/drawable/grey_button_background.xml new file mode 100644 index 0000000..297bba2 --- /dev/null +++ b/app/src/main/res/drawable/grey_button_background.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_arrow_drop_down.xml b/app/src/main/res/drawable/ic_arrow_drop_down.xml new file mode 100644 index 0000000..b571455 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_down.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml new file mode 100644 index 0000000..cf9e208 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_forward_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_check.xml b/app/src/main/res/drawable/ic_check.xml new file mode 100644 index 0000000..2505846 --- /dev/null +++ b/app/src/main/res/drawable/ic_check.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_chevron_right.xml b/app/src/main/res/drawable/ic_chevron_right.xml new file mode 100644 index 0000000..125885a --- /dev/null +++ b/app/src/main/res/drawable/ic_chevron_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml new file mode 100644 index 0000000..55c4d27 --- /dev/null +++ b/app/src/main/res/drawable/ic_close.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete_black_24dp.xml new file mode 100644 index 0000000..39e64d6 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_doctor_circle.xml b/app/src/main/res/drawable/ic_doctor_circle.xml new file mode 100644 index 0000000..8b78a18 --- /dev/null +++ b/app/src/main/res/drawable/ic_doctor_circle.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_ellipse.xml b/app/src/main/res/drawable/ic_ellipse.xml new file mode 100644 index 0000000..44585f1 --- /dev/null +++ b/app/src/main/res/drawable/ic_ellipse.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_help_outline_black.xml b/app/src/main/res/drawable/ic_help_outline_black.xml new file mode 100644 index 0000000..ab6f7c8 --- /dev/null +++ b/app/src/main/res/drawable/ic_help_outline_black.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_help_outline_white.xml b/app/src/main/res/drawable/ic_help_outline_white.xml new file mode 100644 index 0000000..ec5ea13 --- /dev/null +++ b/app/src/main/res/drawable/ic_help_outline_white.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_help_stop_covid.xml b/app/src/main/res/drawable/ic_help_stop_covid.xml new file mode 100644 index 0000000..edc824e --- /dev/null +++ b/app/src/main/res/drawable/ic_help_stop_covid.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_home_logo.xml b/app/src/main/res/drawable/ic_home_logo.xml new file mode 100644 index 0000000..1fae9cb --- /dev/null +++ b/app/src/main/res/drawable/ic_home_logo.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_home_share.xml b/app/src/main/res/drawable/ic_home_share.xml new file mode 100644 index 0000000..a2dd419 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_share.xml @@ -0,0 +1,41 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_home_unprotected.xml b/app/src/main/res/drawable/ic_home_unprotected.xml new file mode 100644 index 0000000..25c0e0a --- /dev/null +++ b/app/src/main/res/drawable/ic_home_unprotected.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_how_it_works.xml b/app/src/main/res/drawable/ic_how_it_works.xml new file mode 100644 index 0000000..e946d81 --- /dev/null +++ b/app/src/main/res/drawable/ic_how_it_works.xml @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_illustration_upload_inital_state.xml b/app/src/main/res/drawable/ic_illustration_upload_inital_state.xml new file mode 100644 index 0000000..6cf1d0e --- /dev/null +++ b/app/src/main/res/drawable/ic_illustration_upload_inital_state.xml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_illustration_upload_step_4.xml b/app/src/main/res/drawable/ic_illustration_upload_step_4.xml new file mode 100644 index 0000000..feeca9e --- /dev/null +++ b/app/src/main/res/drawable/ic_illustration_upload_step_4.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml new file mode 100644 index 0000000..8e1ea6e --- /dev/null +++ b/app/src/main/res/drawable/ic_info.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_intro_picture.xml b/app/src/main/res/drawable/ic_intro_picture.xml new file mode 100644 index 0000000..c385fde --- /dev/null +++ b/app/src/main/res/drawable/ic_intro_picture.xml @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..3700fd0 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,16 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..d552f8c --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_round.xml b/app/src/main/res/drawable/ic_launcher_round.xml new file mode 100644 index 0000000..9aa50ee --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_round.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_logo_home_inactive.xml b/app/src/main/res/drawable/ic_logo_home_inactive.xml new file mode 100644 index 0000000..54fc727 --- /dev/null +++ b/app/src/main/res/drawable/ic_logo_home_inactive.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_logo_home_uploaded.xml b/app/src/main/res/drawable/ic_logo_home_uploaded.xml new file mode 100644 index 0000000..59a3c6c --- /dev/null +++ b/app/src/main/res/drawable/ic_logo_home_uploaded.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_permission.xml b/app/src/main/res/drawable/ic_permission.xml new file mode 100644 index 0000000..8a4ee92 --- /dev/null +++ b/app/src/main/res/drawable/ic_permission.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_permission_success.xml b/app/src/main/res/drawable/ic_permission_success.xml new file mode 100644 index 0000000..ac083f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_permission_success.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_personal_details.xml b/app/src/main/res/drawable/ic_personal_details.xml new file mode 100644 index 0000000..5b28ddf --- /dev/null +++ b/app/src/main/res/drawable/ic_personal_details.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_phone_checked_circle.xml b/app/src/main/res/drawable/ic_phone_checked_circle.xml new file mode 100644 index 0000000..bb41493 --- /dev/null +++ b/app/src/main/res/drawable/ic_phone_checked_circle.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_play_arrow_black_24dp.xml b/app/src/main/res/drawable/ic_play_arrow_black_24dp.xml new file mode 100644 index 0000000..bf9b895 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_arrow_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_privacy.xml b/app/src/main/res/drawable/ic_privacy.xml new file mode 100644 index 0000000..2def57b --- /dev/null +++ b/app/src/main/res/drawable/ic_privacy.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_smartphone.xml b/app/src/main/res/drawable/ic_smartphone.xml new file mode 100644 index 0000000..51ad6a1 --- /dev/null +++ b/app/src/main/res/drawable/ic_smartphone.xml @@ -0,0 +1,20 @@ + + + + diff --git a/app/src/main/res/drawable/ic_smile.xml b/app/src/main/res/drawable/ic_smile.xml new file mode 100644 index 0000000..f7c1170 --- /dev/null +++ b/app/src/main/res/drawable/ic_smile.xml @@ -0,0 +1,34 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_splash_screen_logo.xml b/app/src/main/res/drawable/ic_splash_screen_logo.xml new file mode 100644 index 0000000..ec26a0d --- /dev/null +++ b/app/src/main/res/drawable/ic_splash_screen_logo.xml @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_splash_screen_title.xml b/app/src/main/res/drawable/ic_splash_screen_title.xml new file mode 100644 index 0000000..e1ede1b --- /dev/null +++ b/app/src/main/res/drawable/ic_splash_screen_title.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_stop_black_24dp.xml b/app/src/main/res/drawable/ic_stop_black_24dp.xml new file mode 100644 index 0000000..c428d72 --- /dev/null +++ b/app/src/main/res/drawable/ic_stop_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_under_sixteen.xml b/app/src/main/res/drawable/ic_under_sixteen.xml new file mode 100644 index 0000000..695680a --- /dev/null +++ b/app/src/main/res/drawable/ic_under_sixteen.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_unfold_less_black_24dp.xml b/app/src/main/res/drawable/ic_unfold_less_black_24dp.xml new file mode 100644 index 0000000..7282a97 --- /dev/null +++ b/app/src/main/res/drawable/ic_unfold_less_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_unfold_more_black_24dp.xml b/app/src/main/res/drawable/ic_unfold_more_black_24dp.xml new file mode 100644 index 0000000..e9ba754 --- /dev/null +++ b/app/src/main/res/drawable/ic_unfold_more_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_up.xml b/app/src/main/res/drawable/ic_up.xml new file mode 100644 index 0000000..c1704dc --- /dev/null +++ b/app/src/main/res/drawable/ic_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_upload_error.xml b/app/src/main/res/drawable/ic_upload_error.xml new file mode 100644 index 0000000..5d6d3fd --- /dev/null +++ b/app/src/main/res/drawable/ic_upload_error.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_upload_failed.xml b/app/src/main/res/drawable/ic_upload_failed.xml new file mode 100644 index 0000000..8abcc84 --- /dev/null +++ b/app/src/main/res/drawable/ic_upload_failed.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_upload_icon.xml b/app/src/main/res/drawable/ic_upload_icon.xml new file mode 100644 index 0000000..2f808d9 --- /dev/null +++ b/app/src/main/res/drawable/ic_upload_icon.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/app/src/main/res/drawable/icon_checkbox.xml b/app/src/main/res/drawable/icon_checkbox.xml new file mode 100644 index 0000000..cc6ef6a --- /dev/null +++ b/app/src/main/res/drawable/icon_checkbox.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/illustration_data_uploaded.xml b/app/src/main/res/drawable/illustration_data_uploaded.xml new file mode 100644 index 0000000..f0e0ec5 --- /dev/null +++ b/app/src/main/res/drawable/illustration_data_uploaded.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/illustration_upload_finished.xml b/app/src/main/res/drawable/illustration_upload_finished.xml new file mode 100644 index 0000000..4c503f7 --- /dev/null +++ b/app/src/main/res/drawable/illustration_upload_finished.xml @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/outline_button_background.xml b/app/src/main/res/drawable/outline_button_background.xml new file mode 100644 index 0000000..f156edc --- /dev/null +++ b/app/src/main/res/drawable/outline_button_background.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/phone_number_invalid_background.xml b/app/src/main/res/drawable/phone_number_invalid_background.xml new file mode 100644 index 0000000..6a24df1 --- /dev/null +++ b/app/src/main/res/drawable/phone_number_invalid_background.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/progress_segment.xml b/app/src/main/res/drawable/progress_segment.xml new file mode 100644 index 0000000..4b52324 --- /dev/null +++ b/app/src/main/res/drawable/progress_segment.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/splash_screen_white_wave.xml b/app/src/main/res/drawable/splash_screen_white_wave.xml new file mode 100644 index 0000000..0b8abe5 --- /dev/null +++ b/app/src/main/res/drawable/splash_screen_white_wave.xml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/app/src/main/res/font/font_roboto_regular.xml b/app/src/main/res/font/font_roboto_regular.xml new file mode 100644 index 0000000..7ce3a40 --- /dev/null +++ b/app/src/main/res/font/font_roboto_regular.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/font/roboto_medium.ttf b/app/src/main/res/font/roboto_medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f714a514d94e495095e2f1e525a341eade187c17 GIT binary patch literal 171656 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 + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml new file mode 100644 index 0000000..4996935 --- /dev/null +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + +