From fd17df80a8772306c6bdf31086f357b22cb015e4 Mon Sep 17 00:00:00 2001 From: F7cloud Mobile Date: Tue, 7 Jul 2026 12:05:18 +0300 Subject: [PATCH] Initial import of f7cloud-mobile native Android app. Kotlin/Compose client for F7cloud (mail, files, talk, calendar, contacts, tasks, support). Current version: 0.5.113 (build 121). --- .gitignore | 26 + NOTICE.md | 22 + PROJECT-STATUS.md | 317 + README.md | 113 + app/build.gradle | 96 + app/google-services.json.example | 28 + app/proguard-rules.pro | 1 + app/src/main/AndroidManifest.xml | 71 + .../f7cloud/mobile/CallIncomingActivity.kt | 133 + .../ru/forbion/f7cloud/mobile/F7MobileApp.kt | 94 + .../f7cloud/mobile/IncomingCallScreen.kt | 183 + .../ru/forbion/f7cloud/mobile/MainActivity.kt | 131 + .../f7cloud/mobile/OfficeEditorActivity.kt | 425 + .../f7cloud/mobile/OfficeWebViewClient.kt | 132 + .../f7cloud/mobile/OfficeWebViewPool.kt | 67 + .../mobile/RichDocumentsMobileBridge.kt | 51 + .../mobile/navigation/AppLinkResolver.kt | 118 + .../mobile/permissions/F7AppPermissions.kt | 44 + .../mobile/permissions/F7PermissionDialog.kt | 45 + .../f7cloud/mobile/qr/F7QrScannerActivity.kt | 317 + .../forbion/f7cloud/mobile/ui/AppLockGate.kt | 704 + .../f7cloud/mobile/ui/AppMenuRepository.kt | 68 + .../f7cloud/mobile/ui/AppNavigation.kt | 79 + .../forbion/f7cloud/mobile/ui/AppScaffold.kt | 919 + .../ru/forbion/f7cloud/mobile/ui/AppSheets.kt | 259 + .../res/drawable-nodpi/f7_logo_reference.png | Bin 0 -> 2444 bytes .../main/res/drawable/f7_app_lock_logo.png | Bin 0 -> 3336 bytes app/src/main/res/drawable/ic_call_accept.xml | 10 + app/src/main/res/drawable/ic_call_decline.xml | 10 + .../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 -> 776 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 2265 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 483 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 1160 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1143 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 3510 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 2075 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 6979 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 3295 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 11794 bytes app/src/main/res/values/colors.xml | 4 + app/src/main/res/values/strings.xml | 15 + app/src/main/res/xml/shortcuts.xml | 15 + build.gradle | 13 + core/auth/build.gradle | 25 + core/auth/src/main/AndroidManifest.xml | 2 + .../forbion/f7cloud/core/auth/AppLockStore.kt | 102 + .../forbion/f7cloud/core/auth/AuthErrors.kt | 55 + .../forbion/f7cloud/core/auth/AuthSession.kt | 12 + .../ru/forbion/f7cloud/core/auth/AuthStore.kt | 34 + .../forbion/f7cloud/core/auth/AuthVerifier.kt | 47 + .../f7cloud/core/auth/OcsUserResolver.kt | 40 + core/data/build.gradle | 26 + core/data/src/main/AndroidManifest.xml | 2 + core/database/build.gradle | 27 + core/database/src/main/AndroidManifest.xml | 2 + .../f7cloud/core/database/ContactEntity.kt | 27 + .../f7cloud/core/database/ContactsDao.kt | 46 + .../f7cloud/core/database/F7Database.kt | 80 + .../f7cloud/core/database/FileEntity.kt | 14 + .../forbion/f7cloud/core/database/FilesDao.kt | 18 + core/designsystem/build.gradle | 35 + .../designsystem/src/main/AndroidManifest.xml | 2 + .../core/designsystem/AppForegroundTracker.kt | 15 + .../core/designsystem/F7AppMenuSheet.kt | 222 + .../core/designsystem/F7AutoHideBottomBar.kt | 72 + .../core/designsystem/F7BottomBarConfig.kt | 87 + .../f7cloud/core/designsystem/F7Colors.kt | 45 + .../f7cloud/core/designsystem/F7Components.kt | 585 + .../core/designsystem/F7FloatingPanel.kt | 90 + .../core/designsystem/F7MobileBottomBar.kt | 188 + .../core/designsystem/F7NotificationRow.kt | 141 + .../core/designsystem/F7OverlayNavigation.kt | 108 + .../core/designsystem/F7RelativeTime.kt | 34 + .../f7cloud/core/designsystem/F7Theme.kt | 37 + .../f7cloud/core/designsystem/F7Typography.kt | 27 + .../core/designsystem/F7WindowInsets.kt | 22 + .../src/main/res/font/raleway_medium.ttf | Bin 0 -> 164128 bytes .../src/main/res/font/raleway_semibold.ttf | Bin 0 -> 311856 bytes core/network/build.gradle | 26 + core/network/src/main/AndroidManifest.xml | 2 + .../core/network/BasicAuthInterceptor.kt | 17 + .../f7cloud/core/network/CalDavClient.kt | 1050 + .../f7cloud/core/network/CalendarIcs.kt | 276 + .../f7cloud/core/network/CardDavClient.kt | 441 + .../forbion/f7cloud/core/network/DavClient.kt | 300 + .../f7cloud/core/network/LoginFlowClient.kt | 255 + .../f7cloud/core/network/NetworkFactory.kt | 35 + .../core/network/NotificationsRepository.kt | 95 + .../forbion/f7cloud/core/network/OcsJson.kt | 51 + .../core/network/UnauthorizedException.kt | 3 + .../forbion/f7cloud/core/network/UnsafeSsl.kt | 25 + core/push/build.gradle | 28 + core/push/src/main/AndroidManifest.xml | 16 + .../f7cloud/core/push/F7CallActionReceiver.kt | 20 + .../core/push/F7FirebaseMessagingService.kt | 113 + .../f7cloud/core/push/F7IncomingCallQueue.kt | 448 + .../f7cloud/core/push/F7IncomingCallRinger.kt | 119 + .../core/push/F7NotificationChannels.kt | 72 + .../forbion/f7cloud/core/push/F7PushEvent.kt | 43 + .../f7cloud/core/push/F7PushEventHub.kt | 17 + .../f7cloud/core/push/F7PushEventParser.kt | 82 + .../f7cloud/core/push/F7PushIntentExtras.kt | 49 + .../core/push/F7PushNotificationHelper.kt | 63 + .../f7cloud/core/push/F7PushRegistrar.kt | 90 + .../forbion/f7cloud/core/push/PushIntents.kt | 13 + .../f7cloud/core/push/TalkCallPushLabels.kt | 32 + core/push/src/main/res/values/strings.xml | 14 + core/ui/build.gradle | 3 + design/README.md | 66 + design/icons/.gitkeep | 1 + design/references/figma-links.md | 10 + design/screens/.gitkeep | 1 + design/screens/ico/Ellipse 14.svg | 29 + design/screens/ico/Size=45, Name=Карточки.svg | 42 + design/screens/ico/Vector 181.svg | 3 + .../screens/ico/icon/35/Archive Zip rar.svg | 16 + design/screens/ico/icon/35/Audio.svg | 14 + design/screens/ico/icon/35/Calendar.svg | 31 + design/screens/ico/icon/35/Certificate.svg | 14 + design/screens/ico/icon/35/Code.svg | 13 + design/screens/ico/icon/35/Eml.svg | 15 + design/screens/ico/icon/35/Image.svg | 18 + design/screens/ico/icon/35/No name.svg | 13 + design/screens/ico/icon/35/PDF.svg | 13 + design/screens/ico/icon/35/Presentation.svg | 13 + design/screens/ico/icon/35/Spreadsheet.svg | 13 + design/screens/ico/icon/35/Text.svg | 13 + design/screens/ico/icon/35/Video.svg | 18 + design/screens/ico/icon/35/Word.svg | 13 + .../ico/icon/35/Колокол c оповещениями.svg | 54 + design/screens/ico/icon/35/колокол.svg | 48 + design/screens/ico/Вайд борд.svg | 16 + design/screens/ico/Карточки.svg | 17 + design/screens/mail/Заполненное.png | Bin 0 -> 31544 bytes design/screens/mail/Ответить на сообщение.png | Bin 0 -> 24995 bytes .../screens/mail/Параметры учётной записи.png | Bin 0 -> 204274 bytes .../mail/Параметры электронной почты.png | Bin 0 -> 107119 bytes design/screens/mail/Пересланные сообщения.png | Bin 0 -> 51813 bytes ...ообщения отправленное нескольким пользователям-1.png | Bin 0 -> 60188 bytes ...ообщения отправленное нескольким пользователям-2.png | Bin 0 -> 61983 bytes ...сообщения отправленное нескольким пользователям.png | Bin 0 -> 46229 bytes .../screens/mail/Почта _ Окно сообщения.png | Bin 0 -> 66483 bytes ...бщения с доп. строчками и открытыми настройками текста.png | Bin 0 -> 25752 bytes .../mail/Почта _ Создание сообщения.png | Bin 0 -> 20842 bytes .../screens/mail/Почта _ Список сообщений.png | Bin 0 -> 76945 bytes ...Прямой поиск ( с кнопками подсказками).png | Bin 0 -> 67601 bytes .../mail/Сообщение с перепиской закрытые.png | Bin 0 -> 58275 bytes .../mail/Сообщение с перепиской открытое.png | Bin 0 -> 80465 bytes .../mail/Список неотправленных сообщений.png | Bin 0 -> 39508 bytes design/screens/tasks/Задачи _ Завершенные.png | Bin 0 -> 38033 bytes design/screens/tasks/Задачи _ На неделе.png | Bin 0 -> 55981 bytes .../tasks/Задачи _ Сегодня _ Нажат плюс.png | Bin 0 -> 31470 bytes ...Задачи _ Список пуст с кнопкой удалить.png | Bin 0 -> 35771 bytes design/screens/tasks/Задачи _ Список пуст.png | Bin 0 -> 32842 bytes design/screens/tasks/Задачи _ Список.png | Bin 0 -> 48687 bytes .../tasks/Задачи _ Фильтровать по меткам.png | Bin 0 -> 50548 bytes design/screens/tasks/Параметры задач.png | Bin 0 -> 23117 bytes .../screens/tasks/Правая панель заметки.png | Bin 0 -> 26851 bytes .../Правая панель свойства заполненная-1.png | Bin 0 -> 52221 bytes .../Правая панель свойства заполненная.png | Bin 0 -> 57382 bytes .../Правая панель свойства незаполненная.png | Bin 0 -> 47078 bytes design/tokens/colors.txt | 11 + design/tokens/typography.txt | 9 + feature/calendar/build.gradle | 41 + feature/calendar/src/main/AndroidManifest.xml | 2 + .../feature/calendar/CalendarApiClient.kt | 163 + .../feature/calendar/CalendarComponents.kt | 1362 + .../feature/calendar/CalendarExtendedUi.kt | 290 + .../feature/calendar/CalendarModels.kt | 101 + .../feature/calendar/CalendarPrefsStore.kt | 63 + .../feature/calendar/CalendarRepository.kt | 446 + .../feature/calendar/CalendarScreen.kt | 471 + .../feature/calendar/CalendarSyncEngine.kt | 212 + .../feature/calendar/CalendarSyncStore.kt | 86 + .../feature/calendar/CalendarViewModel.kt | 645 + .../feature/calendar/DeviceCalendarClient.kt | 207 + feature/contacts/build.gradle | 40 + feature/contacts/src/main/AndroidManifest.xml | 2 + .../feature/contacts/ContactDetailSheet.kt | 290 + .../contacts/ContactRecipientHelper.kt | 29 + .../feature/contacts/ContactsRepository.kt | 218 + .../feature/contacts/ContactsScreen.kt | 351 + .../feature/contacts/ContactsViewModel.kt | 188 + feature/deck/build.gradle | 38 + feature/deck/src/main/AndroidManifest.xml | 2 + .../f7cloud/feature/deck/DeckRepository.kt | 121 + .../f7cloud/feature/deck/DeckScreen.kt | 82 + .../f7cloud/feature/deck/DeckViewModel.kt | 87 + feature/f7support/build.gradle | 41 + .../f7support/src/main/AndroidManifest.xml | 2 + .../feature/f7support/SupportComponents.kt | 1016 + .../feature/f7support/SupportFileIO.kt | 68 + .../feature/f7support/SupportRepository.kt | 420 + .../feature/f7support/SupportScreen.kt | 163 + .../feature/f7support/SupportViewModel.kt | 384 + feature/files/build.gradle | 45 + feature/files/src/main/AndroidManifest.xml | 21 + .../f7cloud/feature/files/ArchiveFiles.kt | 33 + .../f7cloud/feature/files/F7FileProvider.kt | 6 + .../feature/files/FileDownloadRepository.kt | 40 + .../f7cloud/feature/files/FileIcons.kt | 27 + .../forbion/f7cloud/feature/files/FileItem.kt | 12 + .../f7cloud/feature/files/FileOpenAction.kt | 6 + .../feature/files/FilesApiRepository.kt | 303 + .../f7cloud/feature/files/FilesComponents.kt | 1457 + .../f7cloud/feature/files/FilesCreateMenu.kt | 224 + .../f7cloud/feature/files/FilesModels.kt | 148 + .../f7cloud/feature/files/FilesRepository.kt | 170 + .../f7cloud/feature/files/FilesScreen.kt | 432 + .../feature/files/FilesTemplatesRepository.kt | 105 + .../f7cloud/feature/files/FilesUiState.kt | 40 + .../f7cloud/feature/files/FilesViewModel.kt | 814 + .../feature/files/ImageViewerActivity.kt | 98 + .../f7cloud/feature/files/LocalFileOpener.kt | 27 + .../f7cloud/feature/files/OfficeFileLinks.kt | 31 + .../f7cloud/feature/files/OfficeFileOpener.kt | 28 + .../f7cloud/feature/files/OfficeFiles.kt | 16 + .../f7cloud/feature/files/OfficeWarmup.kt | 92 + .../f7cloud/feature/files/OpenableFiles.kt | 26 + .../feature/files/RichdocumentsRepository.kt | 79 + .../files/src/main/res/xml/f7_file_paths.xml | 4 + feature/mail/build.gradle | 44 + feature/mail/src/main/AndroidManifest.xml | 18 + .../f7cloud/feature/mail/MailAttachmentIO.kt | 28 + .../feature/mail/MailBackNavigation.kt | 107 + .../f7cloud/feature/mail/MailBodyHtml.kt | 178 + .../feature/mail/MailCacheRepository.kt | 381 + .../f7cloud/feature/mail/MailComponents.kt | 1898 ++ .../feature/mail/MailComposeActivity.kt | 136 + .../f7cloud/feature/mail/MailComposeLaunch.kt | 51 + .../feature/mail/MailComposeSchedule.kt | 85 + .../f7cloud/feature/mail/MailComposeScreen.kt | 889 + .../feature/mail/MailComposeViewModel.kt | 396 + .../feature/mail/MailFilesPickerActivity.kt | 262 + .../feature/mail/MailMessageBodyView.kt | 153 + .../f7cloud/feature/mail/MailModels.kt | 332 + .../feature/mail/MailRecipientComposeField.kt | 109 + .../f7cloud/feature/mail/MailReplyHelper.kt | 121 + .../f7cloud/feature/mail/MailRepository.kt | 991 + .../feature/mail/MailRichTextEditor.kt | 159 + .../f7cloud/feature/mail/MailScreen.kt | 943 + .../feature/mail/MailSettingsScreens.kt | 774 + .../f7cloud/feature/mail/MailViewModel.kt | 1012 + .../f7cloud/feature/mail/MailWebBranding.kt | 31 + feature/talk-native/build.gradle | 29 + .../talk-native/src/main/AndroidManifest.xml | 2 + .../feature/talknative/TalkAuthBridge.kt | 28 + .../talknative/TalkNativeCallContext.kt | 12 + .../talknative/TalkNativeCallLauncher.kt | 190 + .../feature/talknative/TalkNativeConfig.kt | 21 + .../feature/talknative/TalkNativeFacade.kt | 16 + .../feature/talknative/TalkPushBridge.kt | 34 + .../feature/talknative/TalkVendorBootstrap.kt | 27 + .../feature/talknative/TalkVendorUserSync.kt | 36 + feature/talk/build.gradle | 47 + feature/talk/src/main/AndroidManifest.xml | 29 + .../src/main/assets/f7_talk_direct_join.js | 320 + .../f7cloud/feature/talk/F7CallWakeLock.kt | 51 + .../f7cloud/feature/talk/TalkAssets.kt | 17 + .../feature/talk/TalkAttachmentUploader.kt | 203 + .../f7cloud/feature/talk/TalkCallActivity.kt | 453 + .../f7cloud/feature/talk/TalkComponents.kt | 1591 + .../f7cloud/feature/talk/TalkDeepLink.kt | 32 + .../f7cloud/feature/talk/TalkFilters.kt | 15 + .../f7cloud/feature/talk/TalkFormatting.kt | 185 + .../f7cloud/feature/talk/TalkHelper.kt | 155 + .../f7cloud/feature/talk/TalkMention.kt | 27 + .../f7cloud/feature/talk/TalkMessage.kt | 32 + .../feature/talk/TalkMessageParameter.kt | 7 + .../f7cloud/feature/talk/TalkOfflineDao.kt | 24 + .../feature/talk/TalkOfflineDatabase.kt | 38 + .../feature/talk/TalkOfflineEntities.kt | 31 + .../feature/talk/TalkOfflineRepository.kt | 131 + .../f7cloud/feature/talk/TalkParticipant.kt | 40 + .../f7cloud/feature/talk/TalkRepository.kt | 511 + .../forbion/f7cloud/feature/talk/TalkRoom.kt | 19 + .../f7cloud/feature/talk/TalkRoomInfoSheet.kt | 155 + .../f7cloud/feature/talk/TalkScreen.kt | 663 + .../f7cloud/feature/talk/TalkShareActivity.kt | 14 + .../f7cloud/feature/talk/TalkShareTarget.kt | 26 + .../forbion/f7cloud/feature/talk/TalkUrls.kt | 22 + .../f7cloud/feature/talk/TalkViewModel.kt | 753 + .../f7cloud/feature/talk/TalkVoiceRecorder.kt | 52 + .../f7cloud/feature/talk/TalkWebBranding.kt | 22 + feature/tasks/build.gradle | 39 + feature/tasks/src/main/AndroidManifest.xml | 2 + .../f7cloud/feature/tasks/TasksComponents.kt | 1066 + .../f7cloud/feature/tasks/TasksGrouping.kt | 78 + .../f7cloud/feature/tasks/TasksRepository.kt | 216 + .../f7cloud/feature/tasks/TasksScreen.kt | 234 + .../f7cloud/feature/tasks/TasksViewModel.kt | 371 + feature/widgets/build.gradle | 41 + feature/widgets/src/main/AndroidManifest.xml | 2 + .../feature/widgets/WidgetsRepository.kt | 271 + .../f7cloud/feature/widgets/WidgetsScreen.kt | 176 + .../f7cloud/feature/widgets/WidgetsUiState.kt | 12 + .../feature/widgets/WidgetsViewModel.kt | 79 + gradle.properties | 12 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 46175 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 248 + gradlew.bat | 93 + settings.gradle | 38 + vendor/talk-android/.devcontainer/Dockerfile | 16 + .../.devcontainer/Dockerfile.license | 2 + vendor/talk-android/.devcontainer/README.md | 9 + .../.devcontainer/devcontainer.env | 3 + .../.devcontainer/devcontainer.env.license | 2 + .../.devcontainer/devcontainer.json | 4 + .../.devcontainer/devcontainer.json.license | 2 + vendor/talk-android/.drone.yml | 86 + vendor/talk-android/.editorconfig | 54 + vendor/talk-android/.github/FUNDING.yml | 4 + .../.github/ISSUE_TEMPLATE/bug_report.yml | 130 + .../ISSUE_TEMPLATE/bug_report.yml.license | 3 + .../.github/ISSUE_TEMPLATE/config.yml | 9 + .../.github/ISSUE_TEMPLATE/feature_request.md | 20 + .../ISSUE_TEMPLATE/feature_request.md.license | 3 + vendor/talk-android/.github/no-response.yml | 16 + .../.github/pull_request_template.md | 18 + .../.github/pull_request_template.md.license | 3 + .../.github/workflows/QA_keystore.jks.license | 2 + .../.github/workflows/analysis.yml | 77 + .../.github/workflows/assembleFlavors.yml | 50 + .../.github/workflows/autoApproveSync.yml | 40 + .../talk-android/.github/workflows/check.yml | 37 + .../talk-android/.github/workflows/codeql.yml | 60 + .../.github/workflows/detectNewJavaFiles.yml | 43 + .../talk-android/.github/workflows/fixup.yml | 36 + vendor/talk-android/.github/workflows/lib.sh | 27 + .../.github/workflows/lib.sh.license | 2 + .../.github/workflows/lint-translations.yml | 39 + .../.github/workflows/pr-feedback.yml | 55 + vendor/talk-android/.github/workflows/qa.yml | 57 + .../workflows/renovate-approve-merge.yml | 61 + .../talk-android/.github/workflows/reuse.yml | 27 + .../.github/workflows/scorecard.yml | 47 + .../talk-android/.github/workflows/stale.yml | 35 + .../.github/workflows/unit-tests.yml | 46 + .../.github/workflows/uploadArtifact.sh | 44 + vendor/talk-android/.gitignore | 90 + vendor/talk-android/.tx/config | 10 + vendor/talk-android/.tx/config.license | 2 + vendor/talk-android/CHANGELOG.md | 659 + vendor/talk-android/CODE_OF_CONDUCT.md | 13 + vendor/talk-android/CONTRIBUTING.md | 412 + vendor/talk-android/LICENCE.md | 679 + .../LICENSES/AGPL-3.0-or-later.txt | 235 + vendor/talk-android/LICENSES/Apache-2.0.txt | 73 + vendor/talk-android/LICENSES/CC-BY-4.0.txt | 156 + vendor/talk-android/LICENSES/CC-BY-SA-3.0.txt | 99 + vendor/talk-android/LICENSES/CC0-1.0.txt | 121 + .../LICENSES/GPL-3.0-or-later.txt | 232 + .../LICENSES/LGPL-2.1-or-later.txt | 175 + .../LICENSES/LGPL-3.0-or-later.txt | 304 + .../LicenseRef-NextcloudTrademarks.txt | 9 + .../LICENSES/LicenseRef-XTrademarks.txt | 49 + vendor/talk-android/LICENSES/MIT.txt | 9 + vendor/talk-android/README.F7CLOUD.md | 29 + vendor/talk-android/README.md | 129 + vendor/talk-android/REUSE.toml | 36 + vendor/talk-android/SECURITY.md | 28 + vendor/talk-android/SETUP.md | 132 + vendor/talk-android/app/build.f7cloud.gradle | 25 + vendor/talk-android/app/build.gradle | 412 + vendor/talk-android/app/build.quality.gradle | 44 + vendor/talk-android/app/lint.xml | 56 + vendor/talk-android/app/proguard-rules.pro | 27 + .../10.json | 146 + .../11.json | 719 + .../12.json | 725 + .../13.json | 749 + .../14.json | 719 + .../15.json | 725 + .../16.json | 731 + .../17.json | 730 + .../18.json | 746 + .../19.json | 746 + .../20.json | 751 + .../21.json | 761 + .../22.json | 796 + .../23.json | 801 + .../8.json | 138 + .../9.json | 139 + .../f7cloud/talk/ExampleInstrumentedTest.java | 35 + .../talk/activities/MainActivityTest.kt | 48 + .../data/database/dao/ChatBlocksDaoTest.kt | 393 + .../data/database/dao/ChatMessagesDaoTest.kt | 276 + .../database/migrations/MigrationsTest.kt | 114 + .../java/ru/f7cloud/talk/ui/LoginIT.java | 131 + .../f7cloud/talk/utils/ColorGeneratorTest.kt | 68 + .../ru/f7cloud/talk/utils/ShareUtilsIT.kt | 55 + .../java/ru/f7cloud/talk/utils/UriUtilsIT.kt | 142 + .../f7cloud/talk/utils/VibrationUtilsTest.kt | 45 + .../app/src/f7/AndroidManifest.xml | 9 + .../ru/f7cloud/talk/f7cloud/F7TalkUserSync.kt | 141 + .../app/src/f7/res/values/setup.xml | 14 + .../app/src/generic/AndroidManifest.xml | 9 + .../android/tr-TR/full_description.txt | 27 + .../talk/utils/ClosedInterfaceImpl.java | 28 + .../app/src/gplay/AndroidManifest.xml | 10 + .../talk/jobs/GetFirebasePushTokenWorker.kt | 63 + .../firebase/NCFirebaseMessagingService.kt | 81 + .../f7cloud/talk/utils/ClosedInterfaceImpl.kt | 93 + .../app/src/main/AndroidManifest.xml | 345 + .../main/assets/leafletMapMessagePreview.html | 42 + .../leafletMapMessagePreview.html.license | 2 + .../app/src/main/ic_launcher-web.png | Bin 0 -> 25403 bytes .../client/TalkJsonNominatimClient.java | 296 + .../main/java/ru/f7cloud/talk/PhoneUtils.kt | 12 + .../account/AccountVerificationActivity.kt | 521 + .../talk/account/BrowserLoginActivity.kt | 177 + .../talk/account/ServerSelectionActivity.kt | 468 + .../talk/account/SwitchAccountActivity.kt | 181 + .../talk/account/data/LoginRepository.kt | 213 + .../account/data/io/LocalLoginDataSource.kt | 45 + .../talk/account/data/model/AccountItem.kt | 12 + .../account/data/model/LoginResponseModels.kt | 12 + .../data/network/NetworkLoginDataSource.kt | 167 + .../BrowserLoginActivityViewModel.kt | 128 + .../talk/activities/ActionBarProvider.java | 13 + .../f7cloud/talk/activities/BaseActivity.kt | 300 + .../f7cloud/talk/activities/CallActivity.kt | 3129 ++ .../talk/activities/CallBaseActivity.java | 163 + .../ru/f7cloud/talk/activities/CallStatus.kt | 22 + .../f7cloud/talk/activities/CallViewModel.kt | 100 + .../f7cloud/talk/activities/MainActivity.kt | 289 + .../talk/activities/ParticipantHandler.kt | 235 + .../talk/activities/ParticipantUiState.kt | 28 + .../talk/activities/TakePhotoActivity.java | 427 + .../f7cloud/talk/adapters/GeocodingAdapter.kt | 59 + .../adapters/PredefinedStatusClickListener.kt | 14 + .../adapters/PredefinedStatusListAdapter.kt | 34 + .../adapters/PredefinedStatusViewHolder.kt | 60 + .../ru/f7cloud/talk/adapters/ReactionItem.kt | 11 + .../adapters/ReactionItemClickListener.kt | 11 + .../f7cloud/talk/adapters/ReactionsAdapter.kt | 29 + .../talk/adapters/ReactionsViewHolder.kt | 48 + .../talk/adapters/items/AdvancedUserItem.kt | 109 + .../talk/adapters/items/ContactItem.kt | 192 + .../talk/adapters/items/ConversationItem.kt | 508 + .../adapters/items/FlexibleItemViewType.kt | 17 + .../adapters/items/GenericTextHeaderItem.kt | 72 + .../adapters/items/LoadMoreResultsItem.kt | 53 + .../adapters/items/MentionAutocompleteItem.kt | 264 + .../talk/adapters/items/MessageResultItem.kt | 89 + .../adapters/items/MessagesTextHeaderItem.kt | 20 + .../adapters/items/NotificationSoundItem.java | 95 + .../talk/adapters/items/ParticipantItem.kt | 320 + .../f7cloud/talk/adapters/items/SpacerItem.kt | 37 + .../AdjustableMessageHolderInterface.kt | 51 + .../messages/CallStartedMessageInterface.kt | 12 + .../messages/CommonMessageInterface.kt | 16 + .../messages/IncomingDeckCardViewHolder.kt | 260 + .../IncomingLinkPreviewMessageViewHolder.kt | 252 + .../IncomingLocationMessageViewHolder.kt | 286 + .../messages/IncomingPollMessageViewHolder.kt | 254 + .../IncomingPreviewMessageViewHolder.java | 161 + .../messages/IncomingTextMessageViewHolder.kt | 469 + .../IncomingVoiceMessageViewHolder.kt | 390 + .../talk/adapters/messages/LinkPreview.kt | 119 + .../talk/adapters/messages/MessagePayload.kt | 15 + .../messages/OutcomingDeckCardViewHolder.kt | 252 + .../OutcomingLinkPreviewMessageViewHolder.kt | 243 + .../OutcomingLocationMessageViewHolder.kt | 292 + .../OutcomingPollMessageViewHolder.kt | 252 + .../OutcomingPreviewMessageViewHolder.java | 184 + .../OutcomingTextMessageViewHolder.kt | 486 + .../OutcomingVoiceMessageViewHolder.kt | 401 + .../messages/PreviewMessageInterface.kt | 13 + .../messages/PreviewMessageViewHolder.kt | 368 + .../talk/adapters/messages/Reaction.kt | 190 + .../messages/SystemMessageInterface.kt | 14 + .../messages/SystemMessageViewHolder.kt | 194 + .../messages/TalkMessagesListAdapter.java | 86 + .../f7cloud/talk/adapters/messages/Thread.kt | 45 + .../talk/adapters/messages/ThreadButton.kt | 87 + .../UnreadNoticeMessageViewHolder.java | 37 + .../messages/VoiceMessageInterface.kt | 16 + .../main/java/ru/f7cloud/talk/api/NcApi.java | 643 + .../ru/f7cloud/talk/api/NcApiCoroutines.kt | 370 + .../application/F7cloudTalkApplication.kt | 275 + .../ArbitraryStorageManager.kt | 23 + .../items/BasicListItemWithImage.kt | 22 + .../talk/bottomsheet/items/BottomSheets.kt | 63 + .../items/ListIconDialogAdapter.kt | 131 + .../talk/call/CallParticipantList.java | 154 + .../call/CallParticipantListNotifier.java | 50 + .../talk/call/LocalCallParticipantModel.java | 114 + .../LocalCallParticipantModelNotifier.java | 73 + .../talk/call/LocalStateBroadcaster.java | 171 + .../talk/call/LocalStateBroadcasterMcu.java | 118 + .../talk/call/LocalStateBroadcasterNoMcu.kt | 101 + .../talk/call/MediaConstraintsHelper.kt | 49 + .../ru/f7cloud/talk/call/MessageSender.java | 93 + .../f7cloud/talk/call/MessageSenderMcu.java | 41 + .../f7cloud/talk/call/MessageSenderNoMcu.java | 47 + .../MutableLocalCallParticipantModel.java | 51 + .../java/ru/f7cloud/talk/call/RaisedHand.kt | 9 + .../ru/f7cloud/talk/call/ReactionAnimator.kt | 166 + .../call/components/AvatarWithFallback.kt | 103 + .../talk/call/components/ParticipantGrid.kt | 332 + .../talk/call/components/ParticipantTile.kt | 187 + .../talk/call/components/SelfVideoView.kt | 72 + .../talk/call/components/WebRTCVideoView.kt | 35 + .../screenshare/ScreenShareComponent.kt | 143 + .../screenshare/WebRtcScreenShareComponent.kt | 143 + .../MentionAutocompleteCallback.java | 91 + .../CallNotificationActivity.kt | 244 + .../java/ru/f7cloud/talk/chat/ChatActivity.kt | 4846 +++ .../f7cloud/talk/chat/MessageInputFragment.kt | 1254 + .../MessageInputVoiceRecordingFragment.kt | 232 + .../talk/chat/NoLongClickMovementMethod.kt | 43 + .../java/ru/f7cloud/talk/chat/OverflowMenu.kt | 160 + .../talk/chat/ScheduleMessageCompose.kt | 419 + .../talk/chat/ScheduledMessagesActivity.kt | 1269 + .../ru/f7cloud/talk/chat/TypingParticipant.kt | 45 + .../talk/chat/data/ChatMessageRepository.kt | 155 + .../chat/data/io/AudioFocusRequestManager.kt | 102 + .../talk/chat/data/io/AudioRecorderManager.kt | 143 + .../chat/data/io/LifecycleAwareManager.kt | 32 + .../talk/chat/data/io/MediaPlayerManager.kt | 350 + .../talk/chat/data/io/MediaRecorderManager.kt | 171 + .../talk/chat/data/model/ChatMessage.kt | 462 + .../data/network/ChatNetworkDataSource.kt | 112 + .../network/OfflineFirstChatRepository.kt | 1251 + .../chat/data/network/RetrofitChatNetwork.kt | 277 + .../talk/chat/viewmodels/ChatViewModel.kt | 1121 + .../chat/viewmodels/MessageInputViewModel.kt | 341 + .../viewmodels/ScheduledMessagesViewModel.kt | 284 + .../talk/chooseaccount/StatusRepository.kt | 14 + .../StatusRepositoryImplementation.kt | 21 + .../talk/chooseaccount/StatusViewModel.kt | 52 + .../talk/components/ColoredStatusBar.kt | 60 + .../f7cloud/talk/components/StandardAppBar.kt | 88 + .../talk/components/VerticallyCenteredRow.kt | 24 + .../f7cloud/talk/contacts/ContactsActivity.kt | 84 + .../talk/contacts/ContactsApplication.kt | 38 + .../talk/contacts/ContactsRepository.kt | 30 + .../talk/contacts/ContactsRepositoryImpl.kt | 104 + .../f7cloud/talk/contacts/ContactsScreen.kt | 83 + .../talk/contacts/ContactsViewModel.kt | 197 + .../ru/f7cloud/talk/contacts/ImageRequest.kt | 38 + .../ru/f7cloud/talk/contacts/ShareType.kt | 16 + .../contacts/components/ContactItemRow.kt | 119 + .../contacts/components/ContactsAppBar.kt | 77 + .../talk/contacts/components/ContactsItem.kt | 74 + .../talk/contacts/components/ContactsList.kt | 58 + .../components/ContactsSearchAppBar.kt | 117 + .../components/ConversationCreationOptions.kt | 92 + .../talk/contacts/components/Header.kt | 34 + .../talk/contextchat/ContextChatView.kt | 240 + .../talk/contextchat/ContextChatViewModel.kt | 109 + .../RenameConversationDialogFragment.kt | 227 + .../ConversationCreationActivity.kt | 731 + .../ConversationCreationRepository.kt | 38 + .../ConversationCreationRepositoryImpl.kt | 124 + .../ConversationCreationViewModel.kt | 259 + .../ConversationInfoActivity.kt | 1973 ++ .../conversationinfo/CreateRoomRequest.kt | 72 + .../conversationinfo/GuestAccessHelper.kt | 238 + .../talk/conversationinfo/Participants.kt | 27 + .../viewmodel/ConversationInfoViewModel.kt | 570 + .../ConversationInfoEditActivity.kt | 349 + .../data/ConversationInfoEditRepository.kt | 45 + .../ConversationInfoEditRepositoryImpl.kt | 85 + .../ConversationInfoEditViewModel.kt | 227 + .../ConversationsListActivity.kt | 2188 ++ .../data/OfflineConversationsRepository.kt | 44 + .../network/ConversationsNetworkDataSource.kt | 16 + .../OfflineFirstConversationsRepository.kt | 170 + .../network/RetrofitConversationsNetwork.kt | 28 + .../viewmodels/ConversationsListViewModel.kt | 421 + .../talk/dagger/modules/BusModule.java | 24 + .../talk/dagger/modules/ContextModule.java | 27 + .../f7cloud/talk/dagger/modules/DaosModule.kt | 27 + .../talk/dagger/modules/DatabaseModule.java | 54 + .../talk/dagger/modules/ManagerModule.kt | 36 + .../talk/dagger/modules/RepositoryModule.kt | 199 + .../talk/dagger/modules/RestModule.java | 318 + .../talk/dagger/modules/UtilsModule.kt | 32 + .../talk/dagger/modules/ViewModelModule.kt | 187 + .../talk/data/database/dao/ChatBlocksDao.kt | 84 + .../talk/data/database/dao/ChatMessagesDao.kt | 234 + .../data/database/dao/ConversationsDao.kt | 66 + .../database/mappers/ChatMessageMapUtils.kt | 131 + .../database/mappers/ConversationMapUtils.kt | 182 + .../data/database/model/ChatBlockEntity.kt | 42 + .../data/database/model/ChatMessageEntity.kt | 80 + .../data/database/model/ConversationEntity.kt | 119 + .../talk/data/database/model/SendStatus.kt | 14 + .../talk/data/network/NetworkMonitor.kt | 27 + .../talk/data/network/NetworkMonitorImpl.kt | 84 + .../talk/data/source/local/Migrations.kt | 421 + .../talk/data/source/local/TalkDatabase.kt | 145 + .../local/converters/ArrayListConverter.kt | 39 + .../local/converters/CapabilitiesConverter.kt | 31 + .../ExternalSignalingServerConverter.kt | 31 + .../converters/HashMapHashMapConverter.kt | 31 + .../converters/LinkedHashMapConverter.kt | 58 + .../LinkedHashMapStringIntConverter.kt | 50 + .../converters/PushConfigurationConverter.kt | 32 + .../local/converters/SendStatusConverter.kt | 19 + .../converters/ServerVersionConverter.kt | 31 + .../converters/SignalingSettingsConverter.kt | 32 + .../data/storage/ArbitraryStorageMapper.kt | 30 + .../talk/data/storage/ArbitraryStoragesDao.kt | 40 + .../storage/ArbitraryStoragesRepository.kt | 18 + .../ArbitraryStoragesRepositoryImpl.kt | 31 + .../data/storage/model/ArbitraryStorage.kt | 18 + .../storage/model/ArbitraryStorageEntity.kt | 28 + .../ru/f7cloud/talk/data/user/UserMapper.kt | 55 + .../ru/f7cloud/talk/data/user/UsersDao.kt | 84 + .../f7cloud/talk/data/user/UsersRepository.kt | 32 + .../talk/data/user/UsersRepositoryImpl.kt | 85 + .../ru/f7cloud/talk/data/user/model/User.kt | 50 + .../talk/data/user/model/UserEntity.kt | 63 + .../f7cloud/talk/diagnose/DiagnoseActivity.kt | 502 + .../diagnose/DiagnoseContentComposable.kt | 266 + .../talk/diagnose/DiagnoseViewModel.kt | 69 + .../f7cloud/talk/events/CertificateEvent.java | 42 + .../talk/events/ConfigurationChangeEvent.java | 34 + .../events/ConversationsListFetchDataEvent.kt | 9 + .../ru/f7cloud/talk/events/EventStatus.java | 90 + .../talk/events/MoreMenuClickEvent.java | 54 + .../ru/f7cloud/talk/events/NetworkEvent.java | 55 + .../talk/events/OpenConversationEvent.kt | 38 + .../talk/events/ProximitySensorEvent.java | 61 + .../talk/events/UserMentionClickEvent.java | 52 + .../events/WebSocketCommunicationEvent.java | 71 + .../talk/extensions/ImageViewExtensions.kt | 497 + .../talk/extensions/LongFormatExtension.kt | 14 + .../talk/extensions/ParcelableExtensions.kt | 30 + .../talk/filebrowser/models/BrowserFile.kt | 106 + .../talk/filebrowser/models/DavResponse.java | 69 + .../models/properties/NCEncrypted.kt | 44 + .../models/properties/NCPermission.kt | 45 + .../models/properties/NCPreview.kt | 44 + .../models/properties/OCFavorite.kt | 44 + .../filebrowser/models/properties/OCId.kt | 44 + .../filebrowser/models/properties/OCSize.kt | 44 + .../talk/filebrowser/webdav/DavUtils.java | 94 + .../webdav/ReadFilesystemOperation.java | 94 + .../webdav/ReadFolderListingOperation.kt | 166 + .../fullscreenfile/FullScreenImageActivity.kt | 212 + .../fullscreenfile/FullScreenMediaActivity.kt | 228 + .../FullScreenTextViewerActivity.kt | 124 + .../talk/interfaces/ClosedInterface.kt | 15 + .../interfaces/ConversationMenuInterface.kt | 14 + .../talk/invitation/InvitationsActivity.kt | 174 + .../invitation/adapters/InvitationsAdapter.kt | 86 + .../talk/invitation/data/Invitation.kt | 21 + .../invitation/data/InvitationActionModel.kt | 9 + .../talk/invitation/data/InvitationsModel.kt | 11 + .../invitation/data/InvitationsRepository.kt | 17 + .../data/InvitationsRepositoryImpl.kt | 84 + .../viewmodels/InvitationsViewModel.kt | 149 + .../talk/jobs/AccountRemovalWorker.java | 206 + .../AddParticipantsToConversationWorker.java | 127 + .../f7cloud/talk/jobs/CapabilitiesWorker.java | 157 + .../talk/jobs/ContactAddressBookWorker.kt | 505 + .../talk/jobs/DeleteConversationWorker.java | 113 + .../talk/jobs/DownloadFileToCacheWorker.kt | 156 + .../talk/jobs/LeaveConversationWorker.kt | 108 + .../f7cloud/talk/jobs/NotificationWorker.kt | 1041 + .../talk/jobs/PushRegistrationWorker.java | 75 + .../talk/jobs/SaveFileToStorageWorker.kt | 115 + .../f7cloud/talk/jobs/ShareOperationWorker.kt | 98 + .../talk/jobs/SignalingSettingsWorker.java | 149 + .../talk/jobs/UploadAndShareFilesWorker.kt | 365 + .../talk/jobs/WebsocketConnectionsWorker.java | 70 + .../talk/location/GeocodingActivity.kt | 223 + .../f7cloud/talk/location/GeocodingResult.kt | 13 + .../talk/location/LocationPickerActivity.kt | 589 + .../ru/f7cloud/talk/lock/LockedActivity.kt | 150 + .../messagesearch/MessageSearchActivity.kt | 250 + .../talk/messagesearch/MessageSearchHelper.kt | 113 + .../messagesearch/MessageSearchViewModel.kt | 115 + .../talk/models/ExternalSignalingServer.kt | 28 + .../ru/f7cloud/talk/models/ImportAccount.java | 94 + .../java/ru/f7cloud/talk/models/LoginData.kt | 15 + .../ru/f7cloud/talk/models/MessageDraft.kt | 57 + .../ru/f7cloud/talk/models/RetrofitBucket.kt | 14 + .../f7cloud/talk/models/RingtoneSettings.kt | 27 + .../talk/models/SignatureVerification.kt | 15 + .../talk/models/TakePictureViewModel.java | 102 + .../talk/models/domain/ConversationModel.kt | 141 + .../talk/models/domain/ReactionAddedModel.kt | 11 + .../models/domain/ReactionDeletedModel.kt | 11 + .../talk/models/domain/SearchMessageEntry.kt | 18 + .../models/domain/StartCallRecordingModel.kt | 9 + .../models/domain/StopCallRecordingModel.kt | 9 + .../DomainEnumNotificationLevelConverter.kt | 39 + .../f7cloud/talk/models/json/AnyParceler.kt | 18 + .../json/autocomplete/AutocompleteOCS.kt | 27 + .../json/autocomplete/AutocompleteOverall.kt | 23 + .../json/autocomplete/AutocompleteUser.kt | 27 + .../models/json/capabilities/Capabilities.kt | 36 + .../json/capabilities/CapabilitiesList.kt | 25 + .../json/capabilities/CapabilitiesOCS.kt | 27 + .../json/capabilities/CapabilitiesOverall.kt | 23 + .../json/capabilities/CoreCapability.kt | 32 + .../capabilities/NotificationsCapability.kt | 25 + .../capabilities/ProvisioningCapability.kt | 26 + .../json/capabilities/RoomCapabilitiesOCS.kt | 27 + .../capabilities/RoomCapabilitiesOverall.kt | 23 + .../models/json/capabilities/ServerVersion.kt | 28 + .../json/capabilities/SpreedCapability.kt | 40 + .../json/capabilities/ThemingCapability.kt | 46 + .../json/capabilities/UserStatusCapability.kt | 29 + .../talk/models/json/chat/ChatMessageJson.kt | 58 + .../models/json/chat/ChatMessageMetaData.kt | 23 + .../f7cloud/talk/models/json/chat/ChatOCS.kt | 26 + .../models/json/chat/ChatOCSSingleMessage.kt | 26 + .../talk/models/json/chat/ChatOverall.kt | 23 + .../json/chat/ChatOverallSingleMessage.kt | 23 + .../talk/models/json/chat/ChatShareOCS.kt | 23 + .../talk/models/json/chat/ChatShareOverall.kt | 23 + .../models/json/chat/ChatShareOverviewOCS.kt | 27 + .../json/chat/ChatShareOverviewOverall.kt | 23 + .../talk/models/json/chat/ChatUtils.kt | 61 + .../talk/models/json/chat/ReadStatus.kt | 13 + .../models/json/conversations/Conversation.kt | 181 + .../json/conversations/ConversationEnums.kt | 52 + .../talk/models/json/conversations/RoomOCS.kt | 26 + .../models/json/conversations/RoomOverall.kt | 23 + .../models/json/conversations/RoomsOCS.kt | 26 + .../models/json/conversations/RoomsOverall.kt | 23 + .../conversations/password/PasswordData.kt | 23 + .../conversations/password/PasswordOCS.kt | 27 + .../conversations/password/PasswordOverall.kt | 23 + .../ConversationObjectTypeConverter.kt | 41 + .../json/converters/EnumActorTypeConverter.kt | 50 + .../converters/EnumLobbyStateConverter.java | 37 + .../EnumNotificationLevelConverter.java | 46 + .../EnumParticipantTypeConverter.java | 54 + .../EnumReactionActorTypeConverter.kt | 34 + .../EnumReadOnlyConversationConverter.java | 38 + .../converters/EnumRoomTypeConverter.java | 54 + .../EnumSystemMessageTypeConverter.kt | 226 + .../LoganSquareJodaTimeConverter.java | 46 + .../converters/ObjectParcelConverter.java | 23 + .../json/converters/ScopeConverter.java | 33 + .../json/converters/UriTypeConverter.java | 31 + .../talk/models/json/generic/GenericMeta.kt | 27 + .../talk/models/json/generic/GenericOCS.kt | 23 + .../models/json/generic/GenericOverall.kt | 23 + .../talk/models/json/generic/Status.kt | 41 + .../talk/models/json/hovercard/HoverCard.kt | 26 + .../models/json/hovercard/HoverCardAction.kt | 28 + .../models/json/hovercard/HoverCardOCS.kt | 26 + .../models/json/hovercard/HoverCardOverall.kt | 19 + .../talk/models/json/invitation/Invitation.kt | 43 + .../models/json/invitation/InvitationOCS.kt | 25 + .../json/invitation/InvitationOverall.kt | 22 + .../talk/models/json/mention/Mention.kt | 39 + .../talk/models/json/mention/MentionOCS.kt | 27 + .../models/json/mention/MentionOverall.kt | 23 + .../models/json/notifications/Notification.kt | 53 + .../json/notifications/NotificationAction.kt | 29 + .../json/notifications/NotificationOCS.kt | 26 + .../json/notifications/NotificationOverall.kt | 22 + .../notifications/NotificationRichObject.kt | 27 + .../json/notifications/NotificationsOCS.kt | 27 + .../notifications/NotificationsOverall.kt | 20 + .../models/json/opengraph/OpenGraphOCS.kt | 25 + .../models/json/opengraph/OpenGraphObject.kt | 30 + .../models/json/opengraph/OpenGraphOverall.kt | 22 + .../json/opengraph/OpenGraphResponse.kt | 22 + .../talk/models/json/opengraph/Reference.kt | 28 + .../talk/models/json/opengraph/RichObject.kt | 30 + .../json/participants/AddParticipantOCS.kt | 28 + .../participants/AddParticipantOverall.kt | 24 + .../models/json/participants/Participant.kt | 141 + .../json/participants/ParticipantsOCS.kt | 26 + .../json/participants/ParticipantsOverall.kt | 23 + .../talk/models/json/participants/TalkBan.kt | 40 + .../models/json/participants/TalkBanOCS.kt | 26 + .../json/participants/TalkBanOverall.kt | 23 + .../models/json/profile/CoreProfileAction.kt | 29 + .../talk/models/json/profile/Profile.kt | 30 + .../talk/models/json/profile/ProfileOCS.kt | 26 + .../models/json/profile/ProfileOverall.kt | 23 + .../models/json/push/DecryptedPushMessage.kt | 106 + .../talk/models/json/push/NotificationUser.kt | 29 + .../json/push/PushConfigurationState.kt | 35 + .../talk/models/json/push/PushRegistration.kt | 29 + .../models/json/push/PushRegistrationOCS.kt | 26 + .../json/push/PushRegistrationOverall.kt | 23 + .../models/json/reactions/ReactionVoter.kt | 35 + .../models/json/reactions/ReactionsOCS.kt | 27 + .../models/json/reactions/ReactionsOverall.kt | 22 + .../talk/models/json/reminder/Reminder.kt | 28 + .../talk/models/json/reminder/ReminderOCS.kt | 25 + .../models/json/reminder/ReminderOverall.kt | 22 + .../models/json/search/ContactsByNumberOCS.kt | 26 + .../json/search/ContactsByNumberOverall.kt | 23 + .../talk/models/json/sharees/ExactSharees.kt | 23 + .../talk/models/json/sharees/Sharee.kt | 27 + .../talk/models/json/sharees/ShareesOCS.kt | 26 + .../models/json/sharees/ShareesOverall.kt | 23 + .../talk/models/json/sharees/SharesData.kt | 25 + .../f7cloud/talk/models/json/sharees/Value.kt | 23 + .../json/signaling/DataChannelMessage.kt | 34 + .../models/json/signaling/NCIceCandidate.kt | 27 + .../models/json/signaling/NCMessagePayload.kt | 37 + .../json/signaling/NCSignalingMessage.kt | 35 + .../talk/models/json/signaling/Signaling.kt | 29 + .../models/json/signaling/SignalingOCS.kt | 26 + .../models/json/signaling/SignalingOverall.kt | 23 + .../settings/FederationHelloAuthParams.kt | 24 + .../signaling/settings/FederationSettings.kt | 30 + .../json/signaling/settings/IceServer.kt | 32 + .../signaling/settings/SignalingSettings.kt | 33 + .../settings/SignalingSettingsOcs.kt | 26 + .../settings/SignalingSettingsOverall.kt | 23 + .../talk/models/json/status/ClearAt.kt | 25 + .../f7cloud/talk/models/json/status/Status.kt | 39 + .../talk/models/json/status/StatusOCS.kt | 26 + .../talk/models/json/status/StatusOverall.kt | 23 + .../talk/models/json/status/StatusType.kt | 16 + .../status/predefined/PredefinedStatus.kt | 29 + .../status/predefined/PredefinedStatusOCS.kt | 26 + .../predefined/PredefinedStatusOverall.kt | 23 + .../testNotification/TestNotificationData.kt | 24 + .../testNotification/TestNotificationOCS.kt | 26 + .../TestNotificationOverall.kt | 23 + .../talk/models/json/threads/Thread.kt | 34 + .../models/json/threads/ThreadAttendee.kt | 19 + .../talk/models/json/threads/ThreadInfo.kt | 29 + .../talk/models/json/threads/ThreadOCS.kt | 25 + .../talk/models/json/threads/ThreadOverall.kt | 22 + .../talk/models/json/threads/ThreadsOCS.kt | 25 + .../models/json/threads/ThreadsOverall.kt | 22 + .../json/unifiedsearch/UnifiedSearchEntry.kt | 34 + .../json/unifiedsearch/UnifiedSearchOCS.kt | 25 + .../unifiedsearch/UnifiedSearchOverall.kt | 22 + .../UnifiedSearchResponseData.kt | 29 + .../json/userAbsence/UserAbsenceData.kt | 38 + .../models/json/userAbsence/UserAbsenceOCS.kt | 26 + .../json/userAbsence/UserAbsenceOverall.kt | 23 + .../talk/models/json/userprofile/Scope.kt | 15 + .../json/userprofile/UserProfileData.kt | 86 + .../json/userprofile/UserProfileFieldsOCS.kt | 27 + .../userprofile/UserProfileFieldsOverall.kt | 23 + .../models/json/userprofile/UserProfileOCS.kt | 26 + .../json/userprofile/UserProfileOverall.kt | 23 + .../json/websocket/ActorWebSocketMessage.kt | 27 + .../AuthParametersWebSocketMessage.kt | 25 + .../json/websocket/AuthWebSocketMessage.kt | 25 + .../json/websocket/BaseWebSocketMessage.kt | 23 + .../json/websocket/ByeWebSocketMessage.kt | 29 + .../websocket/CallOverallWebSocketMessage.kt | 25 + .../json/websocket/CallWebSocketMessage.kt | 28 + .../websocket/ErrorOverallWebSocketMessage.kt | 25 + .../json/websocket/ErrorWebSocketMessage.kt | 25 + .../websocket/EventOverallWebSocketMessage.kt | 29 + .../websocket/HelloOverallWebSocketMessage.kt | 25 + .../HelloResponseOverallWebSocketMessage.kt | 25 + .../HelloResponseWebSocketMessage.kt | 32 + .../json/websocket/HelloWebSocketMessage.kt | 27 + .../JoinedRoomOverallWebSocketMessage.kt | 25 + .../RoomFederationWebSocketMessage.kt | 28 + .../websocket/RoomOverallWebSocketMessage.kt | 25 + .../RoomPropertiesWebSocketMessage.kt | 27 + .../json/websocket/RoomWebSocketMessage.kt | 29 + ...erHelloResponseFeaturesWebSocketMessage.kt | 23 + .../ListOpenConversationsActivity.kt | 152 + .../adapters/OpenConversationsAdapter.kt | 84 + .../data/OpenConversationsRepository.kt | 18 + .../data/OpenConversationsRepositoryImpl.kt | 51 + .../viewmodels/OpenConversationsViewModel.kt | 84 + .../polls/adapters/PollCreateOptionItem.kt | 9 + .../adapters/PollCreateOptionViewHolder.kt | 79 + .../adapters/PollCreateOptionsAdapter.kt | 45 + .../adapters/PollCreateOptionsItemListener.kt | 18 + .../polls/adapters/PollResultHeaderItem.kt | 18 + .../adapters/PollResultHeaderViewHolder.kt | 40 + .../talk/polls/adapters/PollResultItem.kt | 11 + .../adapters/PollResultItemClickListener.kt | 11 + .../polls/adapters/PollResultViewHolder.kt | 14 + .../polls/adapters/PollResultVoterItem.kt | 19 + .../adapters/PollResultVoterViewHolder.kt | 70 + .../adapters/PollResultVotersOverviewItem.kt | 20 + .../PollResultVotersOverviewViewHolder.kt | 108 + .../talk/polls/adapters/PollResultsAdapter.kt | 78 + .../java/ru/f7cloud/talk/polls/model/Poll.kt | 32 + .../f7cloud/talk/polls/model/PollDetails.kt | 16 + .../talk/polls/repositories/PollRepository.kt | 30 + .../polls/repositories/PollRepositoryImpl.kt | 101 + .../repositories/model/PollDetailsResponse.kt | 33 + .../talk/polls/repositories/model/PollOCS.kt | 22 + .../polls/repositories/model/PollOverall.kt | 22 + .../polls/repositories/model/PollResponse.kt | 60 + .../talk/polls/ui/PollCreateDialogFragment.kt | 197 + .../talk/polls/ui/PollLoadingFragment.kt | 47 + .../talk/polls/ui/PollMainDialogFragment.kt | 188 + .../talk/polls/ui/PollResultsFragment.kt | 154 + .../f7cloud/talk/polls/ui/PollVoteFragment.kt | 215 + .../polls/viewmodels/PollCreateViewModel.kt | 206 + .../polls/viewmodels/PollMainViewModel.kt | 199 + .../polls/viewmodels/PollResultsViewModel.kt | 111 + .../polls/viewmodels/PollVoteViewModel.kt | 138 + .../MentionAutocompletePresenter.java | 194 + .../f7cloud/talk/profile/ProfileActivity.kt | 780 + .../talk/raisehand/RequestAssistanceModel.kt | 9 + .../raisehand/RequestAssistanceRepository.kt | 20 + .../RequestAssistanceRepositoryImpl.kt | 52 + .../WithdrawRequestAssistanceModel.kt | 9 + .../raisehand/viewmodel/RaiseHandViewModel.kt | 152 + .../talk/receivers/DirectReplyReceiver.kt | 186 + .../DismissRecordingAvailableReceiver.kt | 99 + .../talk/receivers/MarkAsReadReceiver.kt | 109 + .../talk/receivers/PackageReplacedReceiver.kt | 24 + .../receivers/ShareRecordingToChatReceiver.kt | 110 + .../remotefilebrowser/SelectionInterface.kt | 12 + .../activities/RemoteFileBrowserActivity.kt | 279 + .../adapters/RemoteFileBrowserItemsAdapter.kt | 76 + .../RemoteFileBrowserItemsListViewHolder.kt | 127 + .../RemoteFileBrowserItemsViewHolder.kt | 29 + .../model/RemoteFileBrowserItem.kt | 29 + .../RemoteFileBrowserItemsRepository.kt | 16 + .../RemoteFileBrowserItemsRepositoryImpl.kt | 35 + .../RemoteFileBrowserItemsViewModel.kt | 228 + .../callrecording/CallRecordingRepository.kt | 18 + .../CallRecordingRepositoryImpl.kt | 55 + .../conversations/ConversationsRepository.kt | 57 + .../ConversationsRepositoryImpl.kt | 153 + .../reactions/ReactionsRepository.kt | 35 + .../reactions/ReactionsRepositoryImpl.kt | 162 + .../unifiedsearch/UnifiedSearchRepository.kt | 35 + .../UnifiedSearchRepositoryImpl.kt | 91 + .../talk/services/CallForegroundService.kt | 128 + .../f7cloud/talk/settings/SettingsActivity.kt | 1482 + .../activities/SharedItemsActivity.kt | 279 + .../adapters/SharedItemsAdapter.kt | 121 + .../adapters/SharedItemsGridViewHolder.kt | 29 + .../adapters/SharedItemsListViewHolder.kt | 158 + .../adapters/SharedItemsViewHolder.kt | 99 + .../shareditems/model/SharedDeckCardItem.kt | 18 + .../talk/shareditems/model/SharedFileItem.kt | 22 + .../talk/shareditems/model/SharedItem.kt | 15 + .../talk/shareditems/model/SharedItemType.kt | 29 + .../talk/shareditems/model/SharedItems.kt | 15 + .../shareditems/model/SharedLocationItem.kt | 18 + .../talk/shareditems/model/SharedOtherItem.kt | 15 + .../shareditems/model/SharedPinnedItem.kt | 16 + .../talk/shareditems/model/SharedPollItem.kt | 15 + .../repositories/SharedItemsRepository.kt | 23 + .../repositories/SharedItemsRepositoryImpl.kt | 222 + .../viewmodels/SharedItemsViewModel.kt | 163 + .../CallParticipantMessageNotifier.java | 94 + .../signaling/ConversationMessageNotifier.kt | 37 + .../LocalParticipantMessageNotifier.java | 40 + .../talk/signaling/OfferMessageNotifier.java | 40 + .../ParticipantListMessageNotifier.java | 55 + .../signaling/SignalingMessageReceiver.java | 844 + .../signaling/SignalingMessageSender.java | 23 + .../talk/signaling/WebRtcMessageNotifier.java | 107 + .../ThreadsOverviewActivity.kt | 257 + .../threadsoverview/components/ThreadRow.kt | 213 + .../threadsoverview/data/ThreadsRepository.kt | 20 + .../data/ThreadsRepositoryImpl.kt | 29 + .../viewmodels/ThreadsOverviewViewModel.kt | 80 + .../repositories/TranslateRepository.kt | 23 + .../repositories/TranslateRepositoryImpl.kt | 31 + .../translate/repositories/model/Language.kt | 28 + .../repositories/model/LanguagesData.kt | 24 + .../repositories/model/LanguagesOCS.kt | 25 + .../repositories/model/LanguagesOverall.kt | 22 + .../repositories/model/TranslateData.kt | 24 + .../repositories/model/TranslateOCS.kt | 25 + .../repositories/model/TranslationsOverall.kt | 22 + .../talk/translate/ui/TranslateActivity.kt | 290 + .../viewmodels/TranslateViewModel.kt | 119 + .../talk/ui/BackgroundVoiceMessageCard.kt | 195 + .../ru/f7cloud/talk/ui/ComposeChatAdapter.kt | 1154 + .../java/ru/f7cloud/talk/ui/MessageInput.kt | 83 + .../java/ru/f7cloud/talk/ui/MicInputCloud.kt | 383 + .../java/ru/f7cloud/talk/ui/PinnedMessage.kt | 302 + .../f7cloud/talk/ui/PlaybackSpeedControl.kt | 71 + .../ru/f7cloud/talk/ui/StatusDrawable.java | 144 + .../ru/f7cloud/talk/ui/SwipeToCloseLayout.kt | 88 + .../ru/f7cloud/talk/ui/WaveformSeekBar.kt | 125 + .../ui/bottom/sheet/ProfileBottomSheet.kt | 184 + .../talk/ui/dialog/AttachmentDialog.kt | 151 + .../talk/ui/dialog/AudioOutputDialog.kt | 146 + .../ui/dialog/ChooseAccountDialogCompose.kt | 573 + .../ChooseAccountShareToDialogFragment.kt | 161 + .../dialog/ConversationsListBottomDialog.kt | 459 + .../f7cloud/talk/ui/dialog/DateTimeCompose.kt | 427 + .../talk/ui/dialog/DialogBanListFragment.kt | 140 + .../dialog/FileAttachmentPreviewFragment.kt | 95 + .../ui/dialog/FilterConversationFragment.kt | 172 + .../talk/ui/dialog/MessageActionsDialog.kt | 696 + .../talk/ui/dialog/MoreCallActionsDialog.kt | 191 + .../OnlineStatusBottomDialogFragment.kt | 184 + .../ui/dialog/PinnedMessageOptionsDialog.kt | 230 + .../ui/dialog/SaveToStorageDialogFragment.kt | 115 + .../ru/f7cloud/talk/ui/dialog/ScopeDialog.kt | 80 + .../ui/dialog/SetPhoneNumberDialogFragment.kt | 101 + .../talk/ui/dialog/ShowReactionsDialog.kt | 358 + .../ui/dialog/SortingOrderDialogFragment.java | 189 + .../StatusMessageBottomDialogFragment.kt | 600 + .../ui/dialog/TempMessageActionsDialog.kt | 130 + .../ui/recyclerview/MessageSwipeActions.kt | 22 + .../ui/recyclerview/MessageSwipeCallback.kt | 277 + .../talk/ui/theme/MaterialSchemesProvider.kt | 18 + .../ui/theme/MaterialSchemesProviderImpl.kt | 50 + .../f7cloud/talk/ui/theme/ServerThemeImpl.kt | 30 + .../ui/theme/TalkSpecificViewThemeUtils.kt | 497 + .../ru/f7cloud/talk/ui/theme/ThemeModule.kt | 30 + .../f7cloud/talk/ui/theme/ViewThemeUtils.kt | 31 + .../ru/f7cloud/talk/upload/chunked/Chunk.kt | 12 + .../chunked/ChunkFromFileRequestBody.kt | 102 + .../upload/chunked/ChunkedFileUploader.kt | 402 + .../chunked/OnDataTransferProgressListener.kt | 12 + .../talk/upload/normal/FileUploader.kt | 180 + .../java/ru/f7cloud/talk/users/UserManager.kt | 236 + .../ru/f7cloud/talk/utils/AccountUtils.kt | 148 + .../java/ru/f7cloud/talk/utils/ApiUtils.kt | 558 + .../talk/utils/AppCompatActivityExtensions.kt | 38 + .../java/ru/f7cloud/talk/utils/AudioUtils.kt | 231 + .../talk/utils/AuthenticatorService.java | 87 + .../ru/f7cloud/talk/utils/BitmapShrinker.kt | 92 + .../ru/f7cloud/talk/utils/BrandingUtils.kt | 16 + .../ru/f7cloud/talk/utils/CapabilitiesUtil.kt | 339 + .../ru/f7cloud/talk/utils/CharPolicy.java | 110 + .../ru/f7cloud/talk/utils/ChatMessageUtils.kt | 38 + .../ru/f7cloud/talk/utils/ColorGenerator.kt | 69 + .../ru/f7cloud/talk/utils/ContactUtils.kt | 44 + .../f7cloud/talk/utils/ContextExtensions.kt | 39 + .../f7cloud/talk/utils/ConversationUtils.kt | 61 + .../ru/f7cloud/talk/utils/DateConstants.kt | 16 + .../java/ru/f7cloud/talk/utils/DateUtils.kt | 106 + .../ru/f7cloud/talk/utils/DeviceUtils.java | 79 + .../ru/f7cloud/talk/utils/DisplayUtils.kt | 557 + .../f7cloud/talk/utils/DoNotDisturbUtils.kt | 47 + .../ru/f7cloud/talk/utils/DrawableUtils.kt | 184 + .../talk/utils/EmojiTextInputEditText.java | 59 + .../utils/FABAwareScrollingViewBehavior.java | 62 + .../ru/f7cloud/talk/utils/FileSortOrder.kt | 78 + .../f7cloud/talk/utils/FileSortOrderByDate.kt | 32 + .../f7cloud/talk/utils/FileSortOrderByName.kt | 44 + .../f7cloud/talk/utils/FileSortOrderBySize.kt | 41 + .../java/ru/f7cloud/talk/utils/FileUtils.kt | 166 + .../ru/f7cloud/talk/utils/FileViewerUtils.kt | 408 + .../f7cloud/talk/utils/ImageEmojiEditText.kt | 62 + .../ru/f7cloud/talk/utils/LoggingUtils.kt | 50 + .../java/ru/f7cloud/talk/utils/Mimetype.kt | 38 + .../ru/f7cloud/talk/utils/MimetypeUtils.kt | 15 + .../talk/utils/NoSupportedApiException.kt | 9 + .../f7cloud/talk/utils/NotificationUtils.kt | 346 + .../talk/utils/ParticipantPermissions.kt | 86 + .../java/ru/f7cloud/talk/utils/PickImage.kt | 179 + .../java/ru/f7cloud/talk/utils/PushUtils.kt | 412 + .../ru/f7cloud/talk/utils/ReceiverFlag.kt | 29 + .../ru/f7cloud/talk/utils/RemoteFileUtils.kt | 72 + .../ru/f7cloud/talk/utils/SecurityUtils.java | 116 + .../java/ru/f7cloud/talk/utils/ShareUtils.kt | 58 + .../ru/f7cloud/talk/utils/SyncAdapter.java | 29 + .../ru/f7cloud/talk/utils/SyncService.java | 36 + .../ru/f7cloud/talk/utils/TalkFileProvider.kt | 10 + .../ru/f7cloud/talk/utils/TextDrawable.kt | 59 + .../ru/f7cloud/talk/utils/TextMatchers.java | 27 + .../java/ru/f7cloud/talk/utils/UriUtils.kt | 65 + .../java/ru/f7cloud/talk/utils/UserIdUtils.kt | 20 + .../ru/f7cloud/talk/utils/VibrationUtils.kt | 20 + .../talk/utils/animations/PulseAnimation.java | 72 + .../ViewHidingBehaviourAnimation.java | 61 + .../f7cloud/talk/utils/bundle/BundleKeys.kt | 89 + .../ArbitraryStorageModule.java | 33 + .../database/user/CurrentUserProvider.kt | 14 + .../database/user/CurrentUserProviderImpl.kt | 54 + .../database/user/CurrentUserProviderOld.kt | 16 + .../user/CurrentUserProviderOldImpl.kt | 46 + .../talk/utils/database/user/UserModule.kt | 33 + .../utils/message/MessageCheckboxUtils.kt | 142 + .../talk/utils/message/MessageUtils.kt | 228 + .../talk/utils/message/SendMessageUtils.kt | 32 + .../permissions/PlatformPermissionUtil.kt | 18 + .../permissions/PlatformPermissionUtilImpl.kt | 103 + .../talk/utils/power/PowerManagerUtils.kt | 176 + .../talk/utils/power/ProximityLock.java | 45 + .../utils/preferences/AppPreferences.java | 185 + .../utils/preferences/AppPreferencesImpl.kt | 632 + .../DatabaseStorageModule.kt | 200 + .../talk/utils/preview/ComposePreviewUtils.kt | 191 + .../utils/preview/ComposePreviewUtilsDaos.kt | 232 + .../ru/f7cloud/talk/utils/rx/DisposableSet.kt | 23 + .../talk/utils/rx/SearchViewObservable.kt | 35 + .../ApplicationWideCurrentRoomHolder.java | 95 + .../ApplicationWideMessageHolder.java | 33 + .../singletons/AvatarStatusCodeHolder.java | 24 + .../ru/f7cloud/talk/utils/ssl/KeyManager.java | 191 + .../talk/utils/ssl/SSLSocketFactoryCompat.kt | 101 + .../f7cloud/talk/utils/ssl/TrustManager.java | 183 + .../ru/f7cloud/talk/utils/text/Spans.java | 84 + .../talk/viewmodels/CallRecordingViewModel.kt | 186 + .../talk/viewmodels/GeoCodingViewModel.kt | 62 + .../webrtc/DataChannelMessageNotifier.java | 65 + .../java/ru/f7cloud/talk/webrtc/Globals.java | 15 + .../talk/webrtc/PeerConnectionNotifier.java | 55 + .../talk/webrtc/PeerConnectionWrapper.java | 674 + .../f7cloud/talk/webrtc/ProximitySensor.java | 155 + .../ru/f7cloud/talk/webrtc/WebRTCUtils.java | 134 + .../talk/webrtc/WebRtcAudioManager.java | 581 + .../talk/webrtc/WebRtcBluetoothManager.java | 582 + .../webrtc/WebSocketConnectionHelper.java | 171 + .../f7cloud/talk/webrtc/WebSocketInstance.kt | 497 + .../daveKoeller/AlphanumComparator.java | 170 + .../third/parties/fresco/BetterImageSpan.kt | 110 + .../app/src/main/res/anim/popup_animation.xml | 21 + .../res/animator/appbar_elevation_off.xml | 17 + .../main/res/animator/appbar_elevation_on.xml | 17 + .../drawable-land/link_text_background.xml | 19 + .../drawable-night/account_circle_48dp.xml | 17 + .../drawable-night/account_circle_96dp.xml | 16 + .../main/res/drawable-night/ic_cellphone.xml | 16 + .../res/drawable-night/ic_chevron_right.xml | 15 + .../drawable-night/ic_circular_document.xml | 24 + .../res/drawable-night/ic_circular_group.xml | 21 + .../ic_circular_group_mentions.xml | 28 + .../res/drawable-night/ic_circular_link.xml | 21 + .../drawable-night/ic_circular_location.xml | 21 + .../res/drawable-night/ic_circular_lock.xml | 22 + .../res/drawable-night/ic_circular_mail.xml | 21 + .../res/drawable-night/ic_close_search.xml | 15 + .../main/res/drawable-night/ic_contacts.xml | 16 + .../src/main/res/drawable-night/ic_link.xml | 16 + .../main/res/drawable-night/ic_password.xml | 16 + .../drawable-night/icon_circular_phone.xml | 27 + .../res/drawable-night/icon_circular_team.xml | 27 + .../src/main/res/drawable/accent_circle.xml | 11 + .../main/res/drawable/account_circle_48dp.xml | 17 + .../main/res/drawable/account_circle_96dp.xml | 16 + .../main/res/drawable/all_inclusive_24px.xml | 16 + .../main/res/drawable/baseline_article_24.xml | 18 + .../res/drawable/baseline_audiotrack_24.xml | 17 + .../res/drawable/baseline_bar_chart_24.xml | 20 + .../main/res/drawable/baseline_block_24.xml | 17 + .../drawable/baseline_calendar_month_24.xml | 16 + .../drawable/baseline_calendar_today_24.xml | 19 + .../baseline_chat_bubble_outline_24.xml | 16 + .../res/drawable/baseline_contacts_24.xml | 17 + .../res/drawable/baseline_download_24.xml | 16 + .../main/res/drawable/baseline_error_24.xml | 16 + .../drawable/baseline_error_outline_24.xml | 16 + .../baseline_format_list_bulleted_24.xml | 17 + .../main/res/drawable/baseline_image_24.xml | 16 + .../main/res/drawable/baseline_info_24.xml | 16 + .../baseline_insert_drive_file_24.xml | 17 + .../res/drawable/baseline_location_pin_24.xml | 16 + .../res/drawable/baseline_lock_open_24.xml | 16 + .../src/main/res/drawable/baseline_mic_24.xml | 16 + .../drawable/baseline_notifications_24.xml | 16 + .../drawable/baseline_photo_library_24.xml | 16 + .../drawable/baseline_report_problem_24.xml | 16 + .../res/drawable/baseline_schedule_24.xml | 16 + .../main/res/drawable/baseline_stop_24.xml | 16 + .../res/drawable/baseline_tag_faces_24.xml | 17 + .../res/drawable/baseline_unfold_less_24.xml | 15 + .../res/drawable/baseline_unfold_more_24.xml | 15 + .../main/res/drawable/baseline_video_24.xml | 17 + .../src/main/res/drawable/borderless_btn.xml | 14 + .../res/drawable/current_location_circle.xml | 16 + .../src/main/res/drawable/cutout_circle.xml | 11 + .../app/src/main/res/drawable/deck.xml | 25 + .../app/src/main/res/drawable/forward_24.xml | 16 + .../src/main/res/drawable/ic_account_plus.xml | 16 + .../main/res/drawable/ic_add_grey600_24px.xml | 16 + .../main/res/drawable/ic_alphabetical_asc.xml | 16 + .../res/drawable/ic_alphabetical_desc.xml | 19 + .../res/drawable/ic_arrow_back_black_24dp.xml | 16 + .../drawable/ic_arrow_forward_white_24px.xml | 16 + .../res/drawable/ic_av_timer_timer_24dp.xml | 17 + .../res/drawable/ic_avatar_background.xml | 28 + .../main/res/drawable/ic_avatar_document.xml | 18 + .../res/drawable/ic_avatar_federation.xml | 15 + .../src/main/res/drawable/ic_avatar_group.xml | 16 + .../res/drawable/ic_avatar_group_small.xml | 22 + .../src/main/res/drawable/ic_avatar_link.xml | 15 + .../src/main/res/drawable/ic_avatar_mail.xml | 15 + .../res/drawable/ic_avatar_team_small.xml | 23 + .../ic_baseline_arrow_downward_24px.xml | 16 + .../drawable/ic_baseline_attach_file_24.xml | 16 + .../res/drawable/ic_baseline_bar_chart_24.xml | 16 + .../ic_baseline_bluetooth_audio_24.xml | 16 + .../res/drawable/ic_baseline_close_24.xml | 16 + .../main/res/drawable/ic_baseline_deck_24.xml | 27 + .../drawable/ic_baseline_do_not_touch_24.xml | 15 + .../ic_baseline_error_outline_24dp.xml | 16 + .../drawable/ic_baseline_filter_list_24.xml | 16 + .../res/drawable/ic_baseline_flash_off_24.xml | 16 + .../res/drawable/ic_baseline_flash_on_24.xml | 16 + .../ic_baseline_flip_camera_android_24.xml | 16 + .../res/drawable/ic_baseline_gps_fixed_24.xml | 15 + .../drawable/ic_baseline_headset_mic_24.xml | 16 + .../res/drawable/ic_baseline_keyboard_24.xml | 16 + .../drawable/ic_baseline_location_on_24.xml | 16 + .../ic_baseline_location_on_red_24.xml | 15 + .../main/res/drawable/ic_baseline_mic_24.xml | 16 + .../res/drawable/ic_baseline_mic_red_24.xml | 16 + .../ic_baseline_notifications_off_24.xml | 16 + .../ic_baseline_pause_voice_message_24.xml | 15 + .../res/drawable/ic_baseline_person_24.xml | 16 + .../drawable/ic_baseline_person_black_24.xml | 16 + .../drawable/ic_baseline_phone_in_talk_24.xml | 16 + .../drawable/ic_baseline_phone_missed_24.xml | 17 + .../drawable/ic_baseline_photo_camera_24.xml | 16 + .../ic_baseline_picture_in_picture_alt_24.xml | 17 + ...c_baseline_play_arrow_voice_message_24.xml | 15 + .../res/drawable/ic_baseline_translate_24.xml | 16 + .../res/drawable/ic_baseline_videocam_24.xml | 17 + .../main/res/drawable/ic_call_black_24dp.xml | 15 + .../res/drawable/ic_call_end_white_24px.xml | 15 + .../res/drawable/ic_call_grey_600_24dp.xml | 16 + .../main/res/drawable/ic_call_white_24dp.xml | 15 + .../res/drawable/ic_cancel_black_24dp.xml | 15 + .../res/drawable/ic_cancel_white_24dp.xml | 16 + .../src/main/res/drawable/ic_cellphone.xml | 15 + .../app/src/main/res/drawable/ic_check.xml | 16 + .../app/src/main/res/drawable/ic_check_24.xml | 16 + .../src/main/res/drawable/ic_check_all.xml | 16 + .../main/res/drawable/ic_check_black_24dp.xml | 16 + .../src/main/res/drawable/ic_check_circle.xml | 16 + .../res/drawable/ic_check_circle_outlined.xml | 18 + .../main/res/drawable/ic_chevron_right.xml | 15 + .../res/drawable/ic_circular_document.xml | 24 + .../main/res/drawable/ic_circular_group.xml | 21 + .../drawable/ic_circular_group_mentions.xml | 28 + .../main/res/drawable/ic_circular_link.xml | 21 + .../res/drawable/ic_circular_location.xml | 21 + .../main/res/drawable/ic_circular_lock.xml | 22 + .../main/res/drawable/ic_circular_mail.xml | 21 + .../app/src/main/res/drawable/ic_clear_24.xml | 16 + .../src/main/res/drawable/ic_close_search.xml | 15 + .../app/src/main/res/drawable/ic_comment.xml | 17 + .../app/src/main/res/drawable/ic_contacts.xml | 16 + .../src/main/res/drawable/ic_content_copy.xml | 17 + .../src/main/res/drawable/ic_crop_16_9.xml | 16 + .../app/src/main/res/drawable/ic_crop_4_3.xml | 16 + .../app/src/main/res/drawable/ic_delete.xml | 16 + .../res/drawable/ic_delete_black_24dp.xml | 15 + .../res/drawable/ic_delete_grey600_24dp.xml | 15 + .../main/res/drawable/ic_dots_horizontal.xml | 16 + .../res/drawable/ic_dots_horizontal_white.xml | 15 + .../app/src/main/res/drawable/ic_edit.xml | 16 + .../app/src/main/res/drawable/ic_edit_24.xml | 16 + .../src/main/res/drawable/ic_edit_note_24.xml | 16 + .../app/src/main/res/drawable/ic_email.xml | 16 + .../drawable/ic_exit_to_app_black_24dp.xml | 11 + .../app/src/main/res/drawable/ic_folder.xml | 16 + .../res/drawable/ic_folder_multiple_image.xml | 16 + .../main/res/drawable/ic_hand_back_left.xml | 15 + .../src/main/res/drawable/ic_high_quality.xml | 16 + .../main/res/drawable/ic_info_white_24dp.xml | 16 + .../ic_insert_emoticon_black_24dp.xml | 16 + .../res/drawable/ic_keyboard_arrow_down.xml | 15 + .../res/drawable/ic_keyboard_arrow_up.xml | 21 + .../ic_keyboard_double_arrow_down.xml | 16 + .../res/drawable/ic_launcher_background.xml | 28 + .../res/drawable/ic_launcher_foreground.xml | 24 + .../app/src/main/res/drawable/ic_link.xml | 16 + .../main/res/drawable/ic_link_black_24px.xml | 15 + .../res/drawable/ic_link_grey600_24px.xml | 15 + .../main/res/drawable/ic_list_empty_error.xml | 16 + .../res/drawable/ic_lock_grey600_24px.xml | 16 + .../drawable/ic_lock_open_grey600_24dp.xml | 16 + .../drawable/ic_lock_plus_grey600_24dp.xml | 16 + .../main/res/drawable/ic_lock_white_24px.xml | 15 + .../app/src/main/res/drawable/ic_logo.xml | 23 + .../src/main/res/drawable/ic_low_quality.xml | 16 + .../src/main/res/drawable/ic_map_marker.xml | 15 + .../res/drawable/ic_mark_chat_read_24px.xml | 16 + .../res/drawable/ic_mark_chat_unread_24px.xml | 16 + .../app/src/main/res/drawable/ic_menu.xml | 15 + .../res/drawable/ic_mic_grey_600_24dp.xml | 16 + .../res/drawable/ic_mic_off_white_24px.xml | 15 + .../main/res/drawable/ic_mic_white_24px.xml | 15 + .../drawable/ic_mimetype_application_pdf.xml | 16 + .../main/res/drawable/ic_mimetype_audio.xml | 16 + .../main/res/drawable/ic_mimetype_file.xml | 18 + .../main/res/drawable/ic_mimetype_folder.xml | 16 + .../drawable/ic_mimetype_folder_shared.xml | 15 + .../main/res/drawable/ic_mimetype_image.xml | 16 + .../main/res/drawable/ic_mimetype_link.xml | 38 + .../res/drawable/ic_mimetype_location.xml | 17 + .../ic_mimetype_package_x_generic.xml | 18 + .../main/res/drawable/ic_mimetype_text.xml | 17 + .../drawable/ic_mimetype_text_calendar.xml | 17 + .../res/drawable/ic_mimetype_text_code.xml | 22 + .../res/drawable/ic_mimetype_text_vcard.xml | 17 + .../main/res/drawable/ic_mimetype_video.xml | 16 + .../res/drawable/ic_mimetype_whiteboard.xml | 16 + .../ic_mimetype_x_office_document.xml | 17 + .../ic_mimetype_x_office_presentation.xml | 15 + .../ic_mimetype_x_office_spreadsheet.xml | 16 + .../main/res/drawable/ic_modification_asc.xml | 14 + .../res/drawable/ic_modification_desc.xml | 14 + .../res/drawable/ic_more_horiz_black_24dp.xml | 16 + .../src/main/res/drawable/ic_note_to_self.xml | 26 + .../src/main/res/drawable/ic_notification.xml | 23 + .../app/src/main/res/drawable/ic_password.xml | 16 + .../res/drawable/ic_pencil_grey600_24dp.xml | 16 + .../drawable/ic_people_group_black_24px.xml | 16 + .../app/src/main/res/drawable/ic_phone.xml | 18 + .../src/main/res/drawable/ic_phone_small.xml | 24 + .../app/src/main/res/drawable/ic_refresh.xml | 15 + .../app/src/main/res/drawable/ic_reply.xml | 17 + .../drawable/ic_room_service_black_24dp.xml | 15 + .../src/main/res/drawable/ic_search_grey.xml | 15 + .../res/drawable/ic_search_white_24dp.xml | 16 + .../res/drawable/ic_security_white_24dp.xml | 15 + .../app/src/main/res/drawable/ic_settings.xml | 16 + .../src/main/res/drawable/ic_share_action.xml | 17 + .../main/res/drawable/ic_share_variant.xml | 16 + .../ic_signal_wifi_off_white_24dp.xml | 15 + .../app/src/main/res/drawable/ic_size_asc.xml | 16 + .../src/main/res/drawable/ic_size_desc.xml | 16 + .../main/res/drawable/ic_star_black_24dp.xml | 16 + .../drawable/ic_star_border_black_24dp.xml | 16 + .../drawable/ic_switch_video_white_24px.xml | 15 + .../app/src/main/res/drawable/ic_talk.xml | 18 + .../main/res/drawable/ic_timer_black_24dp.xml | 16 + .../app/src/main/res/drawable/ic_twitter.xml | 16 + .../main/res/drawable/ic_unarchive_24px.xml | 16 + .../app/src/main/res/drawable/ic_user.xml | 16 + .../main/res/drawable/ic_user_status_away.xml | 15 + .../main/res/drawable/ic_user_status_busy.xml | 19 + .../main/res/drawable/ic_user_status_dnd.xml | 15 + .../res/drawable/ic_user_status_invisible.xml | 15 + .../drawable/ic_videocam_grey_600_24dp.xml | 17 + .../drawable/ic_videocam_off_white_24px.xml | 15 + .../res/drawable/ic_videocam_white_24px.xml | 16 + .../drawable/ic_volume_mute_white_24dp.xml | 16 + .../res/drawable/ic_volume_up_white_24dp.xml | 16 + .../main/res/drawable/ic_warning_white.xml | 15 + .../app/src/main/res/drawable/ic_web.xml | 15 + .../main/res/drawable/icon_circular_phone.xml | 27 + .../main/res/drawable/icon_circular_team.xml | 27 + .../main/res/drawable/incoming_gradient.xml | 14 + .../app/src/main/res/drawable/keep_24px.xml | 16 + .../src/main/res/drawable/keep_off_24px.xml | 17 + .../src/main/res/drawable/launch_screen.xml | 15 + .../res/drawable/link_text_background.xml | 19 + .../link_text_no_preview_background.xml | 19 + .../src/main/res/drawable/mention_chip.xml | 11 + .../src/main/res/drawable/online_status.xml | 16 + .../res/drawable/outline_access_time_24.xml | 18 + .../main/res/drawable/outline_archive_24.xml | 18 + .../main/res/drawable/outline_forum_24.xml | 18 + .../main/res/drawable/outline_monitor_24.xml | 11 + .../outline_notifications_active_24.xml | 11 + .../main/res/drawable/outline_qr_code_24.xml | 12 + .../main/res/drawable/outline_schedule_24.xml | 18 + .../res/drawable/outline_schedule_send_24.xml | 19 + .../res/drawable/reaction_self_background.xml | 23 + .../reaction_self_bottom_sheet_background.xml | 17 + .../src/main/res/drawable/record_start.xml | 15 + .../src/main/res/drawable/record_starting.xml | 15 + .../app/src/main/res/drawable/record_stop.xml | 15 + .../main/res/drawable/reply_background.xml | 33 + .../app/src/main/res/drawable/round_bgnd.xml | 11 + .../shape_grouped_incoming_message.xml | 19 + .../shape_grouped_outcoming_message.xml | 19 + .../res/drawable/shape_incoming_message.xml | 19 + .../res/drawable/shape_outcoming_message.xml | 19 + .../app/src/main/res/drawable/shape_oval.xml | 11 + .../app/src/main/res/drawable/trashbin.xml | 16 + .../app/src/main/res/drawable/upload.xml | 15 + .../src/main/res/drawable/upload_white.xml | 15 + ...voice_message_outgoing_seek_bar_slider.xml | 15 + .../main/res/layout-land/activity_profile.xml | 194 + .../res/layout-land/activity_translate.xml | 158 + .../layout-land/reference_inside_message.xml | 90 + .../app/src/main/res/layout/account_item.xml | 103 + .../layout/activity_account_verification.xml | 46 + .../app/src/main/res/layout/activity_chat.xml | 320 + .../res/layout/activity_conversation_info.xml | 659 + .../activity_conversation_info_edit.xml | 159 + .../res/layout/activity_conversations.xml | 352 + .../res/layout/activity_full_screen_image.xml | 39 + .../res/layout/activity_full_screen_media.xml | 33 + .../res/layout/activity_full_screen_text.xml | 53 + .../main/res/layout/activity_geocoding.xml | 38 + .../main/res/layout/activity_invitations.xml | 55 + .../src/main/res/layout/activity_location.xml | 136 + .../src/main/res/layout/activity_locked.xml | 51 + .../app/src/main/res/layout/activity_main.xml | 45 + .../res/layout/activity_message_search.xml | 59 + .../layout/activity_open_conversations.xml | 90 + .../src/main/res/layout/activity_profile.xml | 169 + .../layout/activity_remote_file_browser.xml | 118 + .../res/layout/activity_server_selection.xml | 195 + .../src/main/res/layout/activity_settings.xml | 921 + .../main/res/layout/activity_shared_items.xml | 66 + .../res/layout/activity_switch_account.xml | 43 + .../main/res/layout/activity_take_picture.xml | 223 + .../main/res/layout/activity_translate.xml | 151 + .../res/layout/activity_web_view_login.xml | 58 + .../app/src/main/res/layout/ban_item_list.xml | 63 + .../app/src/main/res/layout/call_activity.xml | 352 + .../res/layout/call_notification_activity.xml | 109 + .../main/res/layout/call_started_message.xml | 115 + .../app/src/main/res/layout/call_states.xml | 55 + .../main/res/layout/create_thread_view.xml | 53 + .../main/res/layout/current_account_item.xml | 130 + .../src/main/res/layout/dialog_attachment.xml | 339 + .../main/res/layout/dialog_audio_output.xml | 165 + .../res/layout/dialog_ban_participant.xml | 107 + .../layout/dialog_choose_account_share_to.xml | 38 + .../layout/dialog_conversation_operations.xml | 325 + .../res/layout/dialog_create_conversation.xml | 55 + .../layout/dialog_file_attachment_preview.xml | 95 + .../res/layout/dialog_filter_conversation.xml | 84 + .../res/layout/dialog_message_actions.xml | 682 + .../res/layout/dialog_message_reactions.xml | 39 + .../res/layout/dialog_more_call_actions.xml | 120 + .../src/main/res/layout/dialog_password.xml | 27 + .../main/res/layout/dialog_poll_create.xml | 155 + .../main/res/layout/dialog_poll_loading.xml | 22 + .../src/main/res/layout/dialog_poll_main.xml | 83 + .../main/res/layout/dialog_poll_results.xml | 57 + .../src/main/res/layout/dialog_poll_vote.xml | 82 + .../res/layout/dialog_rename_conversation.xml | 56 + .../app/src/main/res/layout/dialog_scope.xml | 206 + .../res/layout/dialog_set_online_status.xml | 379 + .../res/layout/dialog_set_phone_number.xml | 29 + .../res/layout/dialog_set_status_message.xml | 157 + .../layout/dialog_temp_message_actions.xml | 165 + .../src/main/res/layout/edit_message_view.xml | 62 + .../app/src/main/res/layout/empty_list.xml | 54 + .../res/layout/federated_invitation_hint.xml | 39 + .../res/layout/fragment_dialog_ban_list.xml | 51 + .../res/layout/fragment_message_input.xml | 94 + ...fragment_message_input_voice_recording.xml | 105 + .../src/main/res/layout/geocoding_item.xml | 43 + ...item_custom_incoming_deck_card_message.xml | 133 + ...m_custom_incoming_link_preview_message.xml | 112 + .../item_custom_incoming_location_message.xml | 99 + .../item_custom_incoming_poll_message.xml | 120 + .../item_custom_incoming_preview_message.xml | 251 + .../item_custom_incoming_text_message.xml | 129 + ...m_custom_incoming_text_message_shimmer.xml | 70 + .../item_custom_incoming_voice_message.xml | 162 + ...tem_custom_outcoming_deck_card_message.xml | 123 + ..._custom_outcoming_link_preview_message.xml | 91 + ...item_custom_outcoming_location_message.xml | 83 + .../item_custom_outcoming_poll_message.xml | 102 + .../item_custom_outcoming_preview_message.xml | 235 + .../item_custom_outcoming_text_message.xml | 143 + .../item_custom_outcoming_voice_message.xml | 144 + .../main/res/layout/item_event_schedule.xml | 60 + .../res/layout/item_guest_access_settings.xml | 138 + .../main/res/layout/item_message_quote.xml | 95 + .../res/layout/item_notification_settings.xml | 158 + .../main/res/layout/item_reactions_tab.xml | 33 + .../res/layout/item_recording_consent.xml | 77 + .../app/src/main/res/layout/item_spacer.xml | 10 + .../main/res/layout/item_system_message.xml | 98 + .../src/main/res/layout/item_thread_title.xml | 42 + .../src/main/res/layout/item_webinar_info.xml | 119 + .../app/src/main/res/layout/lobby_view.xml | 38 + .../src/main/res/layout/menu_item_sheet.xml | 41 + .../res/layout/no_saved_messages_view.xml | 37 + .../main/res/layout/notifications_warning.xml | 66 + .../main/res/layout/out_of_office_view.xml | 113 + .../res/layout/poll_create_options_item.xml | 56 + .../res/layout/poll_result_header_item.xml | 47 + .../res/layout/poll_result_voter_item.xml | 31 + .../poll_result_voters_overview_item.xml | 16 + .../src/main/res/layout/predefined_status.xml | 75 + .../app/src/main/res/layout/reaction_item.xml | 43 + .../res/layout/reactions_inside_message.xml | 35 + .../res/layout/reference_inside_message.xml | 87 + .../remainder_to_delete_conversation.xml | 56 + .../main/res/layout/rv_item_browser_file.xml | 91 + .../src/main/res/layout/rv_item_contact.xml | 52 + .../rv_item_conversation_info_participant.xml | 106 + ...rv_item_conversation_with_last_message.xml | 135 + ...conversation_with_last_message_shimmer.xml | 46 + .../main/res/layout/rv_item_invitation.xml | 88 + .../src/main/res/layout/rv_item_load_more.xml | 45 + .../res/layout/rv_item_notification_sound.xml | 34 + .../res/layout/rv_item_open_conversation.xml | 54 + .../res/layout/rv_item_search_message.xml | 64 + .../main/res/layout/rv_item_title_header.xml | 34 + .../app/src/main/res/layout/search_layout.xml | 96 + .../src/main/res/layout/shared_item_grid.xml | 45 + .../src/main/res/layout/shared_item_list.xml | 131 + .../res/layout/sorting_order_fragment.xml | 299 + .../layout/user_info_details_table_item.xml | 70 + .../user_info_details_table_item_shimmer.xml | 30 + .../main/res/layout/view_message_input.xml | 277 + .../app/src/main/res/menu/chat_call_menu.xml | 13 + .../app/src/main/res/menu/chat_send_menu.xml | 24 + .../src/main/res/menu/menu_conversation.xml | 91 + .../main/res/menu/menu_conversation_info.xml | 17 + .../res/menu/menu_conversation_info_edit.xml | 17 + .../menu/menu_conversation_plus_filter.xml | 29 + .../app/src/main/res/menu/menu_geocoding.xml | 19 + .../src/main/res/menu/menu_locationpicker.xml | 19 + .../app/src/main/res/menu/menu_preview.xml | 15 + .../app/src/main/res/menu/menu_profile.xml | 17 + .../app/src/main/res/menu/menu_search.xml | 16 + .../src/main/res/menu/menu_share_files.xml | 15 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 4803 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 3011 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6716 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 10398 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 14973 bytes .../res/raw/librem_by_feandesign_call.ogg | Bin 0 -> 213909 bytes .../res/raw/librem_by_feandesign_message.ogg | Bin 0 -> 82206 bytes .../res/raw/next_voice_message_doodle.ogg | Bin 0 -> 10580 bytes .../main/res/raw/tr110_1_kap8_3_freiton1.ogg | Bin 0 -> 34121 bytes .../app/src/main/res/values-ar/strings.xml | 676 + .../src/main/res/values-b+en+001/strings.xml | 759 + .../app/src/main/res/values-be/strings.xml | 760 + .../src/main/res/values-bg-rBG/strings.xml | 520 + .../app/src/main/res/values-ca/strings.xml | 653 + .../src/main/res/values-cs-rCZ/strings.xml | 765 + .../app/src/main/res/values-da/strings.xml | 729 + .../app/src/main/res/values-de/strings.xml | 759 + .../app/src/main/res/values-el/strings.xml | 490 + .../src/main/res/values-es-rEC/strings.xml | 531 + .../app/src/main/res/values-es/strings.xml | 736 + .../src/main/res/values-et-rEE/strings.xml | 759 + .../app/src/main/res/values-eu/strings.xml | 595 + .../app/src/main/res/values-fa/strings.xml | 436 + .../src/main/res/values-fi-rFI/strings.xml | 443 + .../app/src/main/res/values-fr/strings.xml | 745 + .../app/src/main/res/values-ga/strings.xml | 771 + .../app/src/main/res/values-gl/strings.xml | 759 + .../app/src/main/res/values-hr/strings.xml | 505 + .../src/main/res/values-hu-rHU/strings.xml | 733 + .../app/src/main/res/values-it/strings.xml | 739 + .../src/main/res/values-ja-rJP/strings.xml | 628 + .../app/src/main/res/values-ko/strings.xml | 513 + .../app/src/main/res/values-land/dimens.xml | 13 + .../app/src/main/res/values-lo/strings.xml | 729 + .../src/main/res/values-lt-rLT/strings.xml | 403 + .../src/main/res/values-nb-rNO/strings.xml | 635 + .../app/src/main/res/values-night/colors.xml | 64 + .../app/src/main/res/values-nl/strings.xml | 743 + .../app/src/main/res/values-pl/strings.xml | 765 + .../src/main/res/values-pt-rBR/strings.xml | 761 + .../app/src/main/res/values-ru/strings.xml | 748 + .../app/src/main/res/values-sc/strings.xml | 404 + .../src/main/res/values-sk-rSK/strings.xml | 750 + .../app/src/main/res/values-sl/strings.xml | 533 + .../app/src/main/res/values-sr/strings.xml | 737 + .../app/src/main/res/values-sv/strings.xml | 732 + .../app/src/main/res/values-sw/strings.xml | 758 + .../src/main/res/values-sw600dp/dimens.xml | 13 + .../app/src/main/res/values-tr/strings.xml | 747 + .../app/src/main/res/values-ug/strings.xml | 737 + .../app/src/main/res/values-uk/strings.xml | 732 + .../app/src/main/res/values-v27/styles.xml | 33 + .../app/src/main/res/values-v28/arrays.xml | 64 + .../app/src/main/res/values-v28/defaults.xml | 10 + .../app/src/main/res/values-w820dp/dimens.xml | 13 + .../src/main/res/values-zh-rCN/strings.xml | 601 + .../src/main/res/values-zh-rHK/strings.xml | 755 + .../src/main/res/values-zh-rTW/strings.xml | 753 + .../app/src/main/res/values/arrays.xml | 83 + .../app/src/main/res/values/attrs.xml | 14 + .../app/src/main/res/values/bool.xml | 11 + .../app/src/main/res/values/colors.xml | 96 + .../app/src/main/res/values/defaults.xml | 10 + .../app/src/main/res/values/dimens.xml | 89 + .../app/src/main/res/values/setup.xml | 59 + .../app/src/main/res/values/strings.xml | 936 + .../app/src/main/res/values/styles.xml | 310 + .../app/src/main/res/xml/auth.xml | 12 + .../src/main/res/xml/automotive_app_desc.xml | 10 + .../app/src/main/res/xml/backup_config.xml | 10 + .../app/src/main/res/xml/chip_others.xml | 14 + .../app/src/main/res/xml/chip_you.xml | 14 + .../app/src/main/res/xml/contacts.xml | 13 + .../src/main/res/xml/file_provider_paths.xml | 14 + .../main/res/xml/network_security_config.xml | 16 + .../app/src/main/res/xml/syncadapter.xml | 11 + .../app/src/qa/ic_launcher-web.png | Bin 0 -> 31078 bytes .../talk/utils/ClosedInterfaceImpl.java | 28 + .../res/drawable/ic_launcher_background.xml | 32 + .../res/drawable/ic_launcher_foreground.xml | 21 + .../qa/res/mipmap-anydpi-v26/ic_launcher.xml | 12 + .../src/qa/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 5184 bytes .../src/qa/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 3229 bytes .../src/qa/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 7299 bytes .../src/qa/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 11233 bytes .../src/qa/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 16182 bytes .../app/src/qa/res/values/setup.xml | 12 + .../app/src/test/java/android/util/Log.kt | 56 + .../talk/activities/CallViewModelTest.kt | 163 + .../talk/activities/ParticipantHandlerTest.kt | 77 + ...lParticipantListExternalSignalingTest.java | 654 + ...lParticipantListInternalSignalingTest.java | 528 + .../talk/call/CallParticipantListTest.java | 48 + .../call/LocalCallParticipantModelTest.kt | 168 + .../talk/call/LocalStateBroadcasterMcuTest.kt | 682 + .../call/LocalStateBroadcasterNoMcuTest.kt | 177 + .../talk/call/LocalStateBroadcasterTest.kt | 325 + .../f7cloud/talk/call/MessageSenderMcuTest.kt | 118 + .../talk/call/MessageSenderNoMcuTest.kt | 101 + .../ru/f7cloud/talk/call/MessageSenderTest.kt | 188 + .../talk/contacts/ContactsViewModelTest.kt | 146 + .../talk/contacts/apiService/FakeItem.kt | 58 + .../repository/FakeRepositoryError.kt | 39 + .../repository/FakeRepositorySuccess.kt | 36 + .../ConversationInfoViewModelTest.kt | 25 + .../talk/json/ConversationConversionTest.kt | 174 + .../talk/login/data/LoginRepositoryTest.kt | 596 + .../network/NetworkLoginDataSourceTest.kt | 167 + .../messagesearch/MessageSearchHelperTest.kt | 165 + ...ingMessageReceiverCallParticipantTest.java | 262 + ...ngMessageReceiverLocalParticipantTest.java | 180 + .../SignalingMessageReceiverOfferTest.java | 218 + ...ingMessageReceiverParticipantListTest.java | 461 + .../SignalingMessageReceiverTest.java | 122 + .../SignalingMessageReceiverWebRtcTest.java | 353 + .../test/fakes/FakeCallRecordingRepository.kt | 22 + .../test/fakes/FakeUnifiedSearchRepository.kt | 41 + .../ru/f7cloud/talk/utils/BundleKeysTest.kt | 90 + .../talk/utils/DoNotDisturbUtilsTest.java | 60 + .../talk/utils/ParticipantPermissionsTest.kt | 97 + .../ru/f7cloud/talk/utils/UserIdUtilsTest.kt | 42 + .../talk/viewmodels/AbstractViewModelTest.kt | 40 + .../viewmodels/CallRecordingViewModelTest.kt | 133 + .../webrtc/DataChannelMessageNotifierTest.kt | 75 + .../ru/f7cloud/talk/webrtc/GlobalsTest.kt | 27 + .../talk/webrtc/PeerConnectionNotifierTest.kt | 68 + .../talk/webrtc/PeerConnectionWrapperTest.kt | 760 + .../resources/RoomOverallExample_APIv1.json | 66 + .../resources/RoomOverallExample_APIv2.json | 51 + .../resources/RoomOverallExample_APIv4.json | 83 + .../org.mockito.plugins.MockMaker | 1 + vendor/talk-android/build.gradle | 51 + .../developer-certificate-of-origin | 35 + .../developer-certificate-of-origin.license | 2 + vendor/talk-android/detekt.yml | 493 + vendor/talk-android/docs/TURN.md | 96 + vendor/talk-android/docs/branching.png | Bin 0 -> 22626 bytes .../talk-android/docs/branching.png.license | 2 + vendor/talk-android/docs/branching.svg | 187 + .../talk-android/docs/branching.svg.license | 2 + .../docs/gplayDebugBuildVariant.png | Bin 0 -> 12930 bytes .../docs/gplayDebugBuildVariant.png.license | 2 + ...rantNotificationPermissionAfterInstall.png | Bin 0 -> 12356 bytes ...ficationPermissionAfterInstall.png.license | 2 + .../docs/ignoreBatteryOptimizationDialog.png | Bin 0 -> 46956 bytes ...gnoreBatteryOptimizationDialog.png.license | 2 + ...ignoreBatteryOptimizationSelectAllApps.png | Bin 0 -> 37000 bytes ...tteryOptimizationSelectAllApps.png.license | 2 + ...ignoreBatteryOptimizationTurnOffSwitch.png | Bin 0 -> 30905 bytes ...tteryOptimizationTurnOffSwitch.png.license | 2 + ...tion_newerAndroid_allowBackgroundUsage.png | Bin 0 -> 37194 bytes ...erAndroid_allowBackgroundUsage.png.license | 2 + ...Optimization_newerAndroid_unrestricted.png | Bin 0 -> 62543 bytes ...tion_newerAndroid_unrestricted.png.license | 2 + .../docs/notificationSettingsExample.png | Bin 0 -> 53839 bytes .../notificationSettingsExample.png.license | 2 + vendor/talk-android/docs/notifications.md | 168 + .../notificationsNotSetUpCorrectlyWarning.png | Bin 0 -> 40482 bytes ...ationsNotSetUpCorrectlyWarning.png.license | 2 + .../docs/semantic_versioning_code.png | Bin 0 -> 5433 bytes .../docs/semantic_versioning_code.png.license | 2 + .../drawable_resources/icon-background.svg | 4 + .../icon-background.svg.license | 2 + .../drawable_resources/icon-foreground.svg | 6 + .../icon-foreground.svg.license | 2 + .../drawable_resources/icon-foreground_qa.svg | 5 + .../icon-foreground_qa.svg.license | 2 + .../other/account-circle.svg | 7 + .../other/account-circle.svg.license | 2 + .../other/circular_document.svg | 10 + .../other/circular_document.svg.license | 3 + .../other/circular_group.svg | 10 + .../other/circular_group.svg.license | 3 + .../other/circular_link.svg | 10 + .../other/circular_link.svg.license | 3 + .../other/circular_location.svg | 10 + .../other/circular_location.svg.license | 3 + .../other/circular_lock.svg | 10 + .../other/circular_lock.svg.license | 3 + .../other/circular_mail.svg | 10 + .../other/circular_mail.svg.license | 3 + .../other/file-icon-black-24h.svg | 11 + .../other/file-icon-black-24h.svg.license | 2 + .../drawable_resources/other/file-icon.svg | 12 + .../other/file-icon.svg.license | 2 + .../other/file-password-request.svg | 9 + .../other/file-password-request.svg.license | 2 + .../drawable_resources/other/ic_crop_16_9.svg | 5 + .../other/ic_crop_16_9.svg.license | 3 + .../drawable_resources/other/ic_crop_4_3.svg | 5 + .../other/ic_crop_4_3.svg.license | 3 + .../other/ic_low_quality.svg | 5 + .../other/ic_low_quality.svg.license | 3 + vendor/talk-android/fastlane/Appfile | 2 + vendor/talk-android/fastlane/Appfile.license | 2 + .../android/cs-CZ/full_description.txt | 25 + .../android/cs-CZ/short_description.txt | 1 + .../fastlane/metadata/android/cs-CZ/title.txt | 1 + .../android/de-DE/full_description.txt | 25 + .../android/de-DE/short_description.txt | 1 + .../fastlane/metadata/android/de-DE/title.txt | 1 + .../android/el-GR/short_description.txt | 1 + .../fastlane/metadata/android/el-GR/title.txt | 1 + .../android/en-US/full_description.txt | 25 + .../android/en-US/images/featureGraphic.png | Bin 0 -> 434972 bytes .../metadata/android/en-US/images/icon.png | Bin 0 -> 129190 bytes .../conversationList_dark.png | Bin 0 -> 227288 bytes .../conversationList_light.png | Bin 0 -> 227596 bytes .../phoneScreenshots/markdown_light.png | Bin 0 -> 142940 bytes .../searchParticipant_light.png | Bin 0 -> 60472 bytes .../phoneScreenshots/serverSelection.png | Bin 0 -> 56700 bytes .../phoneScreenshots/settings_light.png | Bin 0 -> 137878 bytes .../images/phoneScreenshots/voiceCall.png | Bin 0 -> 148609 bytes .../phoneScreenshots/voiceRecord_light.png | Bin 0 -> 370254 bytes .../android/en-US/short_description.txt | 1 + .../fastlane/metadata/android/en-US/title.txt | 1 + .../android/es-ES/full_description.txt | 25 + .../android/es-ES/short_description.txt | 1 + .../fastlane/metadata/android/es-ES/title.txt | 1 + .../android/fr-FR/full_description.txt | 25 + .../android/fr-FR/short_description.txt | 1 + .../fastlane/metadata/android/fr-FR/title.txt | 1 + .../android/is-IS/short_description.txt | 1 + .../fastlane/metadata/android/is-IS/title.txt | 1 + .../android/it-IT/full_description.txt | 25 + .../android/it-IT/short_description.txt | 1 + .../fastlane/metadata/android/it-IT/title.txt | 1 + .../android/nl-NL/full_description.txt | 25 + .../android/nl-NL/short_description.txt | 1 + .../fastlane/metadata/android/nl-NL/title.txt | 1 + .../android/pl-PL/short_description.txt | 1 + .../fastlane/metadata/android/pl-PL/title.txt | 1 + .../android/pt-BR/full_description.txt | 25 + .../android/pt-BR/short_description.txt | 1 + .../fastlane/metadata/android/pt-BR/title.txt | 1 + .../android/ru-RU/full_description.txt | 25 + .../android/ru-RU/short_description.txt | 1 + .../fastlane/metadata/android/ru-RU/title.txt | 1 + .../android/sr-SR/full_description.txt | 26 + .../android/sr-SR/short_description.txt | 1 + .../fastlane/metadata/android/sr-SR/title.txt | 1 + .../android/tr-TR/full_description.txt | 27 + .../android/tr-TR/short_description.txt | 1 + .../fastlane/metadata/android/tr-TR/title.txt | 1 + .../android/vi-VI/short_description.txt | 1 + .../fastlane/metadata/android/vi-VI/title.txt | 1 + .../gradle/verification-keyring.keys | 7168 ++++ .../gradle/verification-keyring.keys.license | 2 + .../gradle/verification-metadata.xml | 27928 ++++++++++++++++ .../gradle/verification-metadata.xml.license | 2 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 46175 bytes .../gradle/wrapper/gradle-wrapper.jar.license | 2 + .../gradle/wrapper/gradle-wrapper.properties | 7 + .../wrapper/gradle-wrapper.properties.license | 2 + vendor/talk-android/gradlew | 248 + vendor/talk-android/gradlew.bat | 93 + vendor/talk-android/gradlew.bat.license | 2 + vendor/talk-android/gradlew.license | 2 + vendor/talk-android/renovate.json5 | 19 + vendor/talk-android/renovate.json5.license | 2 + .../scripts/analysis/analysis-wrapper.sh | 148 + .../scripts/analysis/getBranchName.sh | 13 + .../scripts/analysis/lint-results.txt | 2 + .../scripts/analysis/lint-results.txt.license | 2 + .../talk-android/scripts/analysis/lint-up.rb | 191 + .../scripts/analysis/spotbugs-up.rb | 53 + .../scripts/analysis/spotbugsComparison.py | 56 + .../scripts/analysis/spotbugsSummary.py | 64 + .../scripts/checkGplayLimitation.sh | 18 + vendor/talk-android/scripts/hooks/pre-commit | 19 + vendor/talk-android/scripts/hooks/pre-push | 32 + vendor/talk-android/scripts/lib.sh | 27 + .../scripts/metadata/generate_metadata.py | 127 + vendor/talk-android/scripts/repo | 1 + vendor/talk-android/scripts/repo.license | 2 + .../scripts/tools/OxygenConversion.MD | 11 + .../talk-android/scripts/wait_for_emulator.sh | 29 + vendor/talk-android/settings.gradle | 22 + vendor/talk-android/spotbugs-filter.xml | 93 + 1789 files changed, 246889 insertions(+) create mode 100644 .gitignore create mode 100644 NOTICE.md create mode 100644 PROJECT-STATUS.md create mode 100644 README.md create mode 100644 app/build.gradle create mode 100644 app/google-services.json.example create mode 100644 app/proguard-rules.pro create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/CallIncomingActivity.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/IncomingCallScreen.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/MainActivity.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/OfficeEditorActivity.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewClient.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewPool.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/RichDocumentsMobileBridge.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/navigation/AppLinkResolver.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7AppPermissions.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7PermissionDialog.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/qr/F7QrScannerActivity.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppLockGate.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt create mode 100644 app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppSheets.kt create mode 100644 app/src/main/res/drawable-nodpi/f7_logo_reference.png create mode 100644 app/src/main/res/drawable/f7_app_lock_logo.png create mode 100644 app/src/main/res/drawable/ic_call_accept.xml create mode 100644 app/src/main/res/drawable/ic_call_decline.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 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/xml/shortcuts.xml create mode 100644 build.gradle create mode 100644 core/auth/build.gradle create mode 100644 core/auth/src/main/AndroidManifest.xml create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AppLockStore.kt create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthErrors.kt create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthSession.kt create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthStore.kt create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthVerifier.kt create mode 100644 core/auth/src/main/java/ru/forbion/f7cloud/core/auth/OcsUserResolver.kt create mode 100644 core/data/build.gradle create mode 100644 core/data/src/main/AndroidManifest.xml create mode 100644 core/database/build.gradle create mode 100644 core/database/src/main/AndroidManifest.xml create mode 100644 core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactEntity.kt create mode 100644 core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactsDao.kt create mode 100644 core/database/src/main/java/ru/forbion/f7cloud/core/database/F7Database.kt create mode 100644 core/database/src/main/java/ru/forbion/f7cloud/core/database/FileEntity.kt create mode 100644 core/database/src/main/java/ru/forbion/f7cloud/core/database/FilesDao.kt create mode 100644 core/designsystem/build.gradle create mode 100644 core/designsystem/src/main/AndroidManifest.xml create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/AppForegroundTracker.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AppMenuSheet.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AutoHideBottomBar.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Colors.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Components.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7FloatingPanel.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7NotificationRow.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7OverlayNavigation.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7RelativeTime.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Theme.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Typography.kt create mode 100644 core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7WindowInsets.kt create mode 100644 core/designsystem/src/main/res/font/raleway_medium.ttf create mode 100644 core/designsystem/src/main/res/font/raleway_semibold.ttf create mode 100644 core/network/build.gradle create mode 100644 core/network/src/main/AndroidManifest.xml create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/BasicAuthInterceptor.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/CalDavClient.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/CalendarIcs.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/CardDavClient.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/DavClient.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/LoginFlowClient.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/NetworkFactory.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/NotificationsRepository.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/OcsJson.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/UnauthorizedException.kt create mode 100644 core/network/src/main/java/ru/forbion/f7cloud/core/network/UnsafeSsl.kt create mode 100644 core/push/build.gradle create mode 100644 core/push/src/main/AndroidManifest.xml create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7CallActionReceiver.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7FirebaseMessagingService.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallQueue.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallRinger.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7NotificationChannels.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEvent.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventHub.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventParser.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushIntentExtras.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushNotificationHelper.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushRegistrar.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/PushIntents.kt create mode 100644 core/push/src/main/java/ru/forbion/f7cloud/core/push/TalkCallPushLabels.kt create mode 100644 core/push/src/main/res/values/strings.xml create mode 100644 core/ui/build.gradle create mode 100644 design/README.md create mode 100644 design/icons/.gitkeep create mode 100644 design/references/figma-links.md create mode 100644 design/screens/.gitkeep create mode 100644 design/screens/ico/Ellipse 14.svg create mode 100644 design/screens/ico/Size=45, Name=Карточки.svg create mode 100644 design/screens/ico/Vector 181.svg create mode 100644 design/screens/ico/icon/35/Archive Zip rar.svg create mode 100644 design/screens/ico/icon/35/Audio.svg create mode 100644 design/screens/ico/icon/35/Calendar.svg create mode 100644 design/screens/ico/icon/35/Certificate.svg create mode 100644 design/screens/ico/icon/35/Code.svg create mode 100644 design/screens/ico/icon/35/Eml.svg create mode 100644 design/screens/ico/icon/35/Image.svg create mode 100644 design/screens/ico/icon/35/No name.svg create mode 100644 design/screens/ico/icon/35/PDF.svg create mode 100644 design/screens/ico/icon/35/Presentation.svg create mode 100644 design/screens/ico/icon/35/Spreadsheet.svg create mode 100644 design/screens/ico/icon/35/Text.svg create mode 100644 design/screens/ico/icon/35/Video.svg create mode 100644 design/screens/ico/icon/35/Word.svg create mode 100644 design/screens/ico/icon/35/Колокол c оповещениями.svg create mode 100644 design/screens/ico/icon/35/колокол.svg create mode 100644 design/screens/ico/Вайд борд.svg create mode 100644 design/screens/ico/Карточки.svg create mode 100644 design/screens/mail/Заполненное.png create mode 100644 design/screens/mail/Ответить на сообщение.png create mode 100644 design/screens/mail/Параметры учётной записи.png create mode 100644 design/screens/mail/Параметры электронной почты.png create mode 100644 design/screens/mail/Пересланные сообщения.png create mode 100644 design/screens/mail/Почта _ Окно сообщения отправленное нескольким пользователям-1.png create mode 100644 design/screens/mail/Почта _ Окно сообщения отправленное нескольким пользователям-2.png create mode 100644 design/screens/mail/Почта _ Окно сообщения отправленное нескольким пользователям.png create mode 100644 design/screens/mail/Почта _ Окно сообщения.png create mode 100644 design/screens/mail/Почта _ Создание сообщения с доп. строчками и открытыми настройками текста.png create mode 100644 design/screens/mail/Почта _ Создание сообщения.png create mode 100644 design/screens/mail/Почта _ Список сообщений.png create mode 100644 design/screens/mail/Прямой поиск ( с кнопками подсказками).png create mode 100644 design/screens/mail/Сообщение с перепиской закрытые.png create mode 100644 design/screens/mail/Сообщение с перепиской открытое.png create mode 100644 design/screens/mail/Список неотправленных сообщений.png create mode 100644 design/screens/tasks/Задачи _ Завершенные.png create mode 100644 design/screens/tasks/Задачи _ На неделе.png create mode 100644 design/screens/tasks/Задачи _ Сегодня _ Нажат плюс.png create mode 100644 design/screens/tasks/Задачи _ Список пуст с кнопкой удалить.png create mode 100644 design/screens/tasks/Задачи _ Список пуст.png create mode 100644 design/screens/tasks/Задачи _ Список.png create mode 100644 design/screens/tasks/Задачи _ Фильтровать по меткам.png create mode 100644 design/screens/tasks/Параметры задач.png create mode 100644 design/screens/tasks/Правая панель заметки.png create mode 100644 design/screens/tasks/Правая панель свойства заполненная-1.png create mode 100644 design/screens/tasks/Правая панель свойства заполненная.png create mode 100644 design/screens/tasks/Правая панель свойства незаполненная.png create mode 100644 design/tokens/colors.txt create mode 100644 design/tokens/typography.txt create mode 100644 feature/calendar/build.gradle create mode 100644 feature/calendar/src/main/AndroidManifest.xml create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarApiClient.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarComponents.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarExtendedUi.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarModels.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarPrefsStore.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarRepository.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarScreen.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarSyncEngine.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarSyncStore.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/CalendarViewModel.kt create mode 100644 feature/calendar/src/main/java/ru/forbion/f7cloud/feature/calendar/DeviceCalendarClient.kt create mode 100644 feature/contacts/build.gradle create mode 100644 feature/contacts/src/main/AndroidManifest.xml create mode 100644 feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactDetailSheet.kt create mode 100644 feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactRecipientHelper.kt create mode 100644 feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsRepository.kt create mode 100644 feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsScreen.kt create mode 100644 feature/contacts/src/main/java/ru/forbion/f7cloud/feature/contacts/ContactsViewModel.kt create mode 100644 feature/deck/build.gradle create mode 100644 feature/deck/src/main/AndroidManifest.xml create mode 100644 feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckRepository.kt create mode 100644 feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckScreen.kt create mode 100644 feature/deck/src/main/java/ru/forbion/f7cloud/feature/deck/DeckViewModel.kt create mode 100644 feature/f7support/build.gradle create mode 100644 feature/f7support/src/main/AndroidManifest.xml create mode 100644 feature/f7support/src/main/java/ru/forbion/f7cloud/feature/f7support/SupportComponents.kt create mode 100644 feature/f7support/src/main/java/ru/forbion/f7cloud/feature/f7support/SupportFileIO.kt create mode 100644 feature/f7support/src/main/java/ru/forbion/f7cloud/feature/f7support/SupportRepository.kt create mode 100644 feature/f7support/src/main/java/ru/forbion/f7cloud/feature/f7support/SupportScreen.kt create mode 100644 feature/f7support/src/main/java/ru/forbion/f7cloud/feature/f7support/SupportViewModel.kt create mode 100644 feature/files/build.gradle create mode 100644 feature/files/src/main/AndroidManifest.xml create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/ArchiveFiles.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/F7FileProvider.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FileDownloadRepository.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FileIcons.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FileItem.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FileOpenAction.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesApiRepository.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesComponents.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesCreateMenu.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesModels.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesRepository.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesScreen.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesTemplatesRepository.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesUiState.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/FilesViewModel.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/ImageViewerActivity.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/LocalFileOpener.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/OfficeFileLinks.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/OfficeFileOpener.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/OfficeFiles.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/OfficeWarmup.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/OpenableFiles.kt create mode 100644 feature/files/src/main/java/ru/forbion/f7cloud/feature/files/RichdocumentsRepository.kt create mode 100644 feature/files/src/main/res/xml/f7_file_paths.xml create mode 100644 feature/mail/build.gradle create mode 100644 feature/mail/src/main/AndroidManifest.xml create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailAttachmentIO.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailBackNavigation.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailBodyHtml.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailCacheRepository.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComponents.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComposeActivity.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComposeLaunch.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComposeSchedule.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComposeScreen.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailComposeViewModel.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailFilesPickerActivity.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailMessageBodyView.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailModels.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailRecipientComposeField.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailReplyHelper.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailRepository.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailRichTextEditor.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailScreen.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailSettingsScreens.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailViewModel.kt create mode 100644 feature/mail/src/main/java/ru/forbion/f7cloud/feature/mail/MailWebBranding.kt create mode 100644 feature/talk-native/build.gradle create mode 100644 feature/talk-native/src/main/AndroidManifest.xml create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkAuthBridge.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkNativeCallContext.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkNativeCallLauncher.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkNativeConfig.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkNativeFacade.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkPushBridge.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkVendorBootstrap.kt create mode 100644 feature/talk-native/src/main/java/ru/forbion/f7cloud/feature/talknative/TalkVendorUserSync.kt create mode 100644 feature/talk/build.gradle create mode 100644 feature/talk/src/main/AndroidManifest.xml create mode 100644 feature/talk/src/main/assets/f7_talk_direct_join.js create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/F7CallWakeLock.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkAssets.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkAttachmentUploader.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkCallActivity.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkComponents.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkDeepLink.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkFilters.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkFormatting.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkHelper.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkMention.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkMessage.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkMessageParameter.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkOfflineDao.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkOfflineDatabase.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkOfflineEntities.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkOfflineRepository.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkParticipant.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkRepository.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkRoom.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkRoomInfoSheet.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkScreen.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkShareActivity.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkShareTarget.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkUrls.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkViewModel.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkVoiceRecorder.kt create mode 100644 feature/talk/src/main/java/ru/forbion/f7cloud/feature/talk/TalkWebBranding.kt create mode 100644 feature/tasks/build.gradle create mode 100644 feature/tasks/src/main/AndroidManifest.xml create mode 100644 feature/tasks/src/main/java/ru/forbion/f7cloud/feature/tasks/TasksComponents.kt create mode 100644 feature/tasks/src/main/java/ru/forbion/f7cloud/feature/tasks/TasksGrouping.kt create mode 100644 feature/tasks/src/main/java/ru/forbion/f7cloud/feature/tasks/TasksRepository.kt create mode 100644 feature/tasks/src/main/java/ru/forbion/f7cloud/feature/tasks/TasksScreen.kt create mode 100644 feature/tasks/src/main/java/ru/forbion/f7cloud/feature/tasks/TasksViewModel.kt create mode 100644 feature/widgets/build.gradle create mode 100644 feature/widgets/src/main/AndroidManifest.xml create mode 100644 feature/widgets/src/main/java/ru/forbion/f7cloud/feature/widgets/WidgetsRepository.kt create mode 100644 feature/widgets/src/main/java/ru/forbion/f7cloud/feature/widgets/WidgetsScreen.kt create mode 100644 feature/widgets/src/main/java/ru/forbion/f7cloud/feature/widgets/WidgetsUiState.kt create mode 100644 feature/widgets/src/main/java/ru/forbion/f7cloud/feature/widgets/WidgetsViewModel.kt 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 create mode 100644 vendor/talk-android/.devcontainer/Dockerfile create mode 100644 vendor/talk-android/.devcontainer/Dockerfile.license create mode 100644 vendor/talk-android/.devcontainer/README.md create mode 100644 vendor/talk-android/.devcontainer/devcontainer.env create mode 100644 vendor/talk-android/.devcontainer/devcontainer.env.license create mode 100644 vendor/talk-android/.devcontainer/devcontainer.json create mode 100644 vendor/talk-android/.devcontainer/devcontainer.json.license create mode 100644 vendor/talk-android/.drone.yml create mode 100644 vendor/talk-android/.editorconfig create mode 100644 vendor/talk-android/.github/FUNDING.yml create mode 100644 vendor/talk-android/.github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 vendor/talk-android/.github/ISSUE_TEMPLATE/bug_report.yml.license create mode 100644 vendor/talk-android/.github/ISSUE_TEMPLATE/config.yml create mode 100644 vendor/talk-android/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 vendor/talk-android/.github/ISSUE_TEMPLATE/feature_request.md.license create mode 100644 vendor/talk-android/.github/no-response.yml create mode 100644 vendor/talk-android/.github/pull_request_template.md create mode 100644 vendor/talk-android/.github/pull_request_template.md.license create mode 100644 vendor/talk-android/.github/workflows/QA_keystore.jks.license create mode 100644 vendor/talk-android/.github/workflows/analysis.yml create mode 100644 vendor/talk-android/.github/workflows/assembleFlavors.yml create mode 100644 vendor/talk-android/.github/workflows/autoApproveSync.yml create mode 100644 vendor/talk-android/.github/workflows/check.yml create mode 100644 vendor/talk-android/.github/workflows/codeql.yml create mode 100644 vendor/talk-android/.github/workflows/detectNewJavaFiles.yml create mode 100644 vendor/talk-android/.github/workflows/fixup.yml create mode 100644 vendor/talk-android/.github/workflows/lib.sh create mode 100644 vendor/talk-android/.github/workflows/lib.sh.license create mode 100644 vendor/talk-android/.github/workflows/lint-translations.yml create mode 100644 vendor/talk-android/.github/workflows/pr-feedback.yml create mode 100644 vendor/talk-android/.github/workflows/qa.yml create mode 100644 vendor/talk-android/.github/workflows/renovate-approve-merge.yml create mode 100644 vendor/talk-android/.github/workflows/reuse.yml create mode 100644 vendor/talk-android/.github/workflows/scorecard.yml create mode 100644 vendor/talk-android/.github/workflows/stale.yml create mode 100644 vendor/talk-android/.github/workflows/unit-tests.yml create mode 100755 vendor/talk-android/.github/workflows/uploadArtifact.sh create mode 100644 vendor/talk-android/.gitignore create mode 100644 vendor/talk-android/.tx/config create mode 100644 vendor/talk-android/.tx/config.license create mode 100644 vendor/talk-android/CHANGELOG.md create mode 100644 vendor/talk-android/CODE_OF_CONDUCT.md create mode 100644 vendor/talk-android/CONTRIBUTING.md create mode 100644 vendor/talk-android/LICENCE.md create mode 100644 vendor/talk-android/LICENSES/AGPL-3.0-or-later.txt create mode 100644 vendor/talk-android/LICENSES/Apache-2.0.txt create mode 100644 vendor/talk-android/LICENSES/CC-BY-4.0.txt create mode 100644 vendor/talk-android/LICENSES/CC-BY-SA-3.0.txt create mode 100644 vendor/talk-android/LICENSES/CC0-1.0.txt create mode 100644 vendor/talk-android/LICENSES/GPL-3.0-or-later.txt create mode 100644 vendor/talk-android/LICENSES/LGPL-2.1-or-later.txt create mode 100644 vendor/talk-android/LICENSES/LGPL-3.0-or-later.txt create mode 100644 vendor/talk-android/LICENSES/LicenseRef-NextcloudTrademarks.txt create mode 100644 vendor/talk-android/LICENSES/LicenseRef-XTrademarks.txt create mode 100644 vendor/talk-android/LICENSES/MIT.txt create mode 100644 vendor/talk-android/README.F7CLOUD.md create mode 100644 vendor/talk-android/README.md create mode 100644 vendor/talk-android/REUSE.toml create mode 100644 vendor/talk-android/SECURITY.md create mode 100644 vendor/talk-android/SETUP.md create mode 100644 vendor/talk-android/app/build.f7cloud.gradle create mode 100644 vendor/talk-android/app/build.gradle create mode 100644 vendor/talk-android/app/build.quality.gradle create mode 100644 vendor/talk-android/app/lint.xml create mode 100644 vendor/talk-android/app/proguard-rules.pro create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/10.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/11.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/12.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/13.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/14.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/15.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/16.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/17.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/18.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/19.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/20.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/21.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/22.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/23.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/8.json create mode 100644 vendor/talk-android/app/schemas/ru.f7cloud.talk.data.source.local.TalkDatabase/9.json create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/ExampleInstrumentedTest.java create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/activities/MainActivityTest.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/data/database/dao/ChatBlocksDaoTest.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/data/database/dao/ChatMessagesDaoTest.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/data/database/migrations/MigrationsTest.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/ui/LoginIT.java create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/utils/ColorGeneratorTest.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/utils/ShareUtilsIT.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/utils/UriUtilsIT.kt create mode 100644 vendor/talk-android/app/src/androidTest/java/ru/f7cloud/talk/utils/VibrationUtilsTest.kt create mode 100644 vendor/talk-android/app/src/f7/AndroidManifest.xml create mode 100644 vendor/talk-android/app/src/f7/java/ru/f7cloud/talk/f7cloud/F7TalkUserSync.kt create mode 100644 vendor/talk-android/app/src/f7/res/values/setup.xml create mode 100644 vendor/talk-android/app/src/generic/AndroidManifest.xml create mode 100644 vendor/talk-android/app/src/generic/fastlane/metadata/android/tr-TR/full_description.txt create mode 100644 vendor/talk-android/app/src/generic/java/ru/f7cloud/talk/utils/ClosedInterfaceImpl.java create mode 100644 vendor/talk-android/app/src/gplay/AndroidManifest.xml create mode 100644 vendor/talk-android/app/src/gplay/java/ru/f7cloud/talk/jobs/GetFirebasePushTokenWorker.kt create mode 100644 vendor/talk-android/app/src/gplay/java/ru/f7cloud/talk/services/firebase/NCFirebaseMessagingService.kt create mode 100644 vendor/talk-android/app/src/gplay/java/ru/f7cloud/talk/utils/ClosedInterfaceImpl.kt create mode 100644 vendor/talk-android/app/src/main/AndroidManifest.xml create mode 100644 vendor/talk-android/app/src/main/assets/leafletMapMessagePreview.html create mode 100644 vendor/talk-android/app/src/main/assets/leafletMapMessagePreview.html.license create mode 100644 vendor/talk-android/app/src/main/ic_launcher-web.png create mode 100644 vendor/talk-android/app/src/main/java/fr/dudie/nominatim/client/TalkJsonNominatimClient.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/PhoneUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/AccountVerificationActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/BrowserLoginActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/ServerSelectionActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/SwitchAccountActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/data/LoginRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/data/io/LocalLoginDataSource.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/data/model/AccountItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/data/model/LoginResponseModels.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/data/network/NetworkLoginDataSource.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/account/viewmodels/BrowserLoginActivityViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/ActionBarProvider.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/BaseActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/CallActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/CallBaseActivity.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/CallStatus.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/CallViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/MainActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/ParticipantHandler.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/ParticipantUiState.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/activities/TakePhotoActivity.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/GeocodingAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/PredefinedStatusClickListener.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/PredefinedStatusListAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/PredefinedStatusViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/ReactionItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/ReactionItemClickListener.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/ReactionsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/ReactionsViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/AdvancedUserItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/ContactItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/ConversationItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/FlexibleItemViewType.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/GenericTextHeaderItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/LoadMoreResultsItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/MentionAutocompleteItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/MessageResultItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/MessagesTextHeaderItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/NotificationSoundItem.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/ParticipantItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/items/SpacerItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/AdjustableMessageHolderInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/CallStartedMessageInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/CommonMessageInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingDeckCardViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingLinkPreviewMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingLocationMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingPollMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingPreviewMessageViewHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingTextMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/IncomingVoiceMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/LinkPreview.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/MessagePayload.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingDeckCardViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingLinkPreviewMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingLocationMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingPollMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingPreviewMessageViewHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingTextMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/OutcomingVoiceMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/PreviewMessageInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/PreviewMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/Reaction.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/SystemMessageInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/SystemMessageViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/TalkMessagesListAdapter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/Thread.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/ThreadButton.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/UnreadNoticeMessageViewHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/adapters/messages/VoiceMessageInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/api/NcApi.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/api/NcApiCoroutines.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/application/F7cloudTalkApplication.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/arbitrarystorage/ArbitraryStorageManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/bottomsheet/items/BasicListItemWithImage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/bottomsheet/items/BottomSheets.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/bottomsheet/items/ListIconDialogAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/CallParticipantList.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/CallParticipantListNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/LocalCallParticipantModel.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/LocalCallParticipantModelNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/LocalStateBroadcaster.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/LocalStateBroadcasterMcu.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/LocalStateBroadcasterNoMcu.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/MediaConstraintsHelper.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/MessageSender.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/MessageSenderMcu.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/MessageSenderNoMcu.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/MutableLocalCallParticipantModel.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/RaisedHand.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/ReactionAnimator.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/AvatarWithFallback.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/ParticipantGrid.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/ParticipantTile.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/SelfVideoView.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/WebRTCVideoView.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/screenshare/ScreenShareComponent.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/call/components/screenshare/WebRtcScreenShareComponent.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/callbacks/MentionAutocompleteCallback.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/callnotification/CallNotificationActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/ChatActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/MessageInputFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/MessageInputVoiceRecordingFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/NoLongClickMovementMethod.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/OverflowMenu.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/ScheduleMessageCompose.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/ScheduledMessagesActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/TypingParticipant.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/ChatMessageRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/io/AudioFocusRequestManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/io/AudioRecorderManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/io/LifecycleAwareManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/io/MediaPlayerManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/io/MediaRecorderManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/model/ChatMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/network/ChatNetworkDataSource.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/network/OfflineFirstChatRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/data/network/RetrofitChatNetwork.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/viewmodels/ChatViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/viewmodels/MessageInputViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chat/viewmodels/ScheduledMessagesViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chooseaccount/StatusRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chooseaccount/StatusRepositoryImplementation.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/chooseaccount/StatusViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/components/ColoredStatusBar.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/components/StandardAppBar.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/components/VerticallyCenteredRow.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsApplication.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsScreen.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ContactsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ImageRequest.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/ShareType.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ContactItemRow.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ContactsAppBar.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ContactsItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ContactsList.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ContactsSearchAppBar.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/ConversationCreationOptions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contacts/components/Header.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contextchat/ContextChatView.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/contextchat/ContextChatViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversation/RenameConversationDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationcreation/ConversationCreationActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationcreation/ConversationCreationRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationcreation/ConversationCreationRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationcreation/ConversationCreationViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfo/ConversationInfoActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfo/CreateRoomRequest.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfo/GuestAccessHelper.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfo/Participants.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfoedit/data/ConversationInfoEditRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfoedit/data/ConversationInfoEditRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationinfoedit/viewmodel/ConversationInfoEditViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/ConversationsListActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/data/OfflineConversationsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/data/network/ConversationsNetworkDataSource.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/data/network/RetrofitConversationsNetwork.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/conversationlist/viewmodels/ConversationsListViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/BusModule.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/ContextModule.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/DaosModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/DatabaseModule.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/ManagerModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/RepositoryModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/RestModule.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/UtilsModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/dagger/modules/ViewModelModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/dao/ChatBlocksDao.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/dao/ChatMessagesDao.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/dao/ConversationsDao.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/mappers/ChatMessageMapUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/mappers/ConversationMapUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/model/ChatBlockEntity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/model/ChatMessageEntity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/model/ConversationEntity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/database/model/SendStatus.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/network/NetworkMonitor.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/network/NetworkMonitorImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/Migrations.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/TalkDatabase.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/ArrayListConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/CapabilitiesConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/ExternalSignalingServerConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/HashMapHashMapConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/LinkedHashMapConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/LinkedHashMapStringIntConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/PushConfigurationConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/SendStatusConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/ServerVersionConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/source/local/converters/SignalingSettingsConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/ArbitraryStorageMapper.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/ArbitraryStoragesDao.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/ArbitraryStoragesRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/ArbitraryStoragesRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/model/ArbitraryStorage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/storage/model/ArbitraryStorageEntity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/UserMapper.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/UsersDao.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/UsersRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/UsersRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/model/User.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/data/user/model/UserEntity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/diagnose/DiagnoseActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/diagnose/DiagnoseContentComposable.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/diagnose/DiagnoseViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/CertificateEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/ConfigurationChangeEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/ConversationsListFetchDataEvent.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/EventStatus.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/MoreMenuClickEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/NetworkEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/OpenConversationEvent.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/ProximitySensorEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/UserMentionClickEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/events/WebSocketCommunicationEvent.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/extensions/ImageViewExtensions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/extensions/LongFormatExtension.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/extensions/ParcelableExtensions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/BrowserFile.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/DavResponse.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/NCEncrypted.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/NCPermission.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/NCPreview.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/OCFavorite.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/OCId.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/models/properties/OCSize.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/webdav/DavUtils.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/webdav/ReadFilesystemOperation.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/filebrowser/webdav/ReadFolderListingOperation.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/fullscreenfile/FullScreenImageActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/fullscreenfile/FullScreenMediaActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/fullscreenfile/FullScreenTextViewerActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/interfaces/ClosedInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/interfaces/ConversationMenuInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/InvitationsActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/adapters/InvitationsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/data/Invitation.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/data/InvitationActionModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/data/InvitationsModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/data/InvitationsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/data/InvitationsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/invitation/viewmodels/InvitationsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/AccountRemovalWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/AddParticipantsToConversationWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/CapabilitiesWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/ContactAddressBookWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/DeleteConversationWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/DownloadFileToCacheWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/LeaveConversationWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/NotificationWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/PushRegistrationWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/SaveFileToStorageWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/ShareOperationWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/SignalingSettingsWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/UploadAndShareFilesWorker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/jobs/WebsocketConnectionsWorker.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/location/GeocodingActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/location/GeocodingResult.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/location/LocationPickerActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/lock/LockedActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/messagesearch/MessageSearchActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/messagesearch/MessageSearchHelper.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/messagesearch/MessageSearchViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/ExternalSignalingServer.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/ImportAccount.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/LoginData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/MessageDraft.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/RetrofitBucket.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/RingtoneSettings.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/SignatureVerification.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/TakePictureViewModel.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/ConversationModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/ReactionAddedModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/ReactionDeletedModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/SearchMessageEntry.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/StartCallRecordingModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/StopCallRecordingModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/domain/converters/DomainEnumNotificationLevelConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/AnyParceler.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/autocomplete/AutocompleteOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/autocomplete/AutocompleteOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/autocomplete/AutocompleteUser.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/Capabilities.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/CapabilitiesList.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/CapabilitiesOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/CapabilitiesOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/CoreCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/NotificationsCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/ProvisioningCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/RoomCapabilitiesOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/RoomCapabilitiesOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/ServerVersion.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/SpreedCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/ThemingCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/capabilities/UserStatusCapability.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatMessageJson.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatMessageMetaData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatOCSSingleMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatOverallSingleMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatShareOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatShareOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatShareOverviewOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatShareOverviewOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ChatUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/chat/ReadStatus.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/Conversation.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/ConversationEnums.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/RoomOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/RoomOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/RoomsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/RoomsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/password/PasswordData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/password/PasswordOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/conversations/password/PasswordOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/ConversationObjectTypeConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumActorTypeConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumLobbyStateConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumNotificationLevelConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumParticipantTypeConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumReactionActorTypeConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumReadOnlyConversationConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumRoomTypeConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/LoganSquareJodaTimeConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/ObjectParcelConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/ScopeConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/converters/UriTypeConverter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/generic/GenericMeta.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/generic/GenericOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/generic/GenericOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/generic/Status.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/hovercard/HoverCard.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/hovercard/HoverCardAction.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/hovercard/HoverCardOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/hovercard/HoverCardOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/invitation/Invitation.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/invitation/InvitationOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/invitation/InvitationOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/mention/Mention.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/mention/MentionOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/mention/MentionOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/Notification.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationAction.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationRichObject.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/notifications/NotificationsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/OpenGraphOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/OpenGraphObject.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/OpenGraphOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/OpenGraphResponse.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/Reference.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/opengraph/RichObject.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/AddParticipantOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/AddParticipantOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/Participant.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/ParticipantsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/ParticipantsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/TalkBan.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/TalkBanOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/participants/TalkBanOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/profile/CoreProfileAction.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/profile/Profile.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/profile/ProfileOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/profile/ProfileOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/DecryptedPushMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/NotificationUser.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/PushConfigurationState.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/PushRegistration.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/PushRegistrationOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/push/PushRegistrationOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reactions/ReactionVoter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reactions/ReactionsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reactions/ReactionsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reminder/Reminder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reminder/ReminderOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/reminder/ReminderOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/search/ContactsByNumberOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/search/ContactsByNumberOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/ExactSharees.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/Sharee.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/ShareesOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/ShareesOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/SharesData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/sharees/Value.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/DataChannelMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/NCIceCandidate.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/NCMessagePayload.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/NCSignalingMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/Signaling.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/SignalingOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/SignalingOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/FederationHelloAuthParams.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/FederationSettings.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/IceServer.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/SignalingSettings.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/SignalingSettingsOcs.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/signaling/settings/SignalingSettingsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/ClearAt.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/Status.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/StatusOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/StatusOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/StatusType.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/predefined/PredefinedStatus.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/predefined/PredefinedStatusOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/status/predefined/PredefinedStatusOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/testNotification/TestNotificationData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/testNotification/TestNotificationOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/testNotification/TestNotificationOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/Thread.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadAttendee.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadInfo.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/threads/ThreadsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/unifiedsearch/UnifiedSearchEntry.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/unifiedsearch/UnifiedSearchOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/unifiedsearch/UnifiedSearchOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/unifiedsearch/UnifiedSearchResponseData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userAbsence/UserAbsenceData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userAbsence/UserAbsenceOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userAbsence/UserAbsenceOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/Scope.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/UserProfileData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/UserProfileFieldsOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/UserProfileFieldsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/UserProfileOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/userprofile/UserProfileOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/ActorWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/AuthParametersWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/AuthWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/BaseWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/ByeWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/CallOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/CallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/ErrorOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/ErrorWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/EventOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/HelloOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/HelloResponseOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/HelloResponseWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/HelloWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/JoinedRoomOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/RoomFederationWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/RoomOverallWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/RoomPropertiesWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/RoomWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/models/json/websocket/ServerHelloResponseFeaturesWebSocketMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/openconversations/ListOpenConversationsActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/openconversations/adapters/OpenConversationsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/openconversations/data/OpenConversationsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/openconversations/data/OpenConversationsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/openconversations/viewmodels/OpenConversationsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollCreateOptionItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollCreateOptionViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollCreateOptionsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollCreateOptionsItemListener.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultHeaderItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultHeaderViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultItemClickListener.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultVoterItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultVoterViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultVotersOverviewItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultVotersOverviewViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/adapters/PollResultsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/model/Poll.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/model/PollDetails.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/PollRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/PollRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/model/PollDetailsResponse.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/model/PollOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/model/PollOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/repositories/model/PollResponse.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/ui/PollCreateDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/ui/PollLoadingFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/ui/PollMainDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/ui/PollResultsFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/ui/PollVoteFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/viewmodels/PollCreateViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/viewmodels/PollMainViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/viewmodels/PollResultsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/polls/viewmodels/PollVoteViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/presenters/MentionAutocompletePresenter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/profile/ProfileActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/raisehand/RequestAssistanceModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/raisehand/RequestAssistanceRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/raisehand/RequestAssistanceRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/raisehand/WithdrawRequestAssistanceModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/raisehand/viewmodel/RaiseHandViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/receivers/DirectReplyReceiver.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/receivers/DismissRecordingAvailableReceiver.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/receivers/MarkAsReadReceiver.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/receivers/PackageReplacedReceiver.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/receivers/ShareRecordingToChatReceiver.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/SelectionInterface.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/activities/RemoteFileBrowserActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsListViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/adapters/RemoteFileBrowserItemsViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/model/RemoteFileBrowserItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/repositories/RemoteFileBrowserItemsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/remotefilebrowser/viewmodels/RemoteFileBrowserItemsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/callrecording/CallRecordingRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/callrecording/CallRecordingRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/conversations/ConversationsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/reactions/ReactionsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/reactions/ReactionsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/unifiedsearch/UnifiedSearchRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/repositories/unifiedsearch/UnifiedSearchRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/services/CallForegroundService.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/settings/SettingsActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/activities/SharedItemsActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/adapters/SharedItemsAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/adapters/SharedItemsGridViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/adapters/SharedItemsListViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/adapters/SharedItemsViewHolder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedDeckCardItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedFileItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedItemType.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedItems.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedLocationItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedOtherItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedPinnedItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/model/SharedPollItem.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/repositories/SharedItemsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/repositories/SharedItemsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/shareditems/viewmodels/SharedItemsViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/CallParticipantMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/ConversationMessageNotifier.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/LocalParticipantMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/OfferMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/ParticipantListMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/SignalingMessageReceiver.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/SignalingMessageSender.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/signaling/WebRtcMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/threadsoverview/ThreadsOverviewActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/threadsoverview/components/ThreadRow.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/threadsoverview/data/ThreadsRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/threadsoverview/data/ThreadsRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/threadsoverview/viewmodels/ThreadsOverviewViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/TranslateRepository.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/TranslateRepositoryImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/Language.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/LanguagesData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/LanguagesOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/LanguagesOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/TranslateData.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/TranslateOCS.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/repositories/model/TranslationsOverall.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/ui/TranslateActivity.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/translate/viewmodels/TranslateViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/BackgroundVoiceMessageCard.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/ComposeChatAdapter.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/MessageInput.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/MicInputCloud.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/PinnedMessage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/PlaybackSpeedControl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/StatusDrawable.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/SwipeToCloseLayout.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/WaveformSeekBar.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/bottom/sheet/ProfileBottomSheet.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/AttachmentDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/AudioOutputDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/ChooseAccountDialogCompose.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/ChooseAccountShareToDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/ConversationsListBottomDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/DateTimeCompose.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/DialogBanListFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/FileAttachmentPreviewFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/FilterConversationFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/MessageActionsDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/MoreCallActionsDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/OnlineStatusBottomDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/PinnedMessageOptionsDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/SaveToStorageDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/ScopeDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/SetPhoneNumberDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/ShowReactionsDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/SortingOrderDialogFragment.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/StatusMessageBottomDialogFragment.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/dialog/TempMessageActionsDialog.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/recyclerview/MessageSwipeActions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/recyclerview/MessageSwipeCallback.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/MaterialSchemesProvider.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/MaterialSchemesProviderImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/ServerThemeImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/TalkSpecificViewThemeUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/ThemeModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/ui/theme/ViewThemeUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/upload/chunked/Chunk.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/upload/chunked/ChunkFromFileRequestBody.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/upload/chunked/ChunkedFileUploader.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/upload/chunked/OnDataTransferProgressListener.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/upload/normal/FileUploader.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/users/UserManager.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/AccountUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ApiUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/AppCompatActivityExtensions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/AudioUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/AuthenticatorService.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/BitmapShrinker.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/BrandingUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/CapabilitiesUtil.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/CharPolicy.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ChatMessageUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ColorGenerator.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ContactUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ContextExtensions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ConversationUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DateConstants.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DateUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DeviceUtils.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DisplayUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DoNotDisturbUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/DrawableUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/EmojiTextInputEditText.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FABAwareScrollingViewBehavior.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileSortOrder.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileSortOrderByDate.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileSortOrderByName.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileSortOrderBySize.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/FileViewerUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ImageEmojiEditText.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/LoggingUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/Mimetype.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/MimetypeUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/NoSupportedApiException.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/NotificationUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ParticipantPermissions.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/PickImage.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/PushUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ReceiverFlag.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/RemoteFileUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/SecurityUtils.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ShareUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/SyncAdapter.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/SyncService.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/TalkFileProvider.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/TextDrawable.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/TextMatchers.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/UriUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/UserIdUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/VibrationUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/animations/PulseAnimation.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/animations/ViewHidingBehaviourAnimation.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/bundle/BundleKeys.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/arbitrarystorage/ArbitraryStorageModule.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/user/CurrentUserProvider.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/user/CurrentUserProviderImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/user/CurrentUserProviderOld.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/user/CurrentUserProviderOldImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/database/user/UserModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/message/MessageCheckboxUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/message/MessageUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/message/SendMessageUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/permissions/PlatformPermissionUtil.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/permissions/PlatformPermissionUtilImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/power/PowerManagerUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/power/ProximityLock.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/preferences/AppPreferences.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/preferences/AppPreferencesImpl.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/preview/ComposePreviewUtils.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/preview/ComposePreviewUtilsDaos.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/rx/DisposableSet.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/rx/SearchViewObservable.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/singletons/ApplicationWideCurrentRoomHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/singletons/ApplicationWideMessageHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/singletons/AvatarStatusCodeHolder.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ssl/KeyManager.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ssl/SSLSocketFactoryCompat.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/ssl/TrustManager.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/utils/text/Spans.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/viewmodels/CallRecordingViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/viewmodels/GeoCodingViewModel.kt create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/DataChannelMessageNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/Globals.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/PeerConnectionNotifier.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/PeerConnectionWrapper.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/ProximitySensor.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/WebRTCUtils.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/WebRtcAudioManager.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/WebRtcBluetoothManager.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/WebSocketConnectionHelper.java create mode 100644 vendor/talk-android/app/src/main/java/ru/f7cloud/talk/webrtc/WebSocketInstance.kt create mode 100644 vendor/talk-android/app/src/main/java/third/parties/daveKoeller/AlphanumComparator.java create mode 100644 vendor/talk-android/app/src/main/java/third/parties/fresco/BetterImageSpan.kt create mode 100644 vendor/talk-android/app/src/main/res/anim/popup_animation.xml create mode 100644 vendor/talk-android/app/src/main/res/animator/appbar_elevation_off.xml create mode 100644 vendor/talk-android/app/src/main/res/animator/appbar_elevation_on.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-land/link_text_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/account_circle_48dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/account_circle_96dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_cellphone.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_chevron_right.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_document.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_group.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_group_mentions.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_link.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_location.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_lock.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_circular_mail.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_close_search.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_contacts.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_link.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/ic_password.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/icon_circular_phone.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable-night/icon_circular_team.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/accent_circle.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/account_circle_48dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/account_circle_96dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/all_inclusive_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_article_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_audiotrack_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_bar_chart_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_block_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_calendar_month_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_calendar_today_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_chat_bubble_outline_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_contacts_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_download_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_error_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_error_outline_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_format_list_bulleted_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_image_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_info_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_insert_drive_file_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_location_pin_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_lock_open_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_mic_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_notifications_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_photo_library_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_report_problem_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_schedule_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_stop_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_tag_faces_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_unfold_less_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_unfold_more_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/baseline_video_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/borderless_btn.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/current_location_circle.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/cutout_circle.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/deck.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/forward_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_account_plus.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_add_grey600_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_alphabetical_asc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_alphabetical_desc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_arrow_back_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_arrow_forward_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_av_timer_timer_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_document.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_federation.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_group.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_group_small.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_link.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_mail.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_avatar_team_small.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_arrow_downward_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_attach_file_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_bar_chart_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_bluetooth_audio_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_close_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_deck_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_do_not_touch_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_error_outline_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_filter_list_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_flash_off_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_flash_on_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_flip_camera_android_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_gps_fixed_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_headset_mic_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_keyboard_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_location_on_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_location_on_red_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_mic_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_mic_red_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_notifications_off_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_pause_voice_message_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_person_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_person_black_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_phone_in_talk_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_phone_missed_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_photo_camera_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_picture_in_picture_alt_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_play_arrow_voice_message_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_translate_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_baseline_videocam_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_call_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_call_end_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_call_grey_600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_call_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_cancel_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_cancel_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_cellphone.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check_all.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check_circle.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_check_circle_outlined.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_chevron_right.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_document.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_group.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_group_mentions.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_link.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_location.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_lock.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_circular_mail.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_clear_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_close_search.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_comment.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_contacts.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_content_copy.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_crop_16_9.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_crop_4_3.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_delete.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_delete_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_delete_grey600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_dots_horizontal.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_dots_horizontal_white.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_edit.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_edit_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_edit_note_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_email.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_folder.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_folder_multiple_image.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_hand_back_left.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_high_quality.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_info_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_insert_emoticon_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_keyboard_arrow_down.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_keyboard_arrow_up.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_keyboard_double_arrow_down.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_link.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_link_black_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_link_grey600_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_list_empty_error.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_lock_grey600_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_lock_open_grey600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_lock_plus_grey600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_lock_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_logo.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_low_quality.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_map_marker.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mark_chat_read_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mark_chat_unread_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_menu.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mic_grey_600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mic_off_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mic_white_24px.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_application_pdf.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_audio.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_file.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_folder.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_folder_shared.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_image.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_link.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_location.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_package_x_generic.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_text.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_text_calendar.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_text_code.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_text_vcard.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_video.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_whiteboard.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_x_office_document.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_x_office_presentation.xml create mode 100755 vendor/talk-android/app/src/main/res/drawable/ic_mimetype_x_office_spreadsheet.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_modification_asc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_modification_desc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_more_horiz_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_note_to_self.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_notification.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_password.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_pencil_grey600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_people_group_black_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_phone.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_phone_small.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_refresh.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_reply.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_room_service_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_search_grey.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_search_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_security_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_settings.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_share_action.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_share_variant.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_signal_wifi_off_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_size_asc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_size_desc.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_star_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_star_border_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_switch_video_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_talk.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_timer_black_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_twitter.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_unarchive_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_user.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_user_status_away.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_user_status_busy.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_user_status_dnd.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_user_status_invisible.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_videocam_grey_600_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_videocam_off_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_videocam_white_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_volume_mute_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_volume_up_white_24dp.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_warning_white.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/ic_web.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/icon_circular_phone.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/icon_circular_team.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/incoming_gradient.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/keep_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/keep_off_24px.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/launch_screen.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/link_text_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/link_text_no_preview_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/mention_chip.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/online_status.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_access_time_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_archive_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_forum_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_monitor_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_notifications_active_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_qr_code_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_schedule_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/outline_schedule_send_24.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/reaction_self_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/reaction_self_bottom_sheet_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/record_start.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/record_starting.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/record_stop.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/reply_background.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/round_bgnd.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/shape_grouped_incoming_message.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/shape_grouped_outcoming_message.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/shape_incoming_message.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/shape_outcoming_message.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/shape_oval.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/trashbin.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/upload.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/upload_white.xml create mode 100644 vendor/talk-android/app/src/main/res/drawable/voice_message_outgoing_seek_bar_slider.xml create mode 100644 vendor/talk-android/app/src/main/res/layout-land/activity_profile.xml create mode 100644 vendor/talk-android/app/src/main/res/layout-land/activity_translate.xml create mode 100644 vendor/talk-android/app/src/main/res/layout-land/reference_inside_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/account_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_account_verification.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_chat.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_conversation_info.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_conversation_info_edit.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_conversations.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_full_screen_image.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_full_screen_media.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_full_screen_text.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_geocoding.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_invitations.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_location.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_locked.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_main.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_message_search.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_open_conversations.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_profile.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_remote_file_browser.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_server_selection.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_settings.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_shared_items.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_switch_account.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_take_picture.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_translate.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/activity_web_view_login.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/ban_item_list.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/call_activity.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/call_notification_activity.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/call_started_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/call_states.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/create_thread_view.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/current_account_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_attachment.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_audio_output.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_ban_participant.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_choose_account_share_to.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_conversation_operations.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_create_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_file_attachment_preview.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_filter_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_message_actions.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_message_reactions.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_more_call_actions.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_password.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_poll_create.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_poll_loading.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_poll_main.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_poll_results.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_poll_vote.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_rename_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_scope.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_set_online_status.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_set_phone_number.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_set_status_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/dialog_temp_message_actions.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/edit_message_view.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/empty_list.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/federated_invitation_hint.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/fragment_dialog_ban_list.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/fragment_message_input.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/fragment_message_input_voice_recording.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/geocoding_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_deck_card_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_link_preview_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_location_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_poll_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_preview_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_text_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_text_message_shimmer.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_incoming_voice_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_deck_card_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_link_preview_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_location_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_poll_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_preview_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_text_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_custom_outcoming_voice_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_event_schedule.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_guest_access_settings.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_message_quote.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_notification_settings.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_reactions_tab.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_recording_consent.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_spacer.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_system_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_thread_title.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/item_webinar_info.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/lobby_view.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/menu_item_sheet.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/no_saved_messages_view.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/notifications_warning.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/out_of_office_view.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/poll_create_options_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/poll_result_header_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/poll_result_voter_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/poll_result_voters_overview_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/predefined_status.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/reaction_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/reactions_inside_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/reference_inside_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/remainder_to_delete_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_browser_file.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_contact.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_conversation_info_participant.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_conversation_with_last_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_conversation_with_last_message_shimmer.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_invitation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_load_more.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_notification_sound.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_open_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_search_message.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/rv_item_title_header.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/search_layout.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/shared_item_grid.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/shared_item_list.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/sorting_order_fragment.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/user_info_details_table_item.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/user_info_details_table_item_shimmer.xml create mode 100644 vendor/talk-android/app/src/main/res/layout/view_message_input.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/chat_call_menu.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/chat_send_menu.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_conversation.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_conversation_info.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_conversation_info_edit.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_conversation_plus_filter.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_geocoding.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_locationpicker.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_preview.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_profile.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_search.xml create mode 100644 vendor/talk-android/app/src/main/res/menu/menu_share_files.xml create mode 100644 vendor/talk-android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 vendor/talk-android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/main/res/raw/librem_by_feandesign_call.ogg create mode 100644 vendor/talk-android/app/src/main/res/raw/librem_by_feandesign_message.ogg create mode 100644 vendor/talk-android/app/src/main/res/raw/next_voice_message_doodle.ogg create mode 100644 vendor/talk-android/app/src/main/res/raw/tr110_1_kap8_3_freiton1.ogg create mode 100644 vendor/talk-android/app/src/main/res/values-ar/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-b+en+001/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-be/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-bg-rBG/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ca/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-cs-rCZ/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-da/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-de/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-el/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-es-rEC/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-es/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-et-rEE/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-eu/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-fa/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-fi-rFI/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-fr/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ga/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-gl/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-hr/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-hu-rHU/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-it/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ja-rJP/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ko/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-land/dimens.xml create mode 100644 vendor/talk-android/app/src/main/res/values-lo/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-lt-rLT/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-nb-rNO/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-night/colors.xml create mode 100644 vendor/talk-android/app/src/main/res/values-nl/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-pl/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-pt-rBR/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ru/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sc/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sk-rSK/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sl/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sr/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sv/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sw/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-sw600dp/dimens.xml create mode 100644 vendor/talk-android/app/src/main/res/values-tr/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-ug/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-uk/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-v27/styles.xml create mode 100644 vendor/talk-android/app/src/main/res/values-v28/arrays.xml create mode 100644 vendor/talk-android/app/src/main/res/values-v28/defaults.xml create mode 100644 vendor/talk-android/app/src/main/res/values-w820dp/dimens.xml create mode 100644 vendor/talk-android/app/src/main/res/values-zh-rCN/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-zh-rHK/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values-zh-rTW/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values/arrays.xml create mode 100644 vendor/talk-android/app/src/main/res/values/attrs.xml create mode 100644 vendor/talk-android/app/src/main/res/values/bool.xml create mode 100644 vendor/talk-android/app/src/main/res/values/colors.xml create mode 100644 vendor/talk-android/app/src/main/res/values/defaults.xml create mode 100644 vendor/talk-android/app/src/main/res/values/dimens.xml create mode 100644 vendor/talk-android/app/src/main/res/values/setup.xml create mode 100644 vendor/talk-android/app/src/main/res/values/strings.xml create mode 100644 vendor/talk-android/app/src/main/res/values/styles.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/auth.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/automotive_app_desc.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/backup_config.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/chip_others.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/chip_you.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/contacts.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/file_provider_paths.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/network_security_config.xml create mode 100644 vendor/talk-android/app/src/main/res/xml/syncadapter.xml create mode 100644 vendor/talk-android/app/src/qa/ic_launcher-web.png create mode 100644 vendor/talk-android/app/src/qa/java/ru/f7cloud/talk/utils/ClosedInterfaceImpl.java create mode 100644 vendor/talk-android/app/src/qa/res/drawable/ic_launcher_background.xml create mode 100644 vendor/talk-android/app/src/qa/res/drawable/ic_launcher_foreground.xml create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-hdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-mdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-xhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/qa/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 vendor/talk-android/app/src/qa/res/values/setup.xml create mode 100644 vendor/talk-android/app/src/test/java/android/util/Log.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/activities/CallViewModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/activities/ParticipantHandlerTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/CallParticipantListExternalSignalingTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/CallParticipantListInternalSignalingTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/CallParticipantListTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/LocalCallParticipantModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/LocalStateBroadcasterMcuTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/LocalStateBroadcasterNoMcuTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/LocalStateBroadcasterTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/MessageSenderMcuTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/MessageSenderNoMcuTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/call/MessageSenderTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/contacts/ContactsViewModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/contacts/apiService/FakeItem.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/contacts/repository/FakeRepositoryError.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/contacts/repository/FakeRepositorySuccess.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/conversationinfo/viewmodel/ConversationInfoViewModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/json/ConversationConversionTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/login/data/LoginRepositoryTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/login/data/network/NetworkLoginDataSourceTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/messagesearch/MessageSearchHelperTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverCallParticipantTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverLocalParticipantTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverOfferTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverParticipantListTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/signaling/SignalingMessageReceiverWebRtcTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/test/fakes/FakeCallRecordingRepository.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/test/fakes/FakeUnifiedSearchRepository.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/utils/BundleKeysTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/utils/DoNotDisturbUtilsTest.java create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/utils/ParticipantPermissionsTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/utils/UserIdUtilsTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/viewmodels/AbstractViewModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/viewmodels/CallRecordingViewModelTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/webrtc/DataChannelMessageNotifierTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/webrtc/GlobalsTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/webrtc/PeerConnectionNotifierTest.kt create mode 100644 vendor/talk-android/app/src/test/java/ru/f7cloud/talk/webrtc/PeerConnectionWrapperTest.kt create mode 100644 vendor/talk-android/app/src/test/resources/RoomOverallExample_APIv1.json create mode 100644 vendor/talk-android/app/src/test/resources/RoomOverallExample_APIv2.json create mode 100644 vendor/talk-android/app/src/test/resources/RoomOverallExample_APIv4.json create mode 100644 vendor/talk-android/app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker create mode 100644 vendor/talk-android/build.gradle create mode 100644 vendor/talk-android/contribute/developer-certificate-of-origin create mode 100644 vendor/talk-android/contribute/developer-certificate-of-origin.license create mode 100644 vendor/talk-android/detekt.yml create mode 100644 vendor/talk-android/docs/TURN.md create mode 100644 vendor/talk-android/docs/branching.png create mode 100644 vendor/talk-android/docs/branching.png.license create mode 100644 vendor/talk-android/docs/branching.svg create mode 100644 vendor/talk-android/docs/branching.svg.license create mode 100644 vendor/talk-android/docs/gplayDebugBuildVariant.png create mode 100644 vendor/talk-android/docs/gplayDebugBuildVariant.png.license create mode 100644 vendor/talk-android/docs/grantNotificationPermissionAfterInstall.png create mode 100644 vendor/talk-android/docs/grantNotificationPermissionAfterInstall.png.license create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationDialog.png create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationDialog.png.license create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationSelectAllApps.png create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationSelectAllApps.png.license create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationTurnOffSwitch.png create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimizationTurnOffSwitch.png.license create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimization_newerAndroid_allowBackgroundUsage.png create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimization_newerAndroid_allowBackgroundUsage.png.license create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimization_newerAndroid_unrestricted.png create mode 100644 vendor/talk-android/docs/ignoreBatteryOptimization_newerAndroid_unrestricted.png.license create mode 100644 vendor/talk-android/docs/notificationSettingsExample.png create mode 100644 vendor/talk-android/docs/notificationSettingsExample.png.license create mode 100644 vendor/talk-android/docs/notifications.md create mode 100644 vendor/talk-android/docs/notificationsNotSetUpCorrectlyWarning.png create mode 100644 vendor/talk-android/docs/notificationsNotSetUpCorrectlyWarning.png.license create mode 100644 vendor/talk-android/docs/semantic_versioning_code.png create mode 100644 vendor/talk-android/docs/semantic_versioning_code.png.license create mode 100644 vendor/talk-android/drawable_resources/icon-background.svg create mode 100644 vendor/talk-android/drawable_resources/icon-background.svg.license create mode 100644 vendor/talk-android/drawable_resources/icon-foreground.svg create mode 100644 vendor/talk-android/drawable_resources/icon-foreground.svg.license create mode 100644 vendor/talk-android/drawable_resources/icon-foreground_qa.svg create mode 100644 vendor/talk-android/drawable_resources/icon-foreground_qa.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/account-circle.svg create mode 100644 vendor/talk-android/drawable_resources/other/account-circle.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_document.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_document.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_group.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_group.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_link.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_link.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_location.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_location.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_lock.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_lock.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/circular_mail.svg create mode 100644 vendor/talk-android/drawable_resources/other/circular_mail.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/file-icon-black-24h.svg create mode 100644 vendor/talk-android/drawable_resources/other/file-icon-black-24h.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/file-icon.svg create mode 100644 vendor/talk-android/drawable_resources/other/file-icon.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/file-password-request.svg create mode 100644 vendor/talk-android/drawable_resources/other/file-password-request.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/ic_crop_16_9.svg create mode 100644 vendor/talk-android/drawable_resources/other/ic_crop_16_9.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/ic_crop_4_3.svg create mode 100644 vendor/talk-android/drawable_resources/other/ic_crop_4_3.svg.license create mode 100644 vendor/talk-android/drawable_resources/other/ic_low_quality.svg create mode 100644 vendor/talk-android/drawable_resources/other/ic_low_quality.svg.license create mode 100644 vendor/talk-android/fastlane/Appfile create mode 100644 vendor/talk-android/fastlane/Appfile.license create mode 100644 vendor/talk-android/fastlane/metadata/android/cs-CZ/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/cs-CZ/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/cs-CZ/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/de-DE/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/de-DE/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/de-DE/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/el-GR/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/el-GR/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/featureGraphic.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/icon.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/conversationList_dark.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/conversationList_light.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/markdown_light.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/searchParticipant_light.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/serverSelection.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/settings_light.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/voiceCall.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/images/phoneScreenshots/voiceRecord_light.png create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/en-US/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/es-ES/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/es-ES/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/es-ES/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/fr-FR/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/fr-FR/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/fr-FR/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/is-IS/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/is-IS/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/it-IT/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/it-IT/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/it-IT/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/nl-NL/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/nl-NL/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/nl-NL/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/pl-PL/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/pl-PL/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/pt-BR/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/pt-BR/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/pt-BR/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/ru-RU/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/ru-RU/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/ru-RU/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/sr-SR/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/sr-SR/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/sr-SR/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/tr-TR/full_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/tr-TR/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/tr-TR/title.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/vi-VI/short_description.txt create mode 100644 vendor/talk-android/fastlane/metadata/android/vi-VI/title.txt create mode 100644 vendor/talk-android/gradle/verification-keyring.keys create mode 100644 vendor/talk-android/gradle/verification-keyring.keys.license create mode 100644 vendor/talk-android/gradle/verification-metadata.xml create mode 100644 vendor/talk-android/gradle/verification-metadata.xml.license create mode 100644 vendor/talk-android/gradle/wrapper/gradle-wrapper.jar create mode 100644 vendor/talk-android/gradle/wrapper/gradle-wrapper.jar.license create mode 100644 vendor/talk-android/gradle/wrapper/gradle-wrapper.properties create mode 100644 vendor/talk-android/gradle/wrapper/gradle-wrapper.properties.license create mode 100755 vendor/talk-android/gradlew create mode 100644 vendor/talk-android/gradlew.bat create mode 100644 vendor/talk-android/gradlew.bat.license create mode 100644 vendor/talk-android/gradlew.license create mode 100644 vendor/talk-android/renovate.json5 create mode 100644 vendor/talk-android/renovate.json5.license create mode 100755 vendor/talk-android/scripts/analysis/analysis-wrapper.sh create mode 100755 vendor/talk-android/scripts/analysis/getBranchName.sh create mode 100644 vendor/talk-android/scripts/analysis/lint-results.txt create mode 100644 vendor/talk-android/scripts/analysis/lint-results.txt.license create mode 100644 vendor/talk-android/scripts/analysis/lint-up.rb create mode 100755 vendor/talk-android/scripts/analysis/spotbugs-up.rb create mode 100755 vendor/talk-android/scripts/analysis/spotbugsComparison.py create mode 100755 vendor/talk-android/scripts/analysis/spotbugsSummary.py create mode 100755 vendor/talk-android/scripts/checkGplayLimitation.sh create mode 100755 vendor/talk-android/scripts/hooks/pre-commit create mode 100755 vendor/talk-android/scripts/hooks/pre-push create mode 100755 vendor/talk-android/scripts/lib.sh create mode 100644 vendor/talk-android/scripts/metadata/generate_metadata.py create mode 100644 vendor/talk-android/scripts/repo create mode 100644 vendor/talk-android/scripts/repo.license create mode 100644 vendor/talk-android/scripts/tools/OxygenConversion.MD create mode 100755 vendor/talk-android/scripts/wait_for_emulator.sh create mode 100644 vendor/talk-android/settings.gradle create mode 100644 vendor/talk-android/spotbugs-filter.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be23b21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Gradle / Android build +/.gradle/ +/build/ +**/build/ +!**/src/**/build/ +/local.properties +/key.properties +*.jks +*.keystore + +# IDE +/.idea/ +*.iml +.DS_Store + +# Firebase (положите свой google-services.json локально) +/app/google-services.json + +# APK / артефакты +*.apk +*.aab + +# Логи и временные файлы +*.log +*.tmp +.cxx/ diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..2058aa9 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,22 @@ +# Third-Party Notices — F7cloud Mobile + +## Nextcloud Talk for Android + +F7cloud Mobile integrates components derived from and/or intended to interoperate with +[Nextcloud Talk for Android](https://github.com/nextcloud/talk-android). + +- **Version vendored:** v23.0.0 +- **Location:** `vendor/talk-android/` +- **License:** GNU General Public License v3.0 or later (GPL-3.0-or-later) +- **Copyright:** Nextcloud GmbH and Nextcloud contributors + +The full source code of Nextcloud Talk for Android is available at: +https://github.com/nextcloud/talk-android/tree/v23.0.0 + +When native Talk modules from this codebase are linked into F7cloud Mobile, the combined +work is distributed under the terms of the GPL-3.0-or-later. Corresponding source code +will be made available alongside this application. + +## Firebase Cloud Messaging + +Push notifications use Google Firebase Cloud Messaging (proprietary Google SDK). diff --git a/PROJECT-STATUS.md b/PROJECT-STATUS.md new file mode 100644 index 0000000..9d6738d --- /dev/null +++ b/PROJECT-STATUS.md @@ -0,0 +1,317 @@ +# F7cloud Mobile — статус проекта и журнал работ + +Документ описывает текущее состояние нативного Android-приложения **f7cloud-mobile**, выполненные задачи, процесс сборки APK и актуальную версию. + +**Дата обновления:** 7 июля 2026 +**Расположение проекта:** `/var/www/f7cloud/f7cloud-mobile` +**Сервер:** `https://forbion.f7cloud.ru` + +--- + +## Текущая версия + +| Параметр | Значение | +|----------|----------| +| **versionName** | `0.5.113` | +| **versionCode** | `121` | +| **applicationId** | `ru.forbion.f7cloud.mobile` | +| **Последний APK (debug)** | `app/build/outputs/apk/debug/f7cloud-mobile-v0.5.113-121-debug.apk` | +| **Размер APK** | ~130 МБ | + +Версия задаётся в `app/build.gradle`: + +```gradle +versionCode 121 +versionName '0.5.113' +``` + +При каждой значимой сборке `versionCode` увеличивается на 1, `versionName` — по схеме `0.5.xxx`. + +--- + +## Сборка APK + +### Чем собирается + +Сборка выполняется **на сервере** в каталоге проекта с помощью **Gradle Wrapper** — отдельный от legacy-проекта `android-webview`. + +| Компонент | Версия | +|-----------|--------| +| Gradle | **9.3.0** (`gradle/wrapper/gradle-wrapper.properties`) | +| Android Gradle Plugin (AGP) | **8.13.2** | +| Kotlin | **2.3.0** | +| Jetpack Compose BOM | **2025.02.00** | +| compileSdk / targetSdk | **36** | +| minSdk | **26** | +| JDK на сервере | **OpenJDK 21** | + +> С v0.5.27 используется собственный wrapper в `f7cloud-mobile`. Старый способ через `android-webview` (Gradle 8.7, AGP 8.2) **не поддерживается** — несовместим с Kotlin 2.3. + +### Команды + +**Debug APK** (основной способ для тестирования на устройстве): + +```bash +cd /var/www/f7cloud/f7cloud-mobile +./gradlew assembleDebug +chown www-data:www-data app/build/outputs/apk/debug/*.apk +``` + +**Release APK** (с minify и shrink resources): + +```bash +cd /var/www/f7cloud/f7cloud-mobile +./gradlew assembleRelease +``` + +**Сборка отдельного модуля** (проверка компиляции без полной сборки app): + +```bash +./gradlew :feature:tasks:compileDebugKotlin +``` + +### Имя выходного файла + +Шаблон задаётся в `app/build.gradle`: + +``` +f7cloud-mobile-v{versionName}-{versionCode}-{variant}.apk +``` + +Пример: `f7cloud-mobile-v0.5.113-121-debug.apk` + +### Где лежит APK + +``` +/var/www/f7cloud/f7cloud-mobile/app/build/outputs/apk/debug/ +/var/www/f7cloud/f7cloud-mobile/app/build/outputs/apk/release/ +``` + +### Как собирает ассистент (Cursor Agent) + +1. Вносит изменения в Kotlin/Compose-код. +2. При необходимости увеличивает `versionCode` / `versionName` в `app/build.gradle`. +3. Запускает `./gradlew assembleDebug` (или `:app:assembleDebug`). +4. Проверяет, что сборка завершилась с `BUILD SUCCESSFUL`. +5. Сообщает путь к APK. + +Коммиты в git создаются **только по явной просьбе** пользователя. + +--- + +## Архитектура проекта + +Нативное приложение на **Kotlin + Jetpack Compose**. Не WebView-оболочка (legacy: `android-webview`). + +``` +f7cloud-mobile/ +├── app/ # Точка входа, навигация (AppScaffold, AppNavigation) +├── core/ +│ ├── auth/ # Сессия, авторизация +│ ├── network/ # HTTP, WebDAV, CalDAV, OCS API +│ ├── designsystem/ # F7Colors, компоненты UI, нижняя панель, меню +│ ├── push/ # Firebase push-уведомления +│ ├── database/ # Room (локальный кэш) +│ └── ui/ # Общие UI-утилиты +├── feature/ +│ ├── files/ # Файлы (WebDAV) +│ ├── talk/ # Talk UI, офлайн-чат +│ ├── talk-native/ # Нативные звонки (обёртка vendor/talk-android) +│ ├── mail/ # Почта +│ ├── calendar/ # Календарь (CalDAV) +│ ├── contacts/ # Контакты (CardDAV) +│ ├── tasks/ # Задачи (CalDAV) +│ ├── deck/ # Карточки (Deck) +│ └── f7support/ # Техподдержка +├── vendor/talk-android/ # Форк Nextcloud Talk (нативные конференции) +└── design/ # Макеты PNG, токены, CSS-эталоны +``` + +### Навигация + +- Нижняя панель зависит от активной вкладки (`F7BottomBarConfig.kt`). +- Меню приложений — полноэкранная панель `F7AppMenuSheet` (кнопка «гамбургер»). +- Стартовая вкладка после входа — **Файлы**. +- В активной конференции нижняя панель **скрывается** (`talkInRoom`). + +### Дизайн-система + +Цвета и компоненты из темы forbion (`core/designsystem/F7Colors.kt`): + +| Токен | Значение | +|-------|----------| +| Primary | `#70B62B` | +| Background | `#FBFBFB` | +| Surface | `#FFFFFF` | +| Text primary | `#151515` | +| Text secondary | `#808080` | +| Border | `#E6E6E6` | + +Иконки подгружаются с сервера: `https://forbion.f7cloud.ru/themes/forbion/images/...` + +Макеты для вёрстки: `design/screens/`, эталонный CSS веб-версии: `themes/forbion/css/pages/`. + +--- + +## Выполненные работы (хронология) + +Ниже — основные блоки работ, выполненных в ходе разработки нативного приложения (сессии Cursor Agent, весна–лето 2026). + +### Общая платформа + +- Переход на Kotlin 2.3 + Compose + Gradle 9.3 / AGP 8.13. +- Модульная архитектура `app` / `core` / `feature` / `vendor`. +- Глобальный safe area (`enableEdgeToEdge`, `F7WindowInsets`) — исправление перекрытия статус-бара на Samsung Z и других устройствах с вырезом. +- Swipe-to-dismiss для оверлеев (`F7OverlayNavigation.kt`, `f7SwipeFromRightToDismiss`). +- Push-уведомления через Firebase (`core/push`). + +### Меню приложений (`F7AppMenuSheet`) + +- Полноэкранная белая панель `#FBFBFB` без затемнения (по `_header.css`). +- Поиск приложений сверху. +- Сетка 4 колонки, иконки 62×62 dp, подписи 12sp bold. +- Нижняя панель остаётся видимой (90 dp снизу). +- Внешние сайты (Bitrix, 1C UNF и др.) подгружаются через `AppMenuRepository`. + +### Конференции / Talk (`talk-native`, `vendor/talk-android`) + +- Нативные звонки через форк Nextcloud Talk. +- **Исправление повторного подключения к звонку** после завершения предыдущего (`CallActivity.onNewIntent`, сброс `ApplicationWideCurrentRoomHolder`, очистка в `TalkNativeCallLauncher`) — баг с конференцией «Топ Дейли» у markov.aa. + +### Почта (`feature/mail`) + +- Нативный список писем, папки, поиск, переписки (threads). +- Просмотр письма: HTML в WebView, текстовые письма в Compose. +- Меню действий «⋯» с иконками на белом фоне (ответить, избранное, спам, метки, переместить и т.д.). +- Свайп справа налево для закрытия письма. +- Исправления крашей при открытии HTML-писем (вложенная прокрутка, `fillMaxSize` в `Column`). +- **Фоновая предзагрузка тел писем** (до 60 писем, 3 параллельно) — v0.5.104. +- **Параметры эл. почты** (`MailSettingsScreens.kt`) по макету `AppSettingsMenu.vue`: + - Основные, учётные записи, внешний вид, текстовые шаблоны, конфиденциальность, безопасность. + - API: preferences, trusted senders, text blocks в `MailRepository`. +- **Запланированная отправка** при просмотре письма — открывает compose-ответ с выбранным временем (вместо snooze входящего). + +### Календарь (`feature/calendar`) + +- Виды: День, Неделя, Месяц, Год, Список. +- Боковая панель навигации по календарям. +- Расширенный редактор событий: повторения, участники, Talk, напоминания, RSVP. +- Корзина, незапланированные задачи, создание календаря, импорт `.ics`, настройки. +- Исправление краша `LazyColumn` с бесконечной высотой (v0.5.92). +- Вёрстка по макетам из `design/screens/calendar/` и CSS `_calendar-*-mobile.css`. + +### Контакты (`feature/contacts`) + +- Список контактов CardDAV, поиск, группы. +- Карточка контакта: email, телефон, адрес, организация, аватар. + +### Техподдержка (`feature/f7support`) + +- Нативный канбан тикетов, чат, создание обращений, вложения. +- **Composer чата** (`SupportChatComposerBar`) — pill-поле с эмодзи, скрепкой и круглой кнопкой отправки (как в Talk). +- Исправление выравнивания кнопки отправки (`Alignment.CenterVertically`). + +### Задачи (`feature/tasks`) — последняя крупная доработка (v0.5.113) + +Дизайн по макетам `design/screens/tasks/` и CSS `_tasks-main-mobile.css`, `_tasks-sidebar-mobile.css`: + +| Компонент | Файл | Описание | +|-----------|------|----------| +| `TasksToolbar` | `TasksComponents.kt` | Кнопка «+», inline-создание, фильтр, сортировка | +| `TasksRow` | `TasksComponents.kt` | Строка 48dp, чекбокс 16px, приоритет, дата | +| `TasksGroupHeader` | `TasksComponents.kt` | Группы по дате (Сегодня, Вчера…) | +| `TasksEmptyState` | `TasksComponents.kt` | Пустой список + «Загрузить» | +| `TasksCompletedSection` | `TasksComponents.kt` | Завершённые + удаление | +| `TaskDetailSheet` | `TasksComponents.kt` | Полноэкранная панель свойств/заметок | +| `TasksSettingsSheet` | `TasksComponents.kt` | Параметры задач | +| `TasksGrouping` | `TasksGrouping.kt` | Группировка по сроку | + +Данные — CalDAV (`TasksRepository`, `CalDavClient`). Умные списки (Сегодня, На неделе) пока только в UI настроек, без отдельной серверной логики. + +### Файлы (`feature/files`) + +- WebDAV: список папок/файлов, навигация, загрузка. +- Office-документы через Collabora (`OfficeEditorActivity`). + +--- + +## История версий (ключевые вехи) + +| versionName | versionCode | Основные изменения | +|-------------|-------------|-------------------| +| 0.5.88 | 96 | Базовая навигация, модули | +| 0.5.89–0.5.90 | 97–98 | Техподдержка, карточка контакта, повторный звонок | +| 0.5.91–0.5.92 | 99–100 | Расширенный календарь, composer поддержки, фикс краша календаря | +| 0.5.100 | 108 | Меню «⋯» в почте с иконками | +| 0.5.101–0.5.102 | 109–110 | Вёрстка просмотра письма, swipe-to-dismiss | +| 0.5.103–0.5.105 | 111–113 | Фиксы крашей HTML-писем | +| 0.5.104 | 112 | Предзагрузка тел писем | +| 0.5.106 | 114 | Свайп при открытом sidebar | +| 0.5.110 | 118 | Параметры эл. почты | +| 0.5.111–0.5.112 | 119–120 | Запланированная отправка, меню приложений | +| **0.5.113** | **121** | **Дизайн модуля Задачи** | + +Полный список версий — в git-истории `app/build.gradle`. + +--- + +## Серверные зависимости + +Приложение работает с инстансом F7cloud / Nextcloud: + +| Сервис | Назначение | +|--------|------------| +| OCS API | Авторизация, настройки, Dashboard | +| WebDAV | Файлы | +| CalDAV | Календарь, задачи | +| CardDAV | Контакты | +| Mail (IMAP/SMTP через API) | Почта | +| Spreed / Talk | Конференции, записи | +| Richdocuments + Collabora | Редактирование Office | +| f7support | Техподдержка | +| Deck | Карточки | + +Иконки и CSS-эталоны: `themes/forbion/` на сервере `forbion.f7cloud.ru`. + +--- + +## Макеты и дизайн + +``` +design/ +├── screens/ # PNG-макеты экранов (tasks, calendar, mail, …) +├── tokens/ # colors.txt, typography +├── icons/ # Локальные иконки (если нет на сервере) +└── references/ # Ссылки на Figma +``` + +При вёрстке ориентируемся на **мобильный CSS** веб-версии: `themes/forbion/css/pages/*-mobile.css`. + +--- + +## Известные ограничения + +1. **Задачи** — только CalDAV-календари как списки; умные списки и метки в UI есть, серверной логики нет. +2. **Заметки** — открываются в браузере, не нативно. +3. **Release-подпись** — для production нужен настроенный keystore (сейчас основная сборка — debug). +4. **Размер APK** ~130 МБ — включает vendor/talk-android и все feature-модули. + +--- + +## Связанные документы + +| Файл | Содержание | +|------|------------| +| [README.md](README.md) | Краткая справка по сборке и модулям | +| [design/README.md](design/README.md) | Структура макетов Figma | +| [vendor/talk-android/README.F7CLOUD.md](vendor/talk-android/README.F7CLOUD.md) | Форк Talk для F7cloud | +| [../docs/SERVER-PERFORMANCE.md](../docs/SERVER-PERFORMANCE.md) | Производительность сервера | + +--- + +## Быстрый чеклист перед выдачей APK + +1. `./gradlew assembleDebug` — без ошибок. +2. `versionCode` / `versionName` обновлены в `app/build.gradle`. +3. APK существует в `app/build/outputs/apk/debug/`. +4. При необходимости: `chown www-data:www-data app/build/outputs/apk/debug/*.apk`. diff --git a/README.md b/README.md new file mode 100644 index 0000000..18b214a --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +# F7cloud Mobile (native) + +Нативное Android-приложение F7cloud на Kotlin + Jetpack Compose. + +| Параметр | Значение | +|----------|----------| +| applicationId | `ru.forbion.f7cloud.mobile` | +| minSdk | 26 | +| compileSdk / targetSdk | 36 | +| Gradle | 9.3.0 | +| AGP | 8.13.2 | +| Kotlin | 2.3.0 | +| Модули | app, core (auth, network, designsystem, push), feature (widgets, files, talk, mail, …) | + +## Сборка APK + +С **v0.5.27** используется собственный Gradle wrapper в этом каталоге (Gradle 9.3, AGP 8.13, Kotlin 2.3): + +```bash +cd /var/www/f7cloud/f7cloud-mobile +./gradlew assembleDebug +chown www-data:www-data app/build/outputs/apk/debug/*.apk +``` + +> Старый способ через `android-webview` (Gradle 8.7) больше не поддерживается — там AGP 8.2, несовместим с Kotlin 2.3. + +Release: + +```bash +./gradlew assembleRelease +``` + +APK с версией в имени: + +``` +app/build/outputs/apk/debug/f7cloud-mobile-v{versionName}-{versionCode}-debug.apk +``` + +## Структура навигации + +Мобильный UI повторяет **мобильную** версию сайта (тема forbion): + +- нижняя панель: Talk, Профиль, Уведомления, Создать, Меню; +- меню приложений — bottom sheet со списком модулей; +- стартовый экран после входа — **Главная** (виджеты / Dashboard). + +## Модуль «Файлы» + +- Список папок и файлов через WebDAV PROPFIND (`oc:fileid` для идентификации). +- Навигация по папкам, кнопка «Назад». + +### Word / Excel / PowerPoint (Richdocuments) + +Office-документы открываются в **Collabora Online** через Richdocuments: + +1. По `fileId` (WebDAV или ссылка `/f/{id}` с виджетов) → Direct Editing API: + `POST /ocs/v2.php/apps/richdocuments/api/v1/document`. +2. Полноэкранный WebView (`OfficeEditorActivity`) с: + - `RichDocumentsMobileInterface` (см. `apps/richdocuments/docs/mobile_flow.md` на сервере) — скрывает оболочку F7cloud; + - desktop User-Agent — полная панель инструментов Collabora; + - поддержка iframe Collabora (`coll.f7cloud.ru`). + +**Где работает:** модуль **Файлы** и виджет **Рекомендации** на **Главной** (клик по `.docx` / `.xlsx`). + +Поддерживаемые расширения: см. `OfficeFiles.kt`. + +**Требования на сервере:** `richdocuments` + Collabora (у вас: `https://coll.f7cloud.ru`). + +## Модуль «Главная» (Widgets) + +Данные с Dashboard API F7cloud: + +| Endpoint | Назначение | +|----------|------------| +| `/ocs/v2.php/apps/dashboard/api/v1/widgets` | метаданные виджетов | +| `/ocs/v2.php/apps/dashboard/api/v3/layout` | порядок виджетов пользователя | +| `/ocs/v2.php/apps/dashboard/api/v2/widget-items` | элементы (Talk, Mail, Calendar) | +| `/ocs/v2.php/apps/dashboard/api/v1/widget-items?widgets[]=recommendations` | блок «Рекомендации» | + +Запросы выполняются **параллельно** (`WidgetsRepository`, с v0.5.4). + +## Производительность + +### Клиент (приложение) + +| Версия | Изменение | +|--------|-----------| +| ≤ 0.5.3 | 4 последовательных запроса → до ~30 с | +| ≥ 0.5.4 | параллельные запросы, layout с таймаутом 2 с, v1 только для recommendations → ~2–4 с | + +### Сервер + +Перед релизом или при жалобах на медленную «Главную» проверьте сервер: + +**[docs/SERVER-PERFORMANCE.md](../docs/SERVER-PERFORMANCE.md)** + +Кратко для `forbion.f7cloud.ru` (2026-05-30): + +- ✅ OPcache включён (FPM: 256 MB, 100k файлов) +- ✅ Redis + APCu для кеша F7cloud +- ✅ PHP-FPM: min 18 spare workers, старт 30 + +Первый API-запрос после простоя сервера может занимать 15–20 с — это холодный bootstrap PHP/F7cloud, не ошибка приложения. + +## Авторизация + +- Используется тот же пароль, что и для веб-входа (или пароль приложения при 2FA). +- OCS `/ocs/v2.php/cloud/user` — проверка и получение `davUserId` для WebDAV. + +## Связанные проекты + +- [android-webview](../android-webview/README_ANDROID_BUILD.md) — WebView-оболочка (legacy) +- [f7push](../apps/f7push/README.md) — push-уведомления diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..6482096 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,96 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'org.jetbrains.kotlin.plugin.compose' +} + +def googleServicesFile = file('google-services.json') +if (googleServicesFile.exists()) { + apply plugin: 'com.google.gms.google-services' +} + +android { + namespace 'ru.forbion.f7cloud.mobile' + compileSdk 36 + + defaultConfig { + applicationId 'ru.forbion.f7cloud.mobile' + minSdk 26 + targetSdk 36 + versionCode 121 + versionName '0.5.113' + missingDimensionStrategy 'default', 'f7' + multiDexEnabled true + } + + buildTypes { + debug {} + release { + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + buildFeatures { + compose true + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } + + applicationVariants.configureEach { variant -> + variant.outputs.configureEach { output -> + def vName = variant.versionName ?: "0.0.0" + def vCode = variant.versionCode ?: 0 + output.outputFileName = "f7cloud-mobile-v${vName}-${vCode}-${variant.name}.apk" + } + } +} + +dependencies { + implementation project(':core:auth') + implementation project(':core:network') + implementation project(':core:push') + implementation project(':core:designsystem') + implementation project(':feature:files') + implementation project(':feature:talk') + implementation project(':feature:talk-native') + implementation project(':feature:calendar') + implementation project(':feature:contacts') + implementation project(':feature:tasks') + implementation project(':feature:deck') + implementation project(':feature:mail') + implementation project(':feature:f7support') + + def composeBom = platform('androidx.compose:compose-bom:2025.02.00') + implementation composeBom + androidTestImplementation composeBom + implementation 'androidx.activity:activity-compose:1.10.1' + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-tooling-preview' + implementation 'androidx.compose.material3:material3' + implementation 'androidx.navigation:navigation-compose:2.8.9' + implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7' + implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.8.7' + implementation 'androidx.lifecycle:lifecycle-process:2.8.7' + implementation 'io.coil-kt:coil-compose:2.7.0' + implementation 'io.coil-kt:coil-svg:2.7.0' + implementation platform('com.google.firebase:firebase-bom:33.7.0') + implementation 'com.google.firebase:firebase-messaging' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0' + implementation 'androidx.multidex:multidex:2.0.1' + implementation 'androidx.biometric:biometric:1.1.0' + implementation 'androidx.fragment:fragment-ktx:1.8.6' + implementation 'androidx.camera:camera-camera2:1.5.2' + implementation 'androidx.camera:camera-lifecycle:1.5.2' + implementation 'androidx.camera:camera-view:1.5.2' + implementation 'com.google.zxing:core:3.3.0' + implementation 'androidx.compose.material:material-icons-extended' + implementation 'com.google.guava:guava:33.3.1-android' + debugImplementation 'androidx.compose.ui:ui-tooling' +} diff --git a/app/google-services.json.example b/app/google-services.json.example new file mode 100644 index 0000000..253766d --- /dev/null +++ b/app/google-services.json.example @@ -0,0 +1,28 @@ +{ + "project_info": { + "project_number": "YOUR_PROJECT_NUMBER", + "project_id": "f7push", + "storage_bucket": "f7push.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:PROJECT_NUMBER:android:WEBVIEW_APP_HASH", + "android_client_info": { + "package_name": "ru.forbion.f7cloud" + } + }, + "api_key": [{ "current_key": "YOUR_API_KEY" }] + }, + { + "client_info": { + "mobilesdk_app_id": "1:PROJECT_NUMBER:android:MOBILE_APP_HASH", + "android_client_info": { + "package_name": "ru.forbion.f7cloud.mobile" + } + }, + "api_key": [{ "current_key": "YOUR_API_KEY" }] + } + ], + "configuration_version": "1" +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..a5889bd --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1 @@ +# Project specific ProGuard rules. diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..65dadc4 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/CallIncomingActivity.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/CallIncomingActivity.kt new file mode 100644 index 0000000..8592ab0 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/CallIncomingActivity.kt @@ -0,0 +1,133 @@ +package ru.forbion.f7cloud.mobile + +import android.content.Intent +import android.os.Build +import android.os.Bundle +import android.view.WindowManager +import androidx.activity.ComponentActivity +import androidx.activity.addCallback +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.Modifier +import ru.forbion.f7cloud.core.auth.AuthStore +import ru.forbion.f7cloud.core.designsystem.F7Theme +import ru.forbion.f7cloud.core.push.F7IncomingCallQueue +import ru.forbion.f7cloud.core.push.F7IncomingCallRinger +import ru.forbion.f7cloud.core.push.PushIntents +import ru.forbion.f7cloud.core.push.TalkCallPushLabels +import ru.forbion.f7cloud.feature.talknative.TalkNativeCallLauncher + +/** + * Full-screen incoming call UI (Telegram-style). + * Notification body tap / lock-screen → preview with Accept/Decline. + * Notification Accept button → joins call immediately. + */ +class CallIncomingActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + setShowWhenLocked(true) + setTurnScreenOn(true) + } + @Suppress("DEPRECATION") + window.addFlags( + WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or + WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or + WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON, + ) + + val launch = parseLaunch(intent) + if (launch == null) { + finish() + return + } + if (launch.autoAccept) { + acceptCall(launch) + finish() + return + } + + onBackPressedDispatcher.addCallback(this) { + declineCall(launch) + finish() + } + + setContent { + F7Theme { + IncomingCallScreen( + modifier = Modifier.fillMaxSize(), + callerName = launch.displayName, + subtitle = launch.subtitle, + onAccept = { + acceptCall(launch) + finish() + }, + onDecline = { + declineCall(launch) + finish() + }, + ) + } + } + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + val launch = parseLaunch(intent) ?: return + if (launch.autoAccept) { + acceptCall(launch) + finish() + } + } + + private fun acceptCall(launch: IncomingCallLaunch) { + F7IncomingCallRinger.stop() + val session = AuthStore(this).load() ?: return + F7IncomingCallQueue.dismissAndShowNext(this, launch.roomToken) + TalkNativeCallLauncher.launchIncomingCall( + this, + session, + launch.acceptUrl, + roomDisplayName = launch.displayName, + ) + } + + private fun declineCall(launch: IncomingCallLaunch) { + F7IncomingCallQueue.dismissAndShowNext(this, launch.roomToken) + } + + private fun parseLaunch(intent: Intent?): IncomingCallLaunch? { + if (intent == null) return null + val acceptUrl = intent.getStringExtra(PushIntents.EXTRA_ACCEPT_URL)?.takeIf { it.isNotBlank() } + ?: return null + return IncomingCallLaunch( + acceptUrl = acceptUrl, + roomToken = intent.getStringExtra(PushIntents.EXTRA_ROOM_TOKEN), + title = intent.getStringExtra(PushIntents.EXTRA_CALL_TITLE).orEmpty(), + displayName = intent.getStringExtra(PushIntents.EXTRA_ROOM_DISPLAY_NAME) + ?.takeIf { it.isNotBlank() } + ?: TalkCallPushLabels.resolveRoomDisplayName( + intent.getStringExtra(PushIntents.EXTRA_CALL_TITLE).orEmpty(), + intent.getStringExtra(PushIntents.EXTRA_CALL_BODY).orEmpty(), + null, + ), + subtitle = intent.getStringExtra(PushIntents.EXTRA_CALL_BODY) + ?.takeIf { it.isNotBlank() } + ?: getString(ru.forbion.f7cloud.core.push.R.string.incoming_call_subtitle), + autoAccept = intent.getBooleanExtra(PushIntents.EXTRA_AUTO_ACCEPT, false), + ) + } +} + +private data class IncomingCallLaunch( + val acceptUrl: String, + val roomToken: String?, + val title: String, + val displayName: String, + val subtitle: String, + val autoAccept: Boolean, +) diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt new file mode 100644 index 0000000..8186d59 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/F7MobileApp.kt @@ -0,0 +1,94 @@ +package ru.forbion.f7cloud.mobile + +import android.util.Log +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ProcessLifecycleOwner +import coil.ImageLoader +import coil.ImageLoaderFactory +import coil.decode.SvgDecoder +import coil.disk.DiskCache +import coil.memory.MemoryCache +import com.google.firebase.messaging.FirebaseMessaging +import ru.f7cloud.talk.application.F7cloudTalkApplication +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import ru.forbion.f7cloud.core.auth.AuthStore +import ru.forbion.f7cloud.core.designsystem.AppForegroundTracker +import ru.forbion.f7cloud.core.push.F7NotificationChannels +import ru.forbion.f7cloud.core.push.F7PushRegistrar +import ru.forbion.f7cloud.feature.talknative.TalkVendorBootstrap + +/** + * F7cloud application entry. Extends talk-android [F7cloudTalkApplication] so native + * WebRTC (CallActivity, Dagger, Room) can initialize when [TalkVendorBootstrap] is enabled. + */ +class F7MobileApp : F7cloudTalkApplication(), ImageLoaderFactory { + override fun onCreate() { + super.onCreate() + ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver { + override fun onStart(owner: LifecycleOwner) { + AppForegroundTracker.setForeground(true) + } + + override fun onStop(owner: LifecycleOwner) { + AppForegroundTracker.setForeground(false) + } + }) + F7NotificationChannels.ensureAll(this) + TalkVendorBootstrap.onApplicationCreate(this) + val auth = AuthStore(this).load() ?: return + try { + bootstrapFcmRegistration(auth) + } catch (t: Throwable) { + Log.w("F7MobileApp", "Firebase unavailable, push bootstrap skipped", t) + } + } + + /** + * Re-register after Firebase config changes (e.g. google-services.json for .mobile package). + */ + private fun bootstrapFcmRegistration(auth: ru.forbion.f7cloud.core.auth.AuthSession) { + val prefs = getSharedPreferences("f7push", MODE_PRIVATE) + val configGeneration = 2 + val needsRefresh = prefs.getInt("fcm_config_generation", 0) < configGeneration + + fun registerToken(token: String) { + CoroutineScope(Dispatchers.IO).launch { + val code = F7PushRegistrar.registerBlocking(this@F7MobileApp, auth, token) + Log.d("F7MobileApp", "push register result: $code") + } + } + + if (needsRefresh) { + FirebaseMessaging.getInstance().deleteToken().addOnCompleteListener { + FirebaseMessaging.getInstance().token.addOnSuccessListener { token -> + prefs.edit().putInt("fcm_config_generation", configGeneration).apply() + registerToken(token) + } + } + return + } + + FirebaseMessaging.getInstance().token.addOnSuccessListener { registerToken(it) } + } + + override fun newImageLoader(): ImageLoader { + return ImageLoader.Builder(this) + .components { add(SvgDecoder.Factory()) } + .crossfade(false) + .memoryCache { + MemoryCache.Builder(this) + .maxSizePercent(0.12) + .build() + } + .diskCache { + DiskCache.Builder() + .directory(cacheDir.resolve("coil_image_cache")) + .maxSizePercent(0.02) + .build() + } + .build() + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/IncomingCallScreen.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/IncomingCallScreen.kt new file mode 100644 index 0000000..96e0d01 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/IncomingCallScreen.kt @@ -0,0 +1,183 @@ +package ru.forbion.f7cloud.mobile + +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +private val IncomingBgTop = Color(0xFF3D8FD1) +private val IncomingBgBottom = Color(0xFF1B4F82) +private val AvatarFill = Color(0xFF5BA8E8) +private val AcceptGreen = Color(0xFF2ECC71) +private val DeclineRed = Color(0xFFE74C3C) + +@Composable +fun IncomingCallScreen( + callerName: String, + subtitle: String, + onAccept: () -> Unit, + onDecline: () -> Unit, + modifier: Modifier = Modifier, +) { + val displayName = callerName.ifBlank { "Звонок" } + val initial = displayName.trim().firstOrNull()?.uppercaseChar()?.toString() ?: "?" + + Box( + modifier = modifier + .fillMaxSize() + .background( + Brush.verticalGradient( + colors = listOf(IncomingBgTop, IncomingBgBottom), + ), + ), + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Spacer(Modifier.height(72.dp)) + IncomingAvatar(initial = initial) + Spacer(Modifier.height(28.dp)) + Text( + text = displayName, + color = Color.White, + fontSize = 28.sp, + fontWeight = FontWeight.SemiBold, + textAlign = TextAlign.Center, + ) + Spacer(Modifier.height(8.dp)) + Text( + text = subtitle, + color = Color.White.copy(alpha = 0.82f), + fontSize = 16.sp, + textAlign = TextAlign.Center, + ) + Spacer(Modifier.weight(1f)) + Row( + modifier = Modifier.padding(bottom = 56.dp), + horizontalArrangement = Arrangement.spacedBy(72.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + IncomingCallAction( + label = "Принять", + background = AcceptGreen, + iconRes = R.drawable.ic_call_accept, + onClick = onAccept, + ) + IncomingCallAction( + label = "Отклонить", + background = DeclineRed, + iconRes = R.drawable.ic_call_decline, + onClick = onDecline, + ) + } + } + } +} + +@Composable +private fun IncomingAvatar(initial: String) { + val transition = rememberInfiniteTransition(label = "ring") + val ringAlpha by transition.animateFloat( + initialValue = 0.45f, + targetValue = 0.08f, + animationSpec = infiniteRepeatable( + animation = tween(durationMillis = 1800, easing = LinearEasing), + repeatMode = RepeatMode.Reverse, + ), + label = "ringAlpha", + ) + + Box(contentAlignment = Alignment.Center) { + Box( + modifier = Modifier + .size(168.dp) + .alpha(ringAlpha) + .clip(CircleShape) + .background(Color.White.copy(alpha = 0.18f)), + ) + Box( + modifier = Modifier + .size(136.dp) + .alpha(ringAlpha * 0.8f) + .clip(CircleShape) + .background(Color.White.copy(alpha = 0.14f)), + ) + Box( + modifier = Modifier + .size(112.dp) + .clip(CircleShape) + .background(AvatarFill), + contentAlignment = Alignment.Center, + ) { + Text( + text = initial, + color = Color.White, + fontSize = 44.sp, + fontWeight = FontWeight.Medium, + ) + } + } +} + +@Composable +private fun IncomingCallAction( + label: String, + background: Color, + iconRes: Int, + onClick: () -> Unit, +) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + IconButton( + onClick = onClick, + modifier = Modifier + .size(72.dp) + .clip(CircleShape) + .background(background), + ) { + Icon( + painter = painterResource(iconRes), + contentDescription = label, + tint = Color.White, + modifier = Modifier.size(30.dp), + ) + } + Spacer(Modifier.height(10.dp)) + Text( + text = label, + color = Color.White, + fontSize = 14.sp, + ) + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/MainActivity.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/MainActivity.kt new file mode 100644 index 0000000..c14112b --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/MainActivity.kt @@ -0,0 +1,131 @@ +package ru.forbion.f7cloud.mobile + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.fragment.app.FragmentActivity +import ru.forbion.f7cloud.core.auth.AuthStore +import ru.forbion.f7cloud.core.push.F7PushIntentExtras +import ru.forbion.f7cloud.core.push.PushIntents +import ru.forbion.f7cloud.feature.talk.TalkHelper +import ru.forbion.f7cloud.feature.talknative.TalkNativeCallLauncher +import ru.forbion.f7cloud.mobile.permissions.F7AppPermissions +import ru.forbion.f7cloud.mobile.ui.AppScaffold + +class MainActivity : FragmentActivity() { + private var openUrl by mutableStateOf(null) + + private val runtimePermissionsLauncher = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions(), + ) { results -> + Log.d(TAG, "Runtime permissions result: $results") + onPermissionsResult?.invoke() + onPermissionsResult = null + } + + /** Вызывается после системного диалога разрешений (для регистрации FCM и т.д.). */ + var onPermissionsResult: (() -> Unit)? = null + + fun launchMissingRuntimePermissions(onFinished: (() -> Unit)? = null) { + val missing = F7AppPermissions.missing(this) + if (missing.isEmpty()) { + onFinished?.invoke() + return + } + onPermissionsResult = onFinished + runtimePermissionsLauncher.launch(missing.toTypedArray()) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + if (!handleIncomingIntent(intent)) { + openUrl = resolveOpenUrl(intent) + } + setContent { + AppScaffold( + openUrl = openUrl, + onOpenUrlConsumed = { openUrl = null }, + onRequestRuntimePermissions = { finished -> + launchMissingRuntimePermissions(finished) + }, + ) + } + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + if (!handleIncomingIntent(intent)) { + openUrl = resolveOpenUrl(intent) + } + } + + private fun resolveOpenUrl(intent: Intent?): String? { + if (intent == null) return null + if (F7PushIntentExtras.isFcmLaunch(intent)) { + F7PushIntentExtras.publishEventFromIntent(intent) + } + if (intent.data?.toString() == "f7cloud://talk") { + val session = AuthStore(this).load() ?: return null + return "${session.serverUrl.trimEnd('/')}/apps/spreed/" + } + val url = F7PushIntentExtras.resolveOpenUrl(intent) + val room = F7PushIntentExtras.resolveRoomToken(intent) + val messageId = F7PushIntentExtras.resolveMessageId(intent) + if (!url.isNullOrBlank()) { + if (!messageId.isNullOrBlank() && !url.contains("#message_")) { + return "$url#message_$messageId" + } + return url + } + if (!room.isNullOrBlank()) { + val session = AuthStore(this).load() ?: return null + val base = "${session.serverUrl.trimEnd('/')}/index.php/apps/spreed/$room" + return if (!messageId.isNullOrBlank()) "$base#message_$messageId" else base + } + return null + } + + /** @return true if intent was fully handled (call launched). */ + private fun handleIncomingIntent(intent: Intent?): Boolean { + if (intent == null) return false + val session = AuthStore(this).load() + when { + intent.action == PushIntents.ACTION_OPEN_CALL -> { + val acceptUrl = intent.getStringExtra(PushIntents.EXTRA_ACCEPT_URL) + if (!acceptUrl.isNullOrBlank() && session != null) { + if (intent.getBooleanExtra(PushIntents.EXTRA_AUTO_ACCEPT, false)) { + TalkNativeCallLauncher.launchIncomingCall(this, session, acceptUrl) + } else { + startActivity( + Intent(intent).apply { + setClass(this@MainActivity, CallIncomingActivity::class.java) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + }, + ) + } + return true + } + } + else -> { + val url = intent.getStringExtra(PushIntents.EXTRA_OPEN_URL) + if (!url.isNullOrBlank() && TalkHelper.isCallRoomUrl(url) && session != null) { + TalkNativeCallLauncher.launchIncomingCall(this, session, url) + return true + } + } + } + return false + } + + companion object { + private const val TAG = "MainActivity" + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeEditorActivity.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeEditorActivity.kt new file mode 100644 index 0000000..099c523 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeEditorActivity.kt @@ -0,0 +1,425 @@ +package ru.forbion.f7cloud.mobile + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.Message +import android.view.ViewGroup +import android.webkit.CookieManager +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.FrameLayout +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import kotlinx.coroutines.delay +import okhttp3.OkHttpClient +import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton +import ru.forbion.f7cloud.core.designsystem.F7Theme +import ru.forbion.f7cloud.core.network.NetworkFactory +import ru.forbion.f7cloud.feature.files.OfficeEditorLaunch + +class OfficeEditorActivity : ComponentActivity() { + + private var webViewRef: WebView? = null + private var editorVisible by mutableStateOf(false) + private var loadError by mutableStateOf(null) + private var launch by mutableStateOf(null) + + @OptIn(ExperimentalMaterial3Api::class) + @SuppressLint("SetJavaScriptEnabled") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val initial = readLaunch() ?: run { + finish() + return + } + launch = initial + bindUi(initial) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + val next = readLaunch() ?: return + if (OfficeWebViewPool.sessionKey(next) != launch?.let { OfficeWebViewPool.sessionKey(it) }) { + OfficeWebViewPool.dispose() + webViewRef = null + } + launch = next + editorVisible = false + loadError = null + loadDocument(next) + } + + @OptIn(ExperimentalMaterial3Api::class) + @SuppressLint("SetJavaScriptEnabled") + private fun bindUi(initial: OfficeEditorLaunch) { + val httpClient = NetworkFactory.newAuthedClientForOffice( + initial.username, + initial.password, + initial.trustAllCerts, + ) + val authHosts = OfficeWebViewClient.buildAuthHosts(initial) + val interceptPrefixes = OfficeWebViewClient.buildInterceptPrefixes(initial) + + setContent { + F7Theme { + val currentLaunch = launch + if (currentLaunch == null) return@F7Theme + + LaunchedEffect(currentLaunch.url, editorVisible) { + if (editorVisible) return@LaunchedEffect + delay(LOAD_TIMEOUT_MS) + if (!editorVisible && loadError == null) { + loadError = "Редактор не ответил вовремя. Проверьте интернет и попробуйте снова." + } + } + + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = currentLaunch.title, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + }, + navigationIcon = { + IconButton(onClick = { finish() }) { + Text("←", style = MaterialTheme.typography.titleLarge) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = F7Colors.Surface, + titleContentColor = F7Colors.TextPrimary, + ), + ) + }, + containerColor = F7Colors.Background, + ) { padding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(padding) + .background(androidx.compose.ui.graphics.Color.White), + ) { + if (loadError != null) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(24.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + loadError!!, + style = MaterialTheme.typography.bodyLarge, + textAlign = TextAlign.Center, + color = F7Colors.TextPrimary, + ) + F7PrimaryButton( + text = "Закрыть", + onClick = { finish() }, + modifier = Modifier.padding(top = 16.dp), + ) + } + } else { + OfficeWebView( + launch = currentLaunch, + httpClient = httpClient, + authHosts = authHosts, + interceptPrefixes = interceptPrefixes, + modifier = Modifier.fillMaxSize(), + ) + if (!editorVisible) { + Box( + modifier = Modifier + .fillMaxSize() + .background(androidx.compose.ui.graphics.Color.White), + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + CircularProgressIndicator(color = F7Colors.Primary) + Text( + "Загрузка редактора…", + modifier = Modifier.padding(top = 16.dp), + style = MaterialTheme.typography.bodyMedium, + color = F7Colors.TextSecondary, + ) + } + } + } + } + } + } + } + } + } + + fun onCollaboraDocumentLoaded(webView: WebView?) { + editorVisible = true + loadError = null + webView?.evaluateJavascript(HIDE_F7CLOUD_CHROME_JS, null) + } + + private fun loadDocument(target: OfficeEditorLaunch) { + val view = webViewRef ?: return + val current = view.url?.trimEnd('/').orEmpty() + val next = target.url.trimEnd('/') + if (current == next) return + editorVisible = false + loadError = null + view.loadUrl(target.url) + } + + private fun readLaunch(): OfficeEditorLaunch? { + val url = intent.getStringExtra(EXTRA_URL) ?: return null + val title = intent.getStringExtra(EXTRA_TITLE).orEmpty() + val username = intent.getStringExtra(EXTRA_USERNAME).orEmpty() + val password = intent.getStringExtra(EXTRA_PASSWORD).orEmpty() + val serverUrl = intent.getStringExtra(EXTRA_SERVER_URL).orEmpty() + if (url.isBlank() || username.isBlank()) return null + return OfficeEditorLaunch( + url = url, + title = title, + username = username, + password = password, + trustAllCerts = intent.getBooleanExtra(EXTRA_TRUST_ALL_CERTS, false), + serverUrl = serverUrl, + collaboraBaseUrl = intent.getStringExtra(EXTRA_COLLABORA_URL).orEmpty(), + ) + } + + @SuppressLint("SetJavaScriptEnabled") + @Composable + private fun OfficeWebView( + launch: OfficeEditorLaunch, + httpClient: OkHttpClient, + authHosts: Set, + interceptPrefixes: List, + modifier: Modifier = Modifier, + ) { + AndroidView( + modifier = modifier, + factory = { context -> + OfficeWebViewPool.obtain(context, launch) { webView -> + configureOfficeWebView( + webView = webView, + launch = launch, + httpClient = httpClient, + authHosts = authHosts, + interceptPrefixes = interceptPrefixes, + ) + }.also { webView -> + webViewRef = webView + webView.layoutParams = FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + ) + val current = webView.url?.trimEnd('/').orEmpty() + val target = launch.url.trimEnd('/') + if (current != target) { + webView.loadUrl(launch.url) + } + } + }, + update = { webView -> + webViewRef = webView + }, + onRelease = { webViewRef = null }, + ) + } + + @SuppressLint("SetJavaScriptEnabled") + private fun configureOfficeWebView( + webView: WebView, + launch: OfficeEditorLaunch, + httpClient: OkHttpClient, + authHosts: Set, + interceptPrefixes: List, + ) { + webView.setBackgroundColor(android.graphics.Color.WHITE) + val cookieManager = CookieManager.getInstance() + cookieManager.setAcceptCookie(true) + cookieManager.setAcceptThirdPartyCookies(webView, true) + webView.settings.apply { + javaScriptEnabled = true + domStorageEnabled = true + @Suppress("DEPRECATION") + databaseEnabled = true + javaScriptCanOpenWindowsAutomatically = true + setSupportMultipleWindows(true) + loadWithOverviewMode = true + useWideViewPort = true + builtInZoomControls = true + displayZoomControls = false + mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW + cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK + mediaPlaybackRequiresUserGesture = false + userAgentString = MOBILE_USER_AGENT + } + webView.removeJavascriptInterface("RichDocumentsMobileInterface") + webView.addJavascriptInterface( + RichDocumentsMobileBridge(this@OfficeEditorActivity) { webViewRef }, + "RichDocumentsMobileInterface", + ) + webView.webChromeClient = object : WebChromeClient() { + override fun onCreateWindow( + view: WebView?, + isDialog: Boolean, + isUserGesture: Boolean, + resultMsg: Message?, + ): Boolean { + val transport = resultMsg?.obj as? WebView.WebViewTransport ?: return false + val popup = WebView(webView.context).apply { + applyOfficePopupSettings(launch, httpClient, authHosts, interceptPrefixes) + } + transport.webView = popup + resultMsg.sendToTarget() + return true + } + } + webView.webViewClient = createClient(launch, httpClient, authHosts, interceptPrefixes) + } + + @SuppressLint("SetJavaScriptEnabled") + private fun WebView.applyOfficePopupSettings( + launch: OfficeEditorLaunch, + httpClient: OkHttpClient, + authHosts: Set, + interceptPrefixes: List, + ) { + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.setSupportMultipleWindows(true) + settings.userAgentString = MOBILE_USER_AGENT + webViewClient = createClient(launch, httpClient, authHosts, interceptPrefixes) + } + + private fun createClient( + launch: OfficeEditorLaunch, + httpClient: OkHttpClient, + authHosts: Set, + interceptPrefixes: List, + ): WebViewClient = OfficeWebViewClient( + launch = launch, + httpClient = httpClient, + authHosts = authHosts, + interceptPrefixes = interceptPrefixes, + onMainFrameError = { msg -> + runOnUiThread { + if (!editorVisible) { + loadError = "Не удалось загрузить редактор: $msg" + } + } + }, + onPageReady = { view -> + runOnUiThread { + view?.evaluateJavascript(HIDE_F7CLOUD_CHROME_JS, null) + } + }, + ) + + override fun onDestroy() { + OfficeWebViewPool.recycle(webViewRef) + webViewRef = null + super.onDestroy() + } + + companion object { + private const val EXTRA_URL = "url" + private const val EXTRA_TITLE = "title" + private const val EXTRA_USERNAME = "username" + private const val EXTRA_PASSWORD = "password" + private const val EXTRA_TRUST_ALL_CERTS = "trust_all_certs" + private const val EXTRA_SERVER_URL = "server_url" + private const val EXTRA_COLLABORA_URL = "collabora_url" + + private const val LOAD_TIMEOUT_MS = 90_000L + + const val MOBILE_USER_AGENT = + "Mozilla/5.0 (Linux; Android 13; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) " + + "Chrome/131.0.0.0 Mobile Safari/537.36" + + const val HIDE_F7CLOUD_CHROME_JS = """ + (function() { + var hide = function(el) { if (el) { el.style.display = 'none'; el.remove(); } }; + hide(document.getElementById('loadingContainer')); + hide(document.getElementById('proxyLoadingContainer')); + hide(document.getElementById('header')); + hide(document.getElementById('app-navigation')); + hide(document.getElementById('app-navigation-vue')); + hide(document.querySelector('#body-user')); + hide(document.querySelector('footer')); + var main = document.getElementById('content'); + if (main) { main.style.margin = '0'; main.style.padding = '0'; } + document.documentElement.style.overflow = 'hidden'; + document.body.style.margin = '0'; + document.body.style.padding = '0'; + document.body.style.background = '#fff'; + var doc = document.getElementById('documents-content'); + if (doc) { + doc.style.position = 'fixed'; + doc.style.top = '0'; + doc.style.left = '0'; + doc.style.right = '0'; + doc.style.bottom = '0'; + doc.style.width = '100%'; + doc.style.height = '100%'; + doc.style.zIndex = '99999'; + doc.style.background = '#fff'; + } + var frame = document.getElementById('loleafletframe') || document.querySelector('iframe'); + if (frame) { + frame.style.width = '100%'; + frame.style.height = '100%'; + frame.style.minHeight = '100vh'; + frame.style.border = 'none'; + } + })(); + """ + + fun intent(context: Context, launch: OfficeEditorLaunch): Intent = + Intent(context, OfficeEditorActivity::class.java).apply { + addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) + putExtra(EXTRA_URL, launch.url) + putExtra(EXTRA_TITLE, launch.title) + putExtra(EXTRA_USERNAME, launch.username) + putExtra(EXTRA_PASSWORD, launch.password) + putExtra(EXTRA_TRUST_ALL_CERTS, launch.trustAllCerts) + putExtra(EXTRA_SERVER_URL, launch.serverUrl) + putExtra(EXTRA_COLLABORA_URL, launch.collaboraBaseUrl) + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewClient.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewClient.kt new file mode 100644 index 0000000..c758139 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewClient.kt @@ -0,0 +1,132 @@ +package ru.forbion.f7cloud.mobile + +import android.graphics.Bitmap +import android.net.http.SslError +import android.webkit.HttpAuthHandler +import android.webkit.SslErrorHandler +import android.webkit.WebResourceRequest +import android.webkit.WebResourceResponse +import android.webkit.WebView +import android.webkit.WebViewClient +import okhttp3.OkHttpClient +import okhttp3.Request +import ru.forbion.f7cloud.feature.files.OfficeEditorLaunch +import java.io.FilterInputStream +import java.net.URI + +internal class OfficeWebViewClient( + private val launch: OfficeEditorLaunch, + private val httpClient: OkHttpClient, + private val authHosts: Set, + private val interceptPrefixes: List, + private val onMainFrameError: (String) -> Unit, + private val onPageReady: (WebView?) -> Unit, +) : WebViewClient() { + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + view?.evaluateJavascript(OfficeEditorActivity.HIDE_F7CLOUD_CHROME_JS, null) + } + + override fun onPageFinished(view: WebView?, url: String?) { + view?.evaluateJavascript(OfficeEditorActivity.HIDE_F7CLOUD_CHROME_JS, null) + onPageReady(view) + } + + override fun onReceivedHttpAuthRequest( + view: WebView?, + handler: HttpAuthHandler?, + host: String?, + realm: String?, + ) { + if (host != null && authHosts.any { host.equals(it, ignoreCase = true) }) { + handler?.proceed(launch.username, launch.password) + } else { + super.onReceivedHttpAuthRequest(view, handler, host, realm) + } + } + + override fun shouldInterceptRequest( + view: WebView?, + request: WebResourceRequest, + ): WebResourceResponse? { + val url = request.url?.toString() ?: return null + if (!shouldIntercept(url)) return null + return runCatching { + val builder = Request.Builder().url(url) + val method = request.method.uppercase() + when (method) { + "GET", "HEAD" -> builder.method(method, null) + else -> builder.method(method, null) + } + request.requestHeaders.forEach { (k, v) -> + if (!k.equals("Authorization", ignoreCase = true)) { + builder.header(k, v) + } + } + val response = httpClient.newCall(builder.build()).execute() + if (!response.isSuccessful || response.body == null) { + response.close() + return null + } + val body = response.body!! + val stream = object : FilterInputStream(body.byteStream()) { + override fun close() { + super.close() + response.close() + } + } + WebResourceResponse( + body.contentType()?.let { "${it.type}/${it.subtype}" }, + body.contentType()?.charset()?.name() ?: "utf-8", + stream, + ) + }.getOrNull() + } + + override fun onReceivedSslError( + view: WebView?, + handler: SslErrorHandler?, + error: SslError?, + ) { + if (launch.trustAllCerts) { + handler?.proceed() + } else { + super.onReceivedSslError(view, handler, error) + } + } + + override fun onReceivedError( + view: WebView?, + request: WebResourceRequest, + error: android.webkit.WebResourceError?, + ) { + if (request.isForMainFrame) { + val msg = error?.description?.toString().orEmpty().ifBlank { "Ошибка сети" } + onMainFrameError(msg) + } + super.onReceivedError(view, request, error) + } + + private fun shouldIntercept(url: String): Boolean = + interceptPrefixes.any { prefix -> url.startsWith(prefix, ignoreCase = true) } + + companion object { + fun buildAuthHosts(launch: OfficeEditorLaunch): Set { + val hosts = mutableSetOf() + runCatching { URI(launch.url).host }.getOrNull()?.let { hosts += it } + runCatching { URI(launch.serverUrl).host }.getOrNull()?.let { hosts += it } + if (launch.collaboraBaseUrl.isNotBlank()) { + runCatching { URI(launch.collaboraBaseUrl).host }.getOrNull()?.let { hosts += it } + } + return hosts + } + + fun buildInterceptPrefixes(launch: OfficeEditorLaunch): List { + val prefixes = mutableListOf(launch.serverUrl.trimEnd('/')) + if (launch.collaboraBaseUrl.isNotBlank()) { + prefixes += launch.collaboraBaseUrl.trimEnd('/') + } + return prefixes.distinct() + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewPool.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewPool.kt new file mode 100644 index 0000000..083827a --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/OfficeWebViewPool.kt @@ -0,0 +1,67 @@ +package ru.forbion.f7cloud.mobile + +import android.content.Context +import android.view.ViewGroup +import android.webkit.WebView +import ru.forbion.f7cloud.feature.files.OfficeEditorLaunch + +/** + * Держит один настроенный WebView между открытиями редактора (тот же пользователь/сервер). + * Статика Collabora подтягивается из HTTP-кэша WebView при повторных loadUrl. + */ +internal object OfficeWebViewPool { + private var webView: WebView? = null + private var sessionKey: String? = null + private var recycledAtMs: Long = 0L + + private const val MAX_IDLE_MS = 15 * 60 * 1000L + + fun sessionKey(launch: OfficeEditorLaunch): String = + "${launch.serverUrl.trimEnd('/')}|${launch.username}" + + fun obtain( + context: Context, + launch: OfficeEditorLaunch, + configure: (WebView) -> Unit, + ): WebView { + evictIfStale() + val key = sessionKey(launch) + val existing = webView + if (existing != null && sessionKey == key) { + detach(existing) + configure(existing) + return existing + } + dispose() + val created = WebView(context).apply { configure(this) } + webView = created + sessionKey = key + recycledAtMs = 0L + return created + } + + fun recycle(view: WebView?) { + if (view == null || view !== webView) return + detach(view) + view.stopLoading() + recycledAtMs = System.currentTimeMillis() + } + + fun dispose() { + webView?.destroy() + webView = null + sessionKey = null + recycledAtMs = 0L + } + + fun evictIfStale() { + if (webView == null) return + if (recycledAtMs > 0L && System.currentTimeMillis() - recycledAtMs > MAX_IDLE_MS) { + dispose() + } + } + + private fun detach(view: WebView) { + (view.parent as? ViewGroup)?.removeView(view) + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/RichDocumentsMobileBridge.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/RichDocumentsMobileBridge.kt new file mode 100644 index 0000000..0f9d6a6 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/RichDocumentsMobileBridge.kt @@ -0,0 +1,51 @@ +package ru.forbion.f7cloud.mobile + +import android.webkit.JavascriptInterface +import android.webkit.WebView + +class RichDocumentsMobileBridge( + private val host: OfficeEditorActivity, + private val webViewProvider: () -> WebView?, +) { + @JavascriptInterface + fun documentLoaded() { + host.runOnUiThread { + host.onCollaboraDocumentLoaded(webViewProvider()) + } + } + + @JavascriptInterface + fun close() { + host.runOnUiThread { host.finish() } + } + + @JavascriptInterface + fun close(json: String?) { + close() + } + + @JavascriptInterface + fun share(json: String?) { + // Не используется в нативной оболочке + } + + @JavascriptInterface + fun insertGraphic(json: String?) { + // Не используется + } + + @JavascriptInterface + fun fileRename(json: String?) { + // Не используется + } + + @JavascriptInterface + fun downloadAs(json: String?) { + // Не используется + } + + @JavascriptInterface + fun paste(json: String?) { + // Не используется + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/navigation/AppLinkResolver.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/navigation/AppLinkResolver.kt new file mode 100644 index 0000000..dcc6ce2 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/navigation/AppLinkResolver.kt @@ -0,0 +1,118 @@ +package ru.forbion.f7cloud.mobile.navigation + +import ru.forbion.f7cloud.feature.files.OfficeFileLinks +import ru.forbion.f7cloud.feature.talk.TalkDeepLink +import ru.forbion.f7cloud.mobile.ui.AppTab + +/** + * Maps F7cloud web URLs (dashboard widgets, push, notifications) to in-app navigation. + */ +object AppLinkResolver { + fun resolve(url: String?, serverUrl: String = ""): AppLinkTarget? { + if (url.isNullOrBlank()) return null + val lower = url.lowercase() + + TalkDeepLink.extractRoomToken(url)?.let { token -> + return AppLinkTarget( + tab = AppTab.Talk, + talkRoomToken = token, + talkMessageId = TalkDeepLink.extractMessageId(url), + ) + } + + parseMail(url)?.let { return it } + + parseCalendar(url)?.let { return it } + + parseDeck(url)?.let { return it } + + parseTasks(url)?.let { return it } + + OfficeFileLinks.parseFileId(url, serverUrl)?.let { fileId -> + return AppLinkTarget(tab = AppTab.Files, fileId = fileId) + } + + if (lower.contains("/apps/files") || lower.contains("/remote.php/dav/files") || + lower.contains("fileid=") || lower.contains("/f/") + ) { + val fileId = OfficeFileLinks.parseFileId(url, serverUrl) + ?: Regex("""fileid=(\d+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1)?.toLongOrNull() + return AppLinkTarget(tab = AppTab.Files, fileId = fileId) + } + + return when { + lower.contains("/apps/f7mail") || lower.contains("/apps/mail") -> AppLinkTarget(tab = AppTab.Mail) + lower.contains("/apps/calendar") -> AppLinkTarget(tab = AppTab.Calendar) + lower.contains("/apps/tasks") -> parseTasks(url) ?: AppLinkTarget(tab = AppTab.Tasks) + lower.contains("/apps/deck") -> AppLinkTarget(tab = AppTab.Deck) + lower.contains("/apps/spreed") -> AppLinkTarget(tab = AppTab.Talk) + lower.contains("/apps/f7support") -> { + AppLinkTarget(tab = AppTab.Support, supportTicket = extractSupportTicket(url)) + } + lower.contains("/apps/dashboard") -> AppLinkTarget(tab = AppTab.Files) + lower.contains("/apps/contacts") -> AppLinkTarget(tab = AppTab.Contacts) + else -> null + } + } + + private fun parseMail(url: String): AppLinkTarget? { + if (!url.contains("/apps/f7mail", ignoreCase = true) && + !url.contains("/apps/mail", ignoreCase = true) + ) { + return null + } + val thread = Regex("""/thread/(\d+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1)?.toIntOrNull() + val mailbox = Regex("""/box/(\d+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1)?.toIntOrNull() + return AppLinkTarget( + tab = AppTab.Mail, + mailMessageId = thread, + mailMailboxId = mailbox, + ) + } + + private fun parseCalendar(url: String): AppLinkTarget? { + if (!url.contains("/apps/calendar", ignoreCase = true)) return null + val uid = Regex("""/edit/([^/?#]+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1) + ?.takeIf { it.isNotBlank() } + return AppLinkTarget(tab = AppTab.Calendar, calendarEventUid = uid) + } + + private fun parseDeck(url: String): AppLinkTarget? { + if (!url.contains("/apps/deck", ignoreCase = true)) return null + val cardId = Regex("""/card/(\d+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1)?.toIntOrNull() + return AppLinkTarget(tab = AppTab.Deck, deckCardId = cardId) + } + + private fun parseTasks(url: String): AppLinkTarget? { + if (!url.contains("/apps/tasks", ignoreCase = true)) return null + val slug = Regex("""/calendars/([^/?#]+)""", RegexOption.IGNORE_CASE).find(url) + ?.groupValues?.get(1) + ?.takeIf { it.isNotBlank() } + return AppLinkTarget(tab = AppTab.Tasks, tasksListSlug = slug) + } + + private fun extractSupportTicket(url: String): String? { + val marker = "ticket=" + val idx = url.indexOf(marker, ignoreCase = true) + if (idx < 0) return null + return url.substring(idx + marker.length).takeWhile { it.isDigit() }.ifBlank { null } + } +} + +data class AppLinkTarget( + val tab: AppTab, + val talkRoomToken: String? = null, + val talkMessageId: Long? = null, + val mailMessageId: Int? = null, + val mailMailboxId: Int? = null, + val calendarEventUid: String? = null, + val deckCardId: Int? = null, + val fileId: Long? = null, + val supportTicket: String? = null, + val tasksListSlug: String? = null, +) diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7AppPermissions.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7AppPermissions.kt new file mode 100644 index 0000000..3ceb17c --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7AppPermissions.kt @@ -0,0 +1,44 @@ +package ru.forbion.f7cloud.mobile.permissions + +import android.Manifest +import android.content.Context +import android.content.pm.PackageManager +import android.os.Build +import androidx.core.content.ContextCompat + +object F7AppPermissions { + + /** Все runtime-разрешения, которые нужны приложению после входа. */ + fun requiredRuntimePermissions(): List = buildList { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + add(Manifest.permission.POST_NOTIFICATIONS) + add(Manifest.permission.READ_MEDIA_IMAGES) + add(Manifest.permission.READ_MEDIA_VIDEO) + add(Manifest.permission.READ_MEDIA_AUDIO) + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + add(Manifest.permission.READ_EXTERNAL_STORAGE) + } + add(Manifest.permission.CAMERA) + add(Manifest.permission.RECORD_AUDIO) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + add(Manifest.permission.BLUETOOTH_CONNECT) + } + } + + fun missing(context: Context): List = + requiredRuntimePermissions().filter { + ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED + } + + fun hasAll(context: Context): Boolean = missing(context).isEmpty() + + fun talkCallPermissions(): Array = arrayOf( + Manifest.permission.CAMERA, + Manifest.permission.RECORD_AUDIO, + ) + + fun missingTalkCall(context: Context): List = + talkCallPermissions().filter { + ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7PermissionDialog.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7PermissionDialog.kt new file mode 100644 index 0000000..ec08841 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/permissions/F7PermissionDialog.kt @@ -0,0 +1,45 @@ +package ru.forbion.f7cloud.mobile.permissions + +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import ru.forbion.f7cloud.core.designsystem.F7Colors + +@Composable +fun F7PermissionRationaleDialog( + visible: Boolean, + onConfirm: () -> Unit, + onDismiss: () -> Unit, +) { + if (!visible) return + AlertDialog( + onDismissRequest = onDismiss, + title = { + Text( + text = "Разрешения для F7cloud", + style = MaterialTheme.typography.titleMedium, + color = F7Colors.TextPrimary, + ) + }, + text = { + Text( + text = "Чтобы работали уведомления о звонках и сообщениях, видеозвонки в конференциях " + + "и загрузка файлов, разрешите доступ к уведомлениям, камере, микрофону и хранилищу.", + style = MaterialTheme.typography.bodyMedium, + color = F7Colors.TextSecondary, + ) + }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text("Разрешить", color = F7Colors.Primary) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text("Позже", color = F7Colors.TextSecondary) + } + }, + ) +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/qr/F7QrScannerActivity.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/qr/F7QrScannerActivity.kt new file mode 100644 index 0000000..d5f3a31 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/qr/F7QrScannerActivity.kt @@ -0,0 +1,317 @@ +package ru.forbion.f7cloud.mobile.qr + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.camera.core.Camera +import androidx.camera.core.CameraSelector +import androidx.camera.core.ImageAnalysis +import androidx.camera.core.ImageProxy +import androidx.camera.core.Preview +import androidx.camera.lifecycle.ProcessCameraProvider +import androidx.camera.view.PreviewView +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Rect +import androidx.compose.ui.geometry.RoundRect +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.BlendMode +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.PathFillType +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.content.ContextCompat +import com.google.zxing.BarcodeFormat +import com.google.zxing.BinaryBitmap +import com.google.zxing.DecodeHintType +import com.google.zxing.MultiFormatReader +import com.google.zxing.common.HybridBinarizer +import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7Theme +import ru.forbion.f7cloud.core.network.LoginFlowClient +import ru.forbion.f7cloud.mobile.R +import java.util.concurrent.Executors +import java.util.concurrent.atomic.AtomicBoolean + +class F7QrScannerActivity : ComponentActivity() { + + private val finishing = AtomicBoolean(false) + private val analysisExecutor = Executors.newSingleThreadExecutor() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + F7Theme { + QrScannerScreen( + onClose = { finish() }, + onStableResult = ::finishWithStableResult, + ) + } + } + } + + override fun onDestroy() { + analysisExecutor.shutdown() + super.onDestroy() + } + + private fun finishWithStableResult(payload: String) { + if (!finishing.compareAndSet(false, true)) return + setResult( + RESULT_OK, + Intent().putExtra(RESULT_EXTRA, payload), + ) + finish() + } + + companion object { + const val RESULT_EXTRA = "ru.forbion.f7cloud.mobile.qr_scan_result" + private const val REQUIRED_STABLE_READS = 5 + + fun intent(context: Context): Intent = + Intent(context, F7QrScannerActivity::class.java) + } + + @OptIn(ExperimentalMaterial3Api::class) + @Composable + private fun QrScannerScreen( + onClose: () -> Unit, + onStableResult: (String) -> Unit, + ) { + val context = LocalContext.current + val idleHint = stringResource(R.string.qr_scan_hint_idle) + var hint by remember(idleHint) { mutableStateOf(idleHint) } + var stableCount by remember { mutableIntStateOf(0) } + var torchEnabled by remember { mutableStateOf(false) } + var camera by remember { mutableStateOf(null) } + val previewView = remember { PreviewView(context).apply { implementationMode = PreviewView.ImplementationMode.COMPATIBLE } } + + val reader = remember { + MultiFormatReader().apply { + setHints( + mapOf( + DecodeHintType.POSSIBLE_FORMATS to listOf(BarcodeFormat.QR_CODE), + DecodeHintType.CHARACTER_SET to "UTF-8", + ), + ) + } + } + + val mainExecutor = remember { ContextCompat.getMainExecutor(context) } + var lastPayload by remember { mutableStateOf(null) } + + fun onDecode(text: String?) { + if (finishing.get()) return + if (text.isNullOrBlank()) { + lastPayload = null + stableCount = 0 + hint = context.getString(R.string.qr_scan_hint_idle) + return + } + val trimmed = text.trim() + if (!LoginFlowClient.isCompleteQrPayload(trimmed)) { + lastPayload = null + stableCount = 0 + hint = context.getString(R.string.qr_scan_hint_align) + return + } + if (trimmed == lastPayload) { + stableCount += 1 + } else { + lastPayload = trimmed + stableCount = 1 + } + hint = if (stableCount >= REQUIRED_STABLE_READS) { + context.getString(R.string.qr_scan_hint_done) + } else { + context.getString(R.string.qr_scan_hint_progress, stableCount, REQUIRED_STABLE_READS) + } + if (stableCount >= REQUIRED_STABLE_READS) { + onStableResult(trimmed) + } + } + + DisposableEffect(previewView) { + val cameraProviderFuture = ProcessCameraProvider.getInstance(context) + cameraProviderFuture.addListener({ + val cameraProvider = cameraProviderFuture.get() + val preview = Preview.Builder().build().also { + it.surfaceProvider = previewView.surfaceProvider + } + val analysis = ImageAnalysis.Builder() + .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) + .build() + analysis.setAnalyzer(analysisExecutor) { imageProxy -> + val decoded = decodeQr(reader, imageProxy) + imageProxy.close() + mainExecutor.execute { onDecode(decoded) } + } + runCatching { + cameraProvider.unbindAll() + camera = cameraProvider.bindToLifecycle( + this@F7QrScannerActivity, + CameraSelector.DEFAULT_BACK_CAMERA, + preview, + analysis, + ) + } + }, mainExecutor) + onDispose { + runCatching { cameraProviderFuture.get().unbindAll() } + } + } + + Scaffold( + topBar = { + TopAppBar( + title = { Text(stringResource(R.string.qr_scan_title)) }, + navigationIcon = { + IconButton(onClick = onClose) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.qr_scan_close), + ) + } + }, + actions = { + IconButton( + onClick = { + val next = !torchEnabled + camera?.cameraControl?.enableTorch(next) + torchEnabled = next + }, + ) { + Text( + text = if (torchEnabled) { + stringResource(R.string.qr_scan_torch_off) + } else { + stringResource(R.string.qr_scan_torch_on) + }, + style = MaterialTheme.typography.labelLarge, + color = Color.White, + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = Color.Black.copy(alpha = 0.55f), + titleContentColor = Color.White, + navigationIconContentColor = Color.White, + actionIconContentColor = Color.White, + ), + ) + }, + containerColor = Color.Black, + ) { padding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(padding), + ) { + AndroidView( + modifier = Modifier.fillMaxSize(), + factory = { previewView }, + ) + + QrFinderOverlay(modifier = Modifier.fillMaxSize()) + + Text( + text = hint, + modifier = Modifier + .align(Alignment.BottomCenter) + .padding(horizontal = 24.dp, vertical = 32.dp), + style = MaterialTheme.typography.bodyLarge, + color = Color.White, + textAlign = TextAlign.Center, + ) + } + } + } + + @Composable + private fun QrFinderOverlay(modifier: Modifier = Modifier) { + val frameColor = F7Colors.Primary + Canvas(modifier = modifier) { + val frameSize = minOf(size.width, size.height) * 0.68f + val left = (size.width - frameSize) / 2f + val top = (size.height - frameSize) / 2f + val frameRect = Rect(Offset(left, top), Size(frameSize, frameSize)) + + val overlayPath = Path().apply { + fillType = PathFillType.EvenOdd + addRect(Rect(Offset.Zero, size)) + addRoundRect(RoundRect(frameRect, CornerRadius(16f, 16f))) + } + drawPath( + path = overlayPath, + color = Color.Black.copy(alpha = 0.55f), + ) + drawRoundRect( + color = frameColor, + topLeft = frameRect.topLeft, + size = frameRect.size, + cornerRadius = CornerRadius(16f, 16f), + style = Stroke(width = 4f), + blendMode = BlendMode.SrcOver, + ) + } + } + + private fun decodeQr(reader: MultiFormatReader, imageProxy: ImageProxy): String? { + if (imageProxy.format != android.graphics.ImageFormat.YUV_420_888) return null + val yBuffer = imageProxy.planes[0].buffer + val ySize = yBuffer.remaining() + val yuv = ByteArray(ySize) + yBuffer.get(yuv) + + val width = imageProxy.width + val height = imageProxy.height + val source = com.google.zxing.PlanarYUVLuminanceSource( + yuv, + width, + height, + 0, + 0, + width, + height, + false, + ) + return runCatching { + reader.decodeWithState(BinaryBitmap(HybridBinarizer(source))).text + }.getOrNull()?.also { + reader.reset() + } ?: run { + reader.reset() + null + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppLockGate.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppLockGate.kt new file mode 100644 index 0000000..bf8dcaf --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppLockGate.kt @@ -0,0 +1,704 @@ +package ru.forbion.f7cloud.mobile.ui + +import androidx.biometric.BiometricManager +import androidx.biometric.BiometricPrompt +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Fingerprint +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import androidx.core.content.ContextCompat +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.ProcessLifecycleOwner +import ru.forbion.f7cloud.core.auth.AppLockStore +import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton +import ru.forbion.f7cloud.core.designsystem.F7TextButton +import ru.forbion.f7cloud.mobile.R + +private enum class AppLockSetupStage { + Choose, + PinCreate, + PinConfirm, +} + +private const val PIN_LENGTH = 4 + +private fun biometricAuthenticators(): Int = + BiometricManager.Authenticators.BIOMETRIC_STRONG or + BiometricManager.Authenticators.BIOMETRIC_WEAK + +private fun canUseBiometric(context: android.content.Context): Boolean = + BiometricManager.from(context).canAuthenticate(biometricAuthenticators()) == + BiometricManager.BIOMETRIC_SUCCESS + +@Composable +fun AppLockGate( + lockStore: AppLockStore, + unlockNonce: Int = 0, + content: @Composable () -> Unit, +) { + if (!lockStore.isEnabled()) { + content() + return + } + var unlocked by remember { mutableStateOf(false) } + var lockSession by remember { mutableIntStateOf(0) } + + LaunchedEffect(Unit) { + if (lockStore.consumeColdStart()) { + unlocked = false + lockSession++ + } + } + + val processLifecycle = ProcessLifecycleOwner.get() + DisposableEffect(processLifecycle, lockStore) { + val observer = LifecycleEventObserver { _, event -> + when (event) { + Lifecycle.Event.ON_STOP -> lockStore.markBackgrounded() + Lifecycle.Event.ON_START -> { + when { + lockStore.consumeColdStart() -> { + unlocked = false + lockSession++ + } + lockStore.shouldRequireUnlock() -> { + unlocked = false + lockSession++ + } + } + } + else -> Unit + } + } + processLifecycle.lifecycle.addObserver(observer) + onDispose { processLifecycle.lifecycle.removeObserver(observer) } + } + + LaunchedEffect(unlockNonce) { + if (unlockNonce > 0) { + unlocked = true + lockStore.clearBackgroundMarker() + } + } + + if (unlocked) { + content() + return + } + AppLockUnlockScreen( + lockStore = lockStore, + lockSession = lockSession, + onUnlocked = { + lockStore.clearBackgroundMarker() + unlocked = true + }, + ) +} + +@Composable +fun AppLockSetupDialog( + visible: Boolean, + lockStore: AppLockStore, + onDismiss: () -> Unit, + onLockConfigured: () -> Unit = {}, +) { + if (!visible) return + + val context = LocalContext.current + val activity = context.findFragmentActivity() + var stage by remember { mutableStateOf(AppLockSetupStage.Choose) } + var firstPin by remember { mutableStateOf("") } + var currentPin by remember { mutableStateOf("") } + var error by remember { mutableStateOf(null) } + + val biometricAvailable = remember { canUseBiometric(context) } + + fun finishSkip() { + lockStore.markSetupOffered() + onDismiss() + } + + fun finishPinSetup(pin: String) { + lockStore.enable(pin, biometric = false) + lockStore.markSetupOffered() + onLockConfigured() + onDismiss() + } + + fun finishBiometricSetup() { + lockStore.enableBiometricOnly() + lockStore.markSetupOffered() + onLockConfigured() + onDismiss() + } + + fun launchBiometricSetup() { + val host = activity ?: run { + error = "Биометрия недоступна на этом устройстве" + return + } + val executor = ContextCompat.getMainExecutor(context) + val prompt = BiometricPrompt( + host, + executor, + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { + finishBiometricSetup() + } + + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + if (errorCode != BiometricPrompt.ERROR_USER_CANCELED && + errorCode != BiometricPrompt.ERROR_NEGATIVE_BUTTON + ) { + error = errString.toString() + } + } + }, + ) + prompt.authenticate( + BiometricPrompt.PromptInfo.Builder() + .setTitle("Биометрия") + .setSubtitle("Подтвердите отпечаток пальца для защиты приложения") + .setNegativeButtonText("Отмена") + .setAllowedAuthenticators(biometricAuthenticators()) + .build(), + ) + } + + fun appendDigit(digit: String) { + if (currentPin.length >= PIN_LENGTH) return + currentPin += digit + error = null + if (currentPin.length == PIN_LENGTH) { + when (stage) { + AppLockSetupStage.PinCreate -> { + firstPin = currentPin + currentPin = "" + stage = AppLockSetupStage.PinConfirm + } + AppLockSetupStage.PinConfirm -> { + if (currentPin == firstPin) { + finishPinSetup(currentPin) + } else { + error = "PIN-коды не совпадают" + currentPin = "" + firstPin = "" + stage = AppLockSetupStage.PinCreate + } + } + else -> Unit + } + } + } + + fun removeDigit() { + if (currentPin.isNotEmpty()) { + currentPin = currentPin.dropLast(1) + error = null + } + } + + Dialog( + onDismissRequest = {}, + properties = DialogProperties( + dismissOnBackPress = false, + dismissOnClickOutside = false, + usePlatformDefaultWidth = false, + ), + ) { + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp), + shape = RoundedCornerShape(16.dp), + color = Color.White, + ) { + when (stage) { + AppLockSetupStage.Choose -> AppLockSetupChoiceContent( + canUseBiometric = biometricAvailable, + error = error, + onChoosePin = { + error = null + currentPin = "" + firstPin = "" + stage = AppLockSetupStage.PinCreate + }, + onChooseBiometric = { + error = null + launchBiometricSetup() + }, + onSkip = ::finishSkip, + ) + AppLockSetupStage.PinCreate, + AppLockSetupStage.PinConfirm, + -> AppLockPinKeypadContent( + title = if (stage == AppLockSetupStage.PinCreate) { + "Придумайте PIN-код" + } else { + "Повторите PIN-код" + }, + subtitle = if (stage == AppLockSetupStage.PinCreate) { + "Введите $PIN_LENGTH цифры на клавиатуре ниже" + } else { + "Подтвердите PIN-код ещё раз" + }, + pinLength = currentPin.length, + maxPinLength = PIN_LENGTH, + error = error, + onDigit = ::appendDigit, + onBackspace = ::removeDigit, + onBack = { + error = null + currentPin = "" + firstPin = "" + stage = AppLockSetupStage.Choose + }, + ) + } + } + } +} + +@Composable +private fun AppLockSetupChoiceContent( + canUseBiometric: Boolean, + error: String?, + onChoosePin: () -> Unit, + onChooseBiometric: () -> Unit, + onSkip: () -> Unit, +) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp, vertical = 28.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + Text( + text = "Защита приложения", + style = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.SemiBold, + color = F7Colors.TextPrimary, + textAlign = TextAlign.Center, + ) + Text( + text = "Вы хотите использовать PIN-код или отпечаток пальца?", + style = MaterialTheme.typography.bodyLarge, + color = F7Colors.TextSecondary, + textAlign = TextAlign.Center, + modifier = Modifier.padding(bottom = 8.dp), + ) + if (!error.isNullOrBlank()) { + Text( + text = error, + color = F7Colors.Error, + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Center, + ) + } + F7PrimaryButton( + text = "PIN-код", + onClick = onChoosePin, + modifier = Modifier.fillMaxWidth(), + ) + if (canUseBiometric) { + F7PrimaryButton( + text = "Отпечаток пальца", + onClick = onChooseBiometric, + modifier = Modifier.fillMaxWidth(), + ) + } + Spacer(modifier = Modifier.height(4.dp)) + F7TextButton( + text = "Пропустить", + onClick = onSkip, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +@Composable +private fun AppLockPinKeypadContent( + title: String, + subtitle: String, + pinLength: Int, + maxPinLength: Int, + error: String?, + onDigit: (String) -> Unit, + onBackspace: () -> Unit, + onBack: (() -> Unit)? = null, + extraAction: (@Composable () -> Unit)? = null, + header: (@Composable () -> Unit)? = null, +) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + if (onBack != null) { + F7TextButton( + text = "← Назад", + onClick = onBack, + modifier = Modifier.align(Alignment.Start), + ) + } + header?.invoke() + Text( + text = title, + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.SemiBold, + color = F7Colors.TextPrimary, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 4.dp), + ) + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = F7Colors.TextSecondary, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 8.dp, bottom = 20.dp), + ) + PinDots( + filledCount = pinLength, + totalCount = maxPinLength, + ) + if (!error.isNullOrBlank()) { + Text( + text = error, + color = F7Colors.Error, + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 12.dp), + ) + } + Spacer(modifier = Modifier.height(20.dp)) + PinNumericKeypad( + onDigit = onDigit, + onBackspace = onBackspace, + ) + extraAction?.invoke() + } +} + +@Composable +private fun PinDots(filledCount: Int, totalCount: Int) { + Row( + horizontalArrangement = Arrangement.spacedBy(14.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + repeat(totalCount) { index -> + Box( + modifier = Modifier + .size(14.dp) + .clip(CircleShape) + .background( + if (index < filledCount) { + F7Colors.Primary + } else { + Color(0xFFE6E6E6) + }, + ), + ) + } + } +} + +@Composable +private fun PinNumericKeypad( + onDigit: (String) -> Unit, + onBackspace: () -> Unit, +) { + val rows = listOf( + listOf("1", "2", "3"), + listOf("4", "5", "6"), + listOf("7", "8", "9"), + listOf("", "0", "⌫"), + ) + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + rows.forEach { row -> + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + row.forEach { key -> + when (key) { + "" -> Spacer(modifier = Modifier.size(72.dp)) + "⌫" -> PinKey( + label = "⌫", + onClick = onBackspace, + ) + else -> PinKey( + label = key, + onClick = { onDigit(key) }, + ) + } + } + } + } + } +} + +@Composable +private fun PinKey( + label: String, + onClick: () -> Unit, +) { + Box( + modifier = Modifier + .size(72.dp) + .clip(CircleShape) + .background(Color(0xFFF3F3F3)) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = label, + fontSize = if (label == "⌫") 24.sp else 28.sp, + fontWeight = FontWeight.Medium, + color = F7Colors.TextPrimary, + ) + } +} + +@Composable +private fun AppLockBrandedBackdrop( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit = {}, +) { + Column( + modifier = modifier + .fillMaxSize() + .background(Color.White) + .padding(horizontal = 32.dp, vertical = 48.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Image( + painter = painterResource(R.drawable.f7_app_lock_logo), + contentDescription = "F7cloud", + modifier = Modifier + .fillMaxWidth(0.88f) + .padding(bottom = 28.dp), + contentScale = ContentScale.Fit, + ) + content() + } +} + +@Composable +private fun AppLockUnlockScreen( + lockStore: AppLockStore, + lockSession: Int, + onUnlocked: () -> Unit, +) { + val context = LocalContext.current + val activity = context.findFragmentActivity() + var pin by remember { mutableStateOf("") } + var error by remember { mutableStateOf(null) } + var showPinEntry by remember(lockSession) { mutableStateOf(!lockStore.useBiometric()) } + val biometricOnly = lockStore.isBiometricOnly() + val biometricAvailable = remember { canUseBiometric(context) } + + fun verifyPinInput() { + if (lockStore.verifyPin(pin)) { + onUnlocked() + } else { + error = "Неверный PIN" + pin = "" + } + } + + fun appendDigit(digit: String) { + if (pin.length >= PIN_LENGTH) return + pin += digit + error = null + if (pin.length == PIN_LENGTH) { + verifyPinInput() + } + } + + fun removeDigit() { + if (pin.isNotEmpty()) { + pin = pin.dropLast(1) + error = null + } + } + + fun launchBiometricUnlock() { + val host = activity ?: run { + error = "Биометрия недоступна" + return + } + val executor = ContextCompat.getMainExecutor(context) + val prompt = BiometricPrompt( + host, + executor, + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { + onUnlocked() + } + + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + when (errorCode) { + BiometricPrompt.ERROR_NEGATIVE_BUTTON -> { + if (!biometricOnly) { + showPinEntry = true + } + } + BiometricPrompt.ERROR_USER_CANCELED -> Unit + else -> error = errString.toString() + } + } + }, + ) + prompt.authenticate( + BiometricPrompt.PromptInfo.Builder() + .setTitle("Разблокировка F7cloud") + .setSubtitle("Прикоснитесь к сканеру отпечатка") + .setAllowedAuthenticators(biometricAuthenticators()) + .setNegativeButtonText(if (biometricOnly) "Отмена" else "Ввести PIN") + .build(), + ) + } + + LaunchedEffect(lockSession, lockStore.useBiometric(), activity) { + if (lockStore.useBiometric() && biometricAvailable && activity != null && !showPinEntry) { + launchBiometricUnlock() + } + } + + if (showPinEntry && !biometricOnly) { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + AppLockPinKeypadContent( + title = "Введите PIN-код", + subtitle = "Для доступа к приложению", + pinLength = pin.length, + maxPinLength = PIN_LENGTH, + error = error, + onDigit = ::appendDigit, + onBackspace = ::removeDigit, + onBack = if (lockStore.useBiometric() && biometricAvailable) { + { + error = null + pin = "" + showPinEntry = false + } + } else { + null + }, + header = { + Image( + painter = painterResource(R.drawable.f7_app_lock_logo), + contentDescription = "F7cloud", + modifier = Modifier + .fillMaxWidth(0.75f) + .padding(bottom = 16.dp), + contentScale = ContentScale.Fit, + ) + }, + ) + } + return + } + + AppLockBrandedBackdrop { + if (lockStore.useBiometric() && biometricAvailable) { + Icon( + imageVector = Icons.Filled.Fingerprint, + contentDescription = null, + tint = F7Colors.Primary, + modifier = Modifier.size(56.dp), + ) + Text( + text = "Прикоснитесь к сканеру отпечатка", + style = MaterialTheme.typography.bodyLarge, + color = F7Colors.TextSecondary, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 16.dp), + ) + if (!error.isNullOrBlank()) { + Text( + text = error ?: "", + color = F7Colors.Error, + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Center, + modifier = Modifier.padding(top = 12.dp), + ) + } + F7PrimaryButton( + text = "Сканер отпечатка", + onClick = ::launchBiometricUnlock, + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp), + ) + } + if (!biometricOnly && lockStore.useBiometric() && biometricAvailable) { + F7TextButton( + text = "Ввести PIN", + onClick = { showPinEntry = true }, + modifier = Modifier.padding(top = 12.dp), + ) + } + } +} + +private fun android.content.Context.findFragmentActivity(): FragmentActivity? { + var ctx: android.content.Context = this + while (true) { + when (ctx) { + is FragmentActivity -> return ctx + is android.content.ContextWrapper -> ctx = ctx.baseContext + else -> return null + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt new file mode 100644 index 0000000..4810194 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppMenuRepository.kt @@ -0,0 +1,68 @@ +package ru.forbion.f7cloud.mobile.ui + +import okhttp3.Request +import org.json.JSONArray +import org.json.JSONObject +import ru.forbion.f7cloud.core.auth.AuthSession +import ru.forbion.f7cloud.core.network.NetworkFactory +import ru.forbion.f7cloud.core.network.UnauthorizedException +import ru.forbion.f7cloud.core.network.applyOcsJson + +object AppMenuRepository { + fun fetchExternalSites(session: AuthSession): List { + val client = NetworkFactory.newAuthedClient( + session.username, + session.appPassword, + session.trustAllCerts, + ) + val url = "${session.serverUrl.trimEnd('/')}/ocs/v2.php/apps/external/api/v1?format=json" + val request = Request.Builder().url(url).applyOcsJson().get().build() + return runCatching { + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (!response.isSuccessful || response.body == null) { + return emptyList() + } + val body = response.body!!.string() + val array = when { + body.trimStart().startsWith("[") -> JSONArray(body) + else -> { + val data = JSONObject(body).optJSONObject("ocs")?.opt("data") + when (data) { + is JSONArray -> data + else -> JSONArray() + } + } + } + (0 until array.length()).mapNotNull { index -> + val site = array.optJSONObject(index) ?: return@mapNotNull null + val name = site.optString("name").ifBlank { return@mapNotNull null } + val icon = site.optString("icon").ifBlank { null } + val redirect = site.optInt("redirect", 0) == 1 + val rawUrl = site.optString("url") + val siteId = site.optInt("id", -1) + val openUrl = when { + redirect && rawUrl.isNotBlank() -> rawUrl + siteId >= 0 -> "${session.serverUrl.trimEnd('/')}/index.php/apps/external/$siteId/" + rawUrl.isNotBlank() -> rawUrl + else -> return@mapNotNull null + } + AppMenuExternalSite( + name = name, + iconUrl = icon ?: defaultExternalIcon(session.serverUrl, name), + openUrl = openUrl, + ) + } + } + }.getOrDefault(emptyList()) + } + + private fun defaultExternalIcon(serverUrl: String, name: String): String { + val base = serverUrl.trimEnd('/') + return when { + name.contains("bitrix", ignoreCase = true) -> "$base/themes/forbion/images/header/bitrix-glass.svg" + name.contains("1c", ignoreCase = true) -> "$base/themes/forbion/images/header/1c-glass.svg" + else -> "$base/index.php/apps/external/img/external.svg" + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt new file mode 100644 index 0000000..6ba1302 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppNavigation.kt @@ -0,0 +1,79 @@ +package ru.forbion.f7cloud.mobile.ui + +import ru.forbion.f7cloud.core.designsystem.F7AppMenuItem + +enum class AppTab( + val title: String, + val headerIconPath: String, + val menuIconPath: String, +) { + Mail("Почта", "mail-header-icon.svg", "mail-glass.svg"), + Files("Файлы", "files-header-icon.svg", "files-glass.svg"), + Calendar("Календарь", "calendar-header-icon.svg", "calendar-glass.svg"), + Contacts("Контакты", "contacts-header-icon.svg", "contact-glass.svg"), + Talk("Конференции", "spreed-header-icon.svg", "spreed-glass.svg"), + Deck("Карточки", "deck-header-icon.svg", "deck-glass.svg"), + Tasks("Задачи", "task-header-icon.svg", "task-glass.svg"), + Support("Поддержка", "icon-header-f7support.svg", "icon-header-f7support.svg"), + ; + + fun menuIconUrl(serverUrl: String): String { + return "${serverUrl.trimEnd('/')}/themes/forbion/images/header/$menuIconPath" + } +} + +private data class AppMenuEntry( + val tab: AppTab?, + val label: String, + val iconPath: String, + val webPath: String? = null, +) + +private val coreAppMenuEntries = listOf( + AppMenuEntry(AppTab.Mail, "Почта", "mail-glass.svg"), + AppMenuEntry(AppTab.Files, "Файлы", "files-glass.svg"), + AppMenuEntry(AppTab.Calendar, "Календарь", "calendar-glass.svg"), + AppMenuEntry(AppTab.Contacts, "Контакты", "contact-glass.svg"), + AppMenuEntry(AppTab.Talk, "Конференции", "spreed-glass.svg"), + AppMenuEntry(AppTab.Deck, "Карточки", "deck-glass.svg"), + AppMenuEntry(AppTab.Tasks, "Задачи", "task-glass.svg"), + AppMenuEntry(null, "Заметки", "notes-glass.svg", webPath = "/apps/notes/"), + AppMenuEntry(AppTab.Support, "Поддержка", "icon-header-f7support.svg"), +) + +data class AppMenuExternalSite( + val name: String, + val iconUrl: String, + val openUrl: String, +) + +val appMenuTabs: List = AppTab.entries + +fun appMenuItems( + serverUrl: String, + active: AppTab, + externalSites: List = emptyList(), +): List { + val base = serverUrl.trimEnd('/') + val core = coreAppMenuEntries.map { entry -> + F7AppMenuItem( + label = entry.label, + iconUrl = "$base/themes/forbion/images/header/${entry.iconPath}", + selected = entry.tab == active, + externalUrl = entry.webPath?.let { "$base$it" }, + ) + } + val external = externalSites.map { site -> + F7AppMenuItem( + label = site.name, + iconUrl = site.iconUrl, + selected = false, + externalUrl = site.openUrl, + ) + } + return core + external +} + +fun appTabFromMenuIndex(index: Int): AppTab? { + return coreAppMenuEntries.getOrNull(index)?.tab +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt new file mode 100644 index 0000000..aa4e59d --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppScaffold.kt @@ -0,0 +1,919 @@ +package ru.forbion.f7cloud.mobile.ui + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.widget.Toast +import androidx.activity.compose.BackHandler +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.ui.input.pointer.PointerEventPass +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusProperties +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableLongStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.Saver +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import coil.compose.AsyncImage +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LocalLifecycleOwner +import com.google.firebase.messaging.FirebaseMessaging +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.tasks.await +import ru.forbion.f7cloud.core.auth.AppLockStore +import ru.forbion.f7cloud.core.auth.AuthSession +import ru.forbion.f7cloud.core.auth.AuthStore +import ru.forbion.f7cloud.core.auth.AuthVerifier +import ru.forbion.f7cloud.core.auth.normalizeServerUrl +import ru.forbion.f7cloud.core.network.LoginFlowClient +import ru.forbion.f7cloud.core.push.F7PushEvent +import ru.forbion.f7cloud.core.push.F7PushEventHub +import ru.forbion.f7cloud.core.push.F7PushRegistrar +import ru.forbion.f7cloud.core.designsystem.F7OverlayNavigationProvider +import ru.forbion.f7cloud.core.designsystem.F7AppMenuSheet +import ru.forbion.f7cloud.core.designsystem.F7AppScaffold +import ru.forbion.f7cloud.core.designsystem.F7AutoHideBottomBar +import ru.forbion.f7cloud.core.designsystem.F7BottomBarActions +import ru.forbion.f7cloud.core.designsystem.F7BottomBarConfig +import ru.forbion.f7cloud.core.designsystem.F7MobileBottomBar +import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7OutlinedField +import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton +import ru.forbion.f7cloud.core.designsystem.F7TextButton +import ru.forbion.f7cloud.core.designsystem.F7Theme +import ru.forbion.f7cloud.core.designsystem.f7SafeTopInsets +import ru.forbion.f7cloud.mobile.OfficeEditorActivity +import ru.forbion.f7cloud.mobile.qr.F7QrScannerActivity +import ru.forbion.f7cloud.mobile.OfficeWebViewPool +import ru.forbion.f7cloud.feature.files.OfficeWarmup +import ru.forbion.f7cloud.mobile.permissions.F7AppPermissions +import ru.forbion.f7cloud.mobile.permissions.F7PermissionRationaleDialog +import ru.forbion.f7cloud.feature.calendar.CalendarScreen +import ru.forbion.f7cloud.feature.contacts.ContactsScreen +import ru.forbion.f7cloud.feature.deck.DeckScreen +import ru.forbion.f7cloud.feature.files.FilesScreen +import ru.forbion.f7cloud.feature.f7support.SupportScreen +import ru.forbion.f7cloud.feature.mail.MailScreen +import ru.forbion.f7cloud.feature.tasks.TasksScreen +import ru.forbion.f7cloud.feature.talk.TalkScreen +import ru.forbion.f7cloud.mobile.navigation.AppLinkResolver +import ru.forbion.f7cloud.mobile.navigation.AppLinkTarget + +@Composable +fun AppScaffold( + openUrl: String? = null, + onOpenUrlConsumed: () -> Unit = {}, + onRequestRuntimePermissions: (onFinished: (() -> Unit)?) -> Unit = {}, +) { + val context = LocalContext.current + val authStore = remember { AuthStore(context) } + var session by remember { mutableStateOf(authStore.load()) } + var activeTab by rememberSaveable( + saver = Saver( + save = { state -> state.value.name }, + restore = { name -> + mutableStateOf( + if (name == "Widgets") AppTab.Files + else runCatching { AppTab.valueOf(name) }.getOrDefault(AppTab.Files), + ) + }, + ), + ) { mutableStateOf(AppTab.Files) } + var pendingOpenUrl by rememberSaveable { mutableStateOf(null) } + var pendingTalkRoomToken by rememberSaveable { mutableStateOf(null) } + var pendingTalkMessageId by rememberSaveable { mutableStateOf(null) } + var pendingSupportTicket by rememberSaveable { mutableStateOf(null) } + var pendingMailMessageId by rememberSaveable { mutableIntStateOf(-1) } + var pendingMailMailboxId by rememberSaveable { mutableIntStateOf(-1) } + var pendingCalendarEventUid by rememberSaveable { mutableStateOf(null) } + var pendingDeckCardId by rememberSaveable { mutableIntStateOf(-1) } + var pendingTasksListSlug by rememberSaveable { mutableStateOf(null) } + var pendingFileId by rememberSaveable { mutableStateOf(null) } + var tabHistory by rememberSaveable { mutableStateOf(emptyList()) } + var menuOpen by rememberSaveable { mutableStateOf(false) } + var talkInRoom by rememberSaveable { mutableStateOf(false) } + var mailInMessage by rememberSaveable { mutableStateOf(false) } + var bottomBarActivity by remember { mutableIntStateOf(0) } + var lastBottomBarPulse by remember { mutableLongStateOf(0L) } + var profileOpen by rememberSaveable { mutableStateOf(false) } + var notificationsOpen by rememberSaveable { mutableStateOf(false) } + var mailSidebarOpen by rememberSaveable { mutableStateOf(false) } + var calendarSidebarOpen by rememberSaveable { mutableStateOf(false) } + var filesSidebarOpen by rememberSaveable { mutableStateOf(false) } + var mailSettingsOpen by rememberSaveable { mutableStateOf(false) } + var filesSettingsOpen by rememberSaveable { mutableStateOf(false) } + val bottomBarPinned = menuOpen || profileOpen || notificationsOpen || + (activeTab == AppTab.Mail && (mailSidebarOpen || mailSettingsOpen)) || + (activeTab == AppTab.Calendar && calendarSidebarOpen) || + (activeTab == AppTab.Files && (filesSidebarOpen || filesSettingsOpen)) + var filesUploadRequest by remember { mutableIntStateOf(0) } + var contactsCreateRequest by remember { mutableIntStateOf(0) } + var tasksCreateRequest by remember { mutableIntStateOf(0) } + var supportCreateRequest by remember { mutableIntStateOf(0) } + var calendarSettingsRequest by remember { mutableIntStateOf(0) } + var talkChatsRequest by remember { mutableIntStateOf(0) } + var mailPushRequest by remember { mutableIntStateOf(0) } + var talkPushRequest by remember { mutableIntStateOf(0) } + var filesPushRequest by remember { mutableIntStateOf(0) } + var notificationsPushRequest by remember { mutableIntStateOf(0) } + var pushTalkRoomToken by remember { mutableStateOf(null) } + var hasNotificationBadge by rememberSaveable { mutableStateOf(false) } + val permissionPrefs = remember { + context.applicationContext.getSharedPreferences("f7_permissions", android.content.Context.MODE_PRIVATE) + } + + val forceLogout = { + OfficeWarmup.clear() + OfficeWebViewPool.dispose() + authStore.clear() + session = null + } + LaunchedEffect(session?.serverUrl, session?.username) { + session?.let { OfficeWarmup.warm(it) } + } + LaunchedEffect(openUrl) { + if (!openUrl.isNullOrBlank()) { + pendingOpenUrl = openUrl + onOpenUrlConsumed() + } + } + + F7Theme { + if (session == null) { + LoginScreen(onLogin = { + authStore.save(it) + session = it + }) + return@F7Theme + } + + val currentSession = session!! + var externalMenuSites by remember { mutableStateOf>(emptyList()) } + val appMenuItemsList = remember(currentSession.serverUrl, activeTab, externalMenuSites) { + appMenuItems(currentSession.serverUrl, activeTab, externalMenuSites) + } + LaunchedEffect(menuOpen, currentSession.serverUrl, currentSession.username) { + if (!menuOpen) return@LaunchedEffect + externalMenuSites = withContext(Dispatchers.IO) { + AppMenuRepository.fetchExternalSites(currentSession) + } + } + val lockStore = remember { AppLockStore(context) } + var showAppLockSetup by rememberSaveable { mutableStateOf(false) } + var lockUnlockNonce by remember { mutableIntStateOf(0) } + LaunchedEffect(currentSession.serverUrl, currentSession.username) { + if (lockStore.shouldOfferSetup()) { + showAppLockSetup = true + } + } + AppLockSetupDialog( + visible = showAppLockSetup, + lockStore = lockStore, + onDismiss = { showAppLockSetup = false }, + onLockConfigured = { lockUnlockNonce++ }, + ) + AppLockGate(lockStore = lockStore, unlockNonce = lockUnlockNonce) { + fun applyAppLink(target: AppLinkTarget) { + activeTab = target.tab + pendingTalkRoomToken = target.talkRoomToken + pendingTalkMessageId = target.talkMessageId + pendingSupportTicket = target.supportTicket + pendingMailMessageId = target.mailMessageId ?: -1 + pendingMailMailboxId = target.mailMailboxId ?: -1 + pendingCalendarEventUid = target.calendarEventUid + pendingDeckCardId = target.deckCardId ?: -1 + pendingFileId = target.fileId + pendingTasksListSlug = target.tasksListSlug + } + fun openAppLink(url: String) { + AppLinkResolver.resolve(url, currentSession.serverUrl)?.let { applyAppLink(it) } + } + LaunchedEffect(pendingOpenUrl) { + val url = pendingOpenUrl ?: return@LaunchedEffect + openAppLink(url) + pendingOpenUrl = null + } + val userId = currentSession.davUserId ?: currentSession.username + val lifecycleOwner = LocalLifecycleOwner.current + val scope = rememberCoroutineScope() + var browserQrBusy by rememberSaveable { mutableStateOf(false) } + + val browserQrLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult(), + ) { result -> + if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult + val qrData = result.data?.getStringExtra(F7QrScannerActivity.RESULT_EXTRA) + ?: return@rememberLauncherForActivityResult + scope.launch { + browserQrBusy = true + val approved = LoginFlowClient.approveBrowserLoginFromQr( + qrData = qrData, + username = currentSession.username, + appPassword = currentSession.appPassword, + trustAllCerts = currentSession.trustAllCerts, + ) + browserQrBusy = false + val message = if (approved) { + "Браузер авторизован" + } else { + "Не удалось подтвердить вход в браузере" + } + Toast.makeText(context.applicationContext, message, Toast.LENGTH_LONG).show() + } + } + + val browserQrCameraLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.RequestPermission(), + ) { granted -> + if (granted) { + browserQrLauncher.launch(F7QrScannerActivity.intent(context)) + } + } + + fun launchBrowserQrScan() { + if (browserQrBusy) return + if (androidx.core.content.ContextCompat.checkSelfPermission( + context, + android.Manifest.permission.CAMERA, + ) == android.content.pm.PackageManager.PERMISSION_GRANTED + ) { + browserQrLauncher.launch(F7QrScannerActivity.intent(context)) + } else { + browserQrCameraLauncher.launch(android.Manifest.permission.CAMERA) + } + } + + var showPermissionRationale by rememberSaveable { mutableStateOf(false) } + var permissionFlowStarted by rememberSaveable { mutableStateOf(false) } + + fun registerFcmPush() { + scope.launch(Dispatchers.IO) { + runCatching { + val token = FirebaseMessaging.getInstance().token.await() + val code = F7PushRegistrar.registerBlocking(context, currentSession, token) + android.util.Log.i("F7Push", "AppScaffold register result: $code") + }.onFailure { + android.util.Log.e("F7Push", "AppScaffold register failed", it) + } + } + } + + fun startPermissionRequest() { + permissionFlowStarted = true + onRequestRuntimePermissions { registerFcmPush() } + } + + DisposableEffect(lifecycleOwner, currentSession.serverUrl, currentSession.username) { + val observer = LifecycleEventObserver { _, event -> + if (event != Lifecycle.Event.ON_RESUME) return@LifecycleEventObserver + if (permissionFlowStarted) return@LifecycleEventObserver + if (F7AppPermissions.hasAll(context)) { + permissionFlowStarted = true + registerFcmPush() + return@LifecycleEventObserver + } + val alreadyPrompted = permissionPrefs.getBoolean(PERMISSIONS_PROMPTED_KEY, false) + if (!alreadyPrompted) { + permissionFlowStarted = true + showPermissionRationale = true + } else { + startPermissionRequest() + } + } + lifecycleOwner.lifecycle.addObserver(observer) + onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } + } + + F7PermissionRationaleDialog( + visible = showPermissionRationale, + onConfirm = { + showPermissionRationale = false + permissionPrefs.edit().putBoolean(PERMISSIONS_PROMPTED_KEY, true).apply() + startPermissionRequest() + }, + onDismiss = { + showPermissionRationale = false + permissionPrefs.edit().putBoolean(PERMISSIONS_PROMPTED_KEY, true).apply() + registerFcmPush() + }, + ) + + LaunchedEffect(activeTab) { + if (activeTab == AppTab.Talk && !F7AppPermissions.hasAll(context)) { + delay(400) + onRequestRuntimePermissions(null) + } + } + + LaunchedEffect(Unit) { + F7PushEventHub.events.collect { event -> + when (event) { + is F7PushEvent.Mail -> { + mailPushRequest++ + event.messageId?.let { pendingMailMessageId = it } + event.mailboxId?.let { pendingMailMailboxId = it } + } + is F7PushEvent.Talk -> { + pushTalkRoomToken = event.roomToken + talkPushRequest++ + event.messageId?.let { pendingTalkMessageId = it } + event.roomToken?.let { pendingTalkRoomToken = it } + } + is F7PushEvent.Files -> { + filesPushRequest++ + event.fileId?.let { pendingFileId = it } + } + is F7PushEvent.Notification -> { + notificationsPushRequest++ + hasNotificationBadge = true + } + is F7PushEvent.Call -> Unit + } + } + } + + LaunchedEffect(activeTab) { + if (activeTab != AppTab.Mail) { + mailInMessage = false + } + if (activeTab != AppTab.Calendar) { + calendarSidebarOpen = false + } + } + + LaunchedEffect(mailInMessage) { + if (mailInMessage) { + bottomBarActivity++ + } + } + + val bottomBarConfig = remember(activeTab, talkInRoom) { + F7BottomBarConfig.forContext(activeTab.name, talkInRoom) + } + + fun pushTabHistory(from: AppTab) { + tabHistory = (tabHistory + from.name).takeLast(20) + } + fun popTabHistory(): AppTab? { + if (tabHistory.isEmpty()) return null + val name = tabHistory.last() + tabHistory = tabHistory.dropLast(1) + return runCatching { AppTab.valueOf(name) }.getOrNull() + } + fun dismissSwipeOverlay(): Boolean { + when { + menuOpen -> menuOpen = false + profileOpen -> profileOpen = false + notificationsOpen -> notificationsOpen = false + mailSettingsOpen -> mailSettingsOpen = false + filesSettingsOpen -> filesSettingsOpen = false + mailSidebarOpen -> mailSidebarOpen = false + calendarSidebarOpen -> calendarSidebarOpen = false + filesSidebarOpen -> filesSidebarOpen = false + else -> return false + } + return true + } + + BackHandler { + when { + menuOpen -> menuOpen = false + profileOpen -> profileOpen = false + notificationsOpen -> notificationsOpen = false + mailSidebarOpen -> mailSidebarOpen = false + calendarSidebarOpen -> calendarSidebarOpen = false + filesSidebarOpen -> filesSidebarOpen = false + mailSettingsOpen -> mailSettingsOpen = false + filesSettingsOpen -> filesSettingsOpen = false + else -> { + val previous = popTabHistory() + if (previous != null) { + activeTab = previous + } else { + (context as? Activity)?.moveTaskToBack(false) + } + } + } + } + + F7OverlayNavigationProvider( + onSwipeDismiss = ::dismissSwipeOverlay, + modifier = Modifier.fillMaxSize(), + ) { + Box( + modifier = Modifier + .fillMaxSize() + .pointerInput(Unit) { + awaitEachGesture { + awaitFirstDown(pass = PointerEventPass.Initial) + val now = System.currentTimeMillis() + if (now - lastBottomBarPulse >= 800L) { + lastBottomBarPulse = now + bottomBarActivity++ + } + } + }, + ) { + F7AppScaffold( + bottomBar = { + if ((activeTab != AppTab.Talk || !talkInRoom)) { + F7AutoHideBottomBar( + enabled = true, + pinned = bottomBarPinned, + activityNonce = bottomBarActivity, + hideDelayMs = 4000L, + ) { + F7MobileBottomBar( + serverUrl = currentSession.serverUrl, + userId = userId, + config = bottomBarConfig, + menuOpen = menuOpen, + chatsHighlighted = activeTab == AppTab.Talk && !talkInRoom, + navBackHighlighted = (activeTab == AppTab.Mail && mailSidebarOpen) || + (activeTab == AppTab.Calendar && calendarSidebarOpen) || + (activeTab == AppTab.Files && filesSidebarOpen), + showNotificationBadge = hasNotificationBadge, + actions = F7BottomBarActions( + onChatsClick = { talkChatsRequest++ }, + onNavBackClick = { + when (activeTab) { + AppTab.Mail -> mailSidebarOpen = !mailSidebarOpen + AppTab.Calendar -> calendarSidebarOpen = !calendarSidebarOpen + AppTab.Files -> filesSidebarOpen = !filesSidebarOpen + else -> Unit + } + }, + onCreateClick = { + when (activeTab) { + AppTab.Files -> { + if (F7AppPermissions.missing(context).isNotEmpty()) { + onRequestRuntimePermissions { filesUploadRequest++ } + } else { + filesUploadRequest++ + } + } + AppTab.Contacts -> contactsCreateRequest++ + AppTab.Tasks -> tasksCreateRequest++ + AppTab.Support -> supportCreateRequest++ + else -> Unit + } + }, + onProfileClick = { + menuOpen = false + profileOpen = true + }, + onNotificationsClick = { + menuOpen = false + hasNotificationBadge = false + notificationsOpen = true + }, + onSettingsClick = { + when (activeTab) { + AppTab.Mail -> mailSettingsOpen = true + AppTab.Calendar -> calendarSettingsRequest++ + AppTab.Files -> filesSettingsOpen = true + else -> Unit + } + }, + onMenuClick = { menuOpen = !menuOpen }, + ), + ) + } + } + }, + ) { contentModifier -> + when (activeTab) { + AppTab.Mail -> MailScreen( + session = currentSession, + modifier = contentModifier, + openMessageId = pendingMailMessageId.takeIf { it > 0 }, + openMailboxId = pendingMailMailboxId.takeIf { it > 0 }, + sidebarOpen = mailSidebarOpen, + onSidebarOpenChange = { mailSidebarOpen = it }, + settingsOpen = mailSettingsOpen, + onSettingsOpenChange = { mailSettingsOpen = it }, + pushRefreshRequest = mailPushRequest, + onOpenMessageConsumed = { pendingMailMessageId = -1; pendingMailMailboxId = -1 }, + onMessageOpenStateChange = { mailInMessage = it }, + onUnauthorized = forceLogout, + ) + AppTab.Files -> FilesScreen( + session = currentSession, + modifier = contentModifier, + uploadRequest = filesUploadRequest, + pushRefreshRequest = filesPushRequest, + openFileId = pendingFileId, + sidebarOpen = filesSidebarOpen, + onSidebarOpenChange = { filesSidebarOpen = it }, + settingsOpen = filesSettingsOpen, + onSettingsOpenChange = { filesSettingsOpen = it }, + onOpenFileConsumed = { pendingFileId = null }, + onUnauthorized = forceLogout, + onOpenOfficeEditor = { launch -> + context.startActivity(OfficeEditorActivity.intent(context, launch)) + }, + ) + AppTab.Calendar -> CalendarScreen( + session = currentSession, + modifier = contentModifier, + focusEventUid = pendingCalendarEventUid, + settingsRequest = calendarSettingsRequest, + sidebarOpen = calendarSidebarOpen, + onSidebarOpenChange = { calendarSidebarOpen = it }, + onFocusEventConsumed = { pendingCalendarEventUid = null }, + onUnauthorized = forceLogout, + ) + AppTab.Contacts -> ContactsScreen( + session = currentSession, + modifier = contentModifier, + createRequest = contactsCreateRequest, + onUnauthorized = forceLogout, + ) + AppTab.Talk -> { + val onTalkConsumed = { + pendingTalkRoomToken = null + pendingTalkMessageId = null + } + TalkScreen( + session = currentSession, + modifier = contentModifier, + openRoomToken = pendingTalkRoomToken, + scrollToMessageId = pendingTalkMessageId, + chatsListRequest = talkChatsRequest, + pushSyncRequest = talkPushRequest, + pushRoomToken = pushTalkRoomToken, + onOpenRoomConsumed = onTalkConsumed, + onRoomOpenStateChange = { talkInRoom = it }, + onOpenCalendar = { activeTab = AppTab.Calendar }, + onUnauthorized = forceLogout, + ) + } + AppTab.Deck -> DeckScreen( + session = currentSession, + modifier = contentModifier, + openCardId = pendingDeckCardId.takeIf { it > 0 }, + onOpenCardConsumed = { pendingDeckCardId = -1 }, + onUnauthorized = forceLogout, + ) + AppTab.Tasks -> TasksScreen( + session = currentSession, + modifier = contentModifier, + createRequest = tasksCreateRequest, + openListSlug = pendingTasksListSlug, + onOpenListConsumed = { pendingTasksListSlug = null }, + onUnauthorized = forceLogout, + ) + AppTab.Support -> SupportScreen( + session = currentSession, + modifier = contentModifier, + createRequest = supportCreateRequest, + openTicketNumber = pendingSupportTicket, + onOpenTicketConsumed = { pendingSupportTicket = null }, + onUnauthorized = forceLogout, + ) + } + } + F7AppMenuSheet( + visible = menuOpen, + serverUrl = currentSession.serverUrl, + items = appMenuItemsList, + onDismiss = { menuOpen = false }, + onItemClick = { index -> + val item = appMenuItemsList.getOrNull(index) ?: return@F7AppMenuSheet + val external = item.externalUrl + if (!external.isNullOrBlank()) { + runCatching { + context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(external))) + } + menuOpen = false + } else { + appTabFromMenuIndex(index)?.let { tab -> + if (tab != activeTab) { + pushTabHistory(activeTab) + activeTab = tab + } + } + menuOpen = false + } + }, + ) + ProfileSheet( + visible = profileOpen, + session = currentSession, + onDismiss = { profileOpen = false }, + onLogout = forceLogout, + onScanBrowserQr = ::launchBrowserQrScan, + ) + NotificationsSheet( + visible = notificationsOpen, + session = currentSession, + refreshRequest = notificationsPushRequest, + onDismiss = { notificationsOpen = false }, + onUnauthorized = forceLogout, + onNotificationClick = { notification -> + openAppLink(notification.link) + }, + ) + } + } + } + } +} + +private const val PERMISSIONS_PROMPTED_KEY = "runtime_permissions_prompted_v2" +@Composable +private fun LoginScreen(onLogin: (AuthSession) -> Unit) { + val context = LocalContext.current + val scope = rememberCoroutineScope() + val keyboardController = LocalSoftwareKeyboardController.current + val focusManager = LocalFocusManager.current + val serverFocus = remember { FocusRequester() } + val usernameFocus = remember { FocusRequester() } + val passwordFocus = remember { FocusRequester() } + var serverUrl by rememberSaveable { mutableStateOf("https://forbion.f7cloud.ru") } + var username by rememberSaveable { mutableStateOf("") } + var password by rememberSaveable { mutableStateOf("") } + var trustAllCerts by rememberSaveable { mutableStateOf(false) } + var loading by rememberSaveable { mutableStateOf(false) } + var error by rememberSaveable { mutableStateOf(null) } + + val qrLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult(), + ) { result -> + if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult + val qrData = result.data?.getStringExtra(F7QrScannerActivity.RESULT_EXTRA) + ?: return@rememberLauncherForActivityResult + scope.launch { + loading = true + error = null + val loginResult = LoginFlowClient.completeQrLogin(qrData, trustAllCerts) + if (loginResult == null) { + error = if (qrData.contains("/login/v2/flow/")) { + "Для входа в браузер откройте профиль в приложении и выберите «Сканировать QR браузера»" + } else { + "Не удалось распознать QR-код" + } + loading = false + return@launch + } + val newSession = AuthSession( + serverUrl = normalizeServerUrl(loginResult.serverUrl), + username = loginResult.username, + appPassword = loginResult.appPassword, + trustAllCerts = trustAllCerts, + ) + AuthVerifier.verify(newSession) + .onSuccess { verified -> onLogin(verified) } + .onFailure { error = it.message ?: "Ошибка входа по QR" } + loading = false + } + } + + val cameraPermissionLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.RequestPermission(), + ) { granted -> + if (granted) { + qrLauncher.launch(F7QrScannerActivity.intent(context)) + } + } + + fun launchQrScan() { + if (androidx.core.content.ContextCompat.checkSelfPermission( + context, + android.Manifest.permission.CAMERA, + ) == android.content.pm.PackageManager.PERMISSION_GRANTED + ) { + qrLauncher.launch(F7QrScannerActivity.intent(context)) + } else { + cameraPermissionLauncher.launch(android.Manifest.permission.CAMERA) + } + } + + fun submitLogin() { + if (loading || serverUrl.isBlank() || username.isBlank() || password.isBlank()) { + return + } + val newSession = AuthSession( + serverUrl = normalizeServerUrl(serverUrl), + username = username.trim(), + appPassword = password, + trustAllCerts = trustAllCerts, + ) + scope.launch { + loading = true + error = null + AuthVerifier.verify(newSession) + .onSuccess { verified -> onLogin(verified) } + .onFailure { error = it.message ?: "Ошибка входа" } + loading = false + } + } + + val logoUrl = remember(serverUrl) { + "${normalizeServerUrl(serverUrl).trimEnd('/')}/themes/forbion/images/login/big-forbion.svg" + } + + Box( + modifier = Modifier + .fillMaxSize() + .f7SafeTopInsets() + .verticalScroll(rememberScrollState()) + .padding(horizontal = 16.dp, vertical = 24.dp), + contentAlignment = Alignment.TopCenter, + ) { + Column( + modifier = Modifier + .widthIn(max = 440.dp) + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + AsyncImage( + model = logoUrl, + contentDescription = "Forbion", + modifier = Modifier + .width(300.dp) + .height(70.dp) + .padding(bottom = 48.dp), + contentScale = ContentScale.Fit, + ) + Surface( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(8.dp), + color = F7Colors.Background, + ) { + Column( + modifier = Modifier.padding(24.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + Text( + "Вход", + fontSize = 18.sp, + fontWeight = FontWeight.SemiBold, + lineHeight = 20.sp, + color = F7Colors.TextPrimary, + modifier = Modifier.padding(bottom = 12.dp), + ) + Text( + "Используйте тот же пароль, что и для входа в веб-интерфейс. " + + "Если включена двухфакторная аутентификация — нужен пароль приложения.", + style = MaterialTheme.typography.bodySmall, + color = F7Colors.TextSecondary, + modifier = Modifier.padding(bottom = 8.dp), + ) + F7OutlinedField( + value = serverUrl, + onValueChange = { serverUrl = it }, + label = "Адрес сервера", + modifier = Modifier + .focusRequester(serverFocus) + .focusProperties { next = usernameFocus }, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Uri, + imeAction = ImeAction.Next, + autoCorrectEnabled = false, + ), + keyboardActions = KeyboardActions( + onNext = { usernameFocus.requestFocus() }, + ), + onEnter = { usernameFocus.requestFocus() }, + ) + F7OutlinedField( + value = username, + onValueChange = { username = it }, + label = "Имя пользователя", + modifier = Modifier + .focusRequester(usernameFocus) + .focusProperties { next = passwordFocus }, + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Text, + imeAction = ImeAction.Next, + autoCorrectEnabled = false, + ), + keyboardActions = KeyboardActions( + onNext = { passwordFocus.requestFocus() }, + ), + onEnter = { passwordFocus.requestFocus() }, + ) + F7OutlinedField( + value = password, + onValueChange = { password = it }, + label = "Пароль", + modifier = Modifier.focusRequester(passwordFocus), + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Password, + imeAction = ImeAction.Done, + autoCorrectEnabled = false, + ), + keyboardActions = KeyboardActions( + onDone = { + focusManager.clearFocus() + keyboardController?.hide() + submitLogin() + }, + onGo = { + focusManager.clearFocus() + keyboardController?.hide() + submitLogin() + }, + ), + onEnter = { + focusManager.clearFocus() + keyboardController?.hide() + submitLogin() + }, + ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + Checkbox( + checked = trustAllCerts, + onCheckedChange = { trustAllCerts = it }, + ) + Text( + text = "Доверять сертификату (dev)", + style = MaterialTheme.typography.bodySmall, + color = F7Colors.TextSecondary, + ) + } + Spacer(Modifier.height(8.dp)) + F7PrimaryButton( + text = if (loading) "…" else "Войти", + onClick = { submitLogin() }, + enabled = !loading && serverUrl.isNotBlank() && username.isNotBlank() && password.isNotBlank(), + modifier = Modifier.fillMaxWidth(), + ) + F7TextButton( + text = "Сканировать QR для входа", + onClick = { launchQrScan() }, + enabled = !loading, + modifier = Modifier.fillMaxWidth(), + ) + if (loading) { + CircularProgressIndicator(color = F7Colors.Primary) + } + if (error != null) { + Text(text = error ?: "", color = F7Colors.Error, style = MaterialTheme.typography.bodyMedium) + F7TextButton( + text = "Очистить", + onClick = { + error = null + password = "" + }, + ) + } + } + } + } + } +} diff --git a/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppSheets.kt b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppSheets.kt new file mode 100644 index 0000000..7787116 --- /dev/null +++ b/app/src/main/java/ru/forbion/f7cloud/mobile/ui/AppSheets.kt @@ -0,0 +1,259 @@ +package ru.forbion.f7cloud.mobile.ui + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.Credentials +import ru.forbion.f7cloud.core.auth.AuthSession +import ru.forbion.f7cloud.core.designsystem.F7Colors +import ru.forbion.f7cloud.core.designsystem.F7FloatingPanel +import ru.forbion.f7cloud.core.designsystem.F7NotificationRow +import ru.forbion.f7cloud.core.designsystem.F7PrimaryButton +import ru.forbion.f7cloud.core.designsystem.F7TextButton +import ru.forbion.f7cloud.core.designsystem.formatNotificationRelativeTime +import ru.forbion.f7cloud.core.network.F7Notification +import ru.forbion.f7cloud.core.network.NotificationsRepository +import ru.forbion.f7cloud.core.network.UnauthorizedException + +private fun themeHeaderAsset(serverUrl: String, fileName: String): String = + "${serverUrl.trimEnd('/')}/themes/forbion/images/header/$fileName" + +private fun resolveNotificationIcon(serverUrl: String, icon: String): String? { + if (icon.isBlank()) return null + return if (icon.startsWith("http")) icon else "${serverUrl.trimEnd('/')}$icon" +} + +@Composable +fun ProfileSheet( + visible: Boolean, + session: AuthSession, + onDismiss: () -> Unit, + onLogout: () -> Unit, + onScanBrowserQr: () -> Unit = {}, +) { + F7FloatingPanel( + visible = visible, + onDismiss = onDismiss, + ) { + Text("Профиль", style = MaterialTheme.typography.titleMedium, color = F7Colors.TextPrimary) + Text( + text = session.username, + style = MaterialTheme.typography.bodyLarge, + color = F7Colors.TextPrimary, + ) + Text( + text = session.serverUrl, + style = MaterialTheme.typography.bodySmall, + color = F7Colors.TextSecondary, + ) + session.davUserId?.let { davId -> + Text( + text = "ID: $davId", + style = MaterialTheme.typography.bodySmall, + color = F7Colors.TextSecondary, + ) + } + F7PrimaryButton( + text = "Сканировать QR браузера", + onClick = { + onDismiss() + onScanBrowserQr() + }, + modifier = Modifier.fillMaxWidth(), + ) + F7PrimaryButton( + text = "Выйти", + onClick = { + onDismiss() + onLogout() + }, + modifier = Modifier.fillMaxWidth(), + ) + F7TextButton(text = "Закрыть", onClick = onDismiss, modifier = Modifier.fillMaxWidth()) + } +} + +@Composable +fun NotificationsSheet( + visible: Boolean, + session: AuthSession, + refreshRequest: Int = 0, + onDismiss: () -> Unit, + onNotificationClick: (F7Notification) -> Unit, + onUnauthorized: () -> Unit, +) { + val scope = rememberCoroutineScope() + val repository = remember { NotificationsRepository() } + var loading by remember { mutableStateOf(true) } + var error by remember { mutableStateOf(null) } + var items by remember { mutableStateOf>(emptyList()) } + val authHeader = remember(session.username, session.appPassword) { + Credentials.basic(session.username, session.appPassword) + } + val closeIconUrl = remember(session.serverUrl) { + themeHeaderAsset(session.serverUrl, "close-modal.svg") + } + + fun loadNotifications() { + loading = true + error = null + scope.launch { + runCatching { + withContext(Dispatchers.IO) { + repository.load( + serverUrl = session.serverUrl, + username = session.username, + appPassword = session.appPassword, + trustAllCerts = session.trustAllCerts, + ) + } + } + .onSuccess { list -> + items = list + loading = false + } + .onFailure { t -> + loading = false + if (t is UnauthorizedException) { + onDismiss() + onUnauthorized() + } else { + error = t.message ?: "Не удалось загрузить уведомления" + } + } + } + } + + LaunchedEffect(visible, refreshRequest, session.serverUrl, session.username) { + if (!visible && refreshRequest == 0) return@LaunchedEffect + loadNotifications() + } + + fun dismissNotification(notification: F7Notification) { + items = items.filter { it.id != notification.id } + scope.launch { + runCatching { + withContext(Dispatchers.IO) { + repository.dismiss( + serverUrl = session.serverUrl, + username = session.username, + appPassword = session.appPassword, + notificationId = notification.id, + trustAllCerts = session.trustAllCerts, + ) + } + }.onFailure { t -> + if (t is UnauthorizedException) { + onDismiss() + onUnauthorized() + } else { + loadNotifications() + } + } + } + } + + F7FloatingPanel( + visible = visible, + onDismiss = onDismiss, + fullHeight = true, + contentPadding = PaddingValues(0.dp), + ) { + when { + loading -> { + Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .padding(32.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + CircularProgressIndicator(color = F7Colors.Primary) + } + } + !error.isNullOrBlank() -> { + Text( + error ?: "", + color = F7Colors.Error, + style = MaterialTheme.typography.bodyLarge.copy( + fontSize = MaterialTheme.typography.bodyLarge.fontSize * 2, + lineHeight = MaterialTheme.typography.bodyLarge.lineHeight * 2, + ), + modifier = Modifier.padding(16.dp), + ) + } + items.isEmpty() -> { + Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .padding(horizontal = 16.dp, vertical = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + AsyncImage( + model = themeHeaderAsset(session.serverUrl, "nof-not-icon.svg"), + contentDescription = null, + modifier = Modifier.size(120.dp), + ) + Text( + "Нет уведомлений", + style = MaterialTheme.typography.titleMedium.copy( + fontSize = MaterialTheme.typography.titleMedium.fontSize * 2, + lineHeight = MaterialTheme.typography.titleMedium.lineHeight * 2, + ), + fontWeight = androidx.compose.ui.text.font.FontWeight.Medium, + color = F7Colors.TextPrimary, + ) + } + } + else -> Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .verticalScroll(rememberScrollState()), + ) { + items.forEachIndexed { index, item -> + F7NotificationRow( + subject = item.subject, + message = item.message, + relativeTime = formatNotificationRelativeTime(item.datetime), + iconUrl = resolveNotificationIcon(session.serverUrl, item.icon), + closeIconUrl = closeIconUrl, + authHeader = authHeader, + onClick = { + onDismiss() + onNotificationClick(item) + }, + onDismiss = { dismissNotification(item) }, + showDivider = index < items.lastIndex, + ) + } + } + } + } +} diff --git a/app/src/main/res/drawable-nodpi/f7_logo_reference.png b/app/src/main/res/drawable-nodpi/f7_logo_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..74b4f6b3c4f057a53ca69c509c48572969a3de7d GIT binary patch literal 2444 zcmV;733K*|P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2_Z>DK~#8N?cIA& zRM#B`@E?o32?P^4CaDN~F@P6;) zFXx+k&)$2^xo*9EfH4Q@=x@dx!bM_E!9`+DVKqiFnM`0X7{F*W0uP;-68%NO66y7N zsH>}kl9CcjnV9W1Y}f$l>FJcL{k!HBIH5m4X<}J>#|{Yg2^%OzQ&VBtvSpO4ozx$M^G!!6O>F$D%>h0>KCo@uHcHky zy4zs?g=Y9dWBH{voVwO?@W~f%QPKu3 zk{#UK++h3m?cm|zL1zZ^^qS$#bGdzE&K^3W4O}EUtX{nul9Q7uSvykm3e;aaPf0tt zND2i61i+RpTPRsGbXUlvo_xdaFG;CP zx}K6Yagl5g5)uMAIXRT9UAbNfM{8cCq+MJj8|3EZLSSGZr2+V?=*@F~0CR6QozX5X z(ijpG6Jgb=Rg|pZ)9V_;8A{s5MH&T8t0^ifvOLKi>bj{J4pux#iE)uev1!vLh>nh? zWNqJtC&1WsjS}M`jR0poW@ctmvi5mPDV)+DqQnpvX$1NC`NPh7?C$A=J@`_#?++Wm zMH-5&g1SQ}piI=6wjSzM%X=Ht5E@Ilq{l*F46I1hd^|7n<{^P)4~;3AD9 zxC9*Mh0B7QMQm939C*3k`~!)LG)`1Be*&+ceN@_dxd5*acyPg=!Pn#Fd0B{yG!EdL zr(Gu=vb^V$0k1&o=RXUReZuI>&A3P^hjYQPMEERA2A!J@ei2^?5rN;PGsEK|sTl5P z^5UnzmHHqweePorJN0f#BjX~e6pn>nJ(B}h+dii=;@v&#SCAMn{C0*zNqw@Nl$2yy z<|A54N(%V<`%_XUeBg+CPs%c9N)kNKH@L=In=PakNtV*mQizO-XZIwRi7m`u2B z@IE=-{yaR)>=x+X|70W93P#$atMz14X|Yi@r#6? z$L04=39$zkNiuv+^v2n(l*IFN_kmw0Jf(PWJ(T8(q^5y(r}=C6>!~cu-?F67eH5no z-$u!Pd_|H7SEV$xRZ|i#{#!qUg<ee{3!#$MF?Og2whs z@Xq<|l*Ds)n*_g%FLHQXG#Foz1jCoHIJoXI%Ufvqqv(e$Q)ZosizL`TYhH%xuTD}D zZ}#K`kTT2pFUtAWCJ^4z-m83ul6ao(-jFeG8@So{Mqddok|20X+kN&iskgM1F^|~w z9?ce9Btbs9^cT4F)hSBi;XAaX$P7x($73V`zPY8z`$h>qy&k+O))n}Q6|;mX)r!)KJln|@0)BuD;?lI!rT&4qAo(fbl_Y542xzSyl+ zYxG@(uShO*sA4CycNr*&cUQ!HF!R>$P;xCUl8fLsN@RZ5_7<;T_;KIZNEE)cxyat~ z$1UHtm1Sj27WjGuP;x!KBDuh+D~BzsL1YOFm;(!@ucRaf7s<)+Ds-^oDN1sr&B=Dj zYmm`MT_7137YAu+X_Um+xN+mKpILVnoO_Mi&&V=&>JMQ3eDUw|cr#Kb!iSFqNAH0q zNnZxQ<<;5AZ#!k`tWui0wYky>{kzgigce1lODPfJA~^|OjXtb;fs%MQ>v3t+dP?GP zk(>nArpf%+&7I-*LXgjNO5$;moB%($CG%>8uRxYayc!`ck`r9~@;_3S70sWXYFQN` z6Bo$|j@7>Id9cB*YX3$3O`O5(+ZE~O)N;3Co6L+~hHDw2VVWCxSk2$x&SD2W#xyoip}gNtMbT*Ghf?WQCiep6O$ zxJY)8xpEfG47!7k)Psv;hbz}B=tw;Lile`05GD2CBH2MNu}EWm$x#+Al0rD8w%Pav zCGqeRSZc&YQs|ng(NZQ^ruatCk-Bh^6f$%)(2*RICC`K$2^UGBHd8Yl$suw*zY<&| zg*wbeI+DZ7iJPoD6BkLL&ThFy@^%-y-A*R9ztbnas z<$XQT9%rt800%CXP!bP!8}U-%IH|u#2+L$J7%U|kbegd-0Q?{7^Z&HeR8-&q0000< KMNUMnLSTZ(_McAx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/f7_app_lock_logo.png b/app/src/main/res/drawable/f7_app_lock_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d36ef8fd4cc8d0c1cd62bd314fb8017cde4d1522 GIT binary patch literal 3336 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 STLvKj0000 + + + diff --git a/app/src/main/res/drawable/ic_call_decline.xml b/app/src/main/res/drawable/ic_call_decline.xml new file mode 100644 index 0000000..81f57cb --- /dev/null +++ b/app/src/main/res/drawable/ic_call_decline.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..be43858 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..be43858 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4a468d0d0a73c3a25d115ea2f063abef9bb9c11c GIT binary patch literal 776 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 Z>kqLdBA=EUnx+5%002ovPDHLkV1j;2(%k?6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..265e8bcacb2e73b8e3dbea143a7e71b760cc62c5 GIT binary patch literal 1160 zcmeAS@N?(olHy`uVBq!ia0vp^IUvlz1|<8_!p|}=u=snrIEGZ*dOPQ>cW|K0@xSUd zEb%{_;xkrWVd8YGS?K8560zXFLxTP(mz4{`!UU3jTspxa?0Tg|<-k;$7{R-*t35@#pP-z4!UK_vtnF`+wiG{66RY&$+Iyj6gea0)-q24oQyY z4HsH=-pxzf8Wrj8&VJo+_Su}m!oX7>#FdR}YgT1E+kbwgzK;M)SX9)hMT-~j^mTG# zDz=(?X?;yyZqL+G*%a|zmqdDtFR$CTVd+xUcdakKR(Vdl|33NZdM?rFtckmQ($b#w zm3zE*nX9!)A!qu=2%Skf^Y5S5sxB2cwtB;(M~`F|d#_z7aHwqJlP4+93M^D2C)>9% z^S@TVLKy5VdU&oywZ{-^0<7@pIMQ{o$>3*K+nQ+NHzs+dC;axmo(> z+iE?z6vrF!L7|~rbG1q~&aOSK&=a1xa^=c1dE31Y{n}?*pv-;fpFs0Lg_BWbej7Kf zE8&0z9&6`mF>m~)d)`>Jt##^@DH)GEQWBQU z)mfeSMCdcSoxrx^5n{VeY< z^={3KOzrQh+%vmou7&#|gYD^aW9z25PEwtA=*T3Aa$P2o#GgNZ9$Z?nqi|s*awX-?fWh>rQ%1`}*PS&j)cpe@-}Z#N}p+uJ!(jt0l|h=5gtS&H3|Pb(N}) zrlzM@3{H)a0|A1OT+m>v6fMXy`X)|RD9mYn!>FYE6Db^li8&AGQ;{t5Mth>DUD zf4{cs^Ueho9KZdIjEqhMKMYOgTRZ9E>g3hZ3v+e9tu>hI=RS)|TIcDLi>7JSYxkZO z$l^SG>XedCE8C_uyO$X&`nLX#izq8AyK(5ri_ZnQmRl_AK556M#V2;9o#EWatmwm-c<7f*Wr?laUQx^cmk;jVF#WP` zO5)`*?G{Z%pF0ok)fG0Wc;}y)`qkR;hP^=a*%gadS3WUn(Ny)Z*|wak+Vn0{q8F!h z?7QiSoByyKnj&<~{;G$V+BzdeAH~GE^RrJJy0$$`(ML0Jt^B<(AM;oe*;S`FrnP zv1@iwuHw&b_vj=(;uV^F@<>*8wzFS!bacRvxT7|iDgO7bPD~OGOZn>;h%*a=Bosb! X8)en0RJ-pK1aUoG{an^LB{Ts5rUwyn literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..8de2d063c8cdddbb903d8ab2bd3f5fd369d402bf GIT binary patch literal 1143 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..844964e3294e0b5909c4e750a7fb29750d05e3da GIT binary patch literal 2075 zcmaKtc~H`e7RR{=N|eb}+{zFw_iU52+`lH8nDK#d0lE+$a+-aNSc2 zcg*tM+|UyBmwU#2V2kAyBfXZIb?r{`=FPl$?~ilN%=diHnK?6O=9B5@a8ee&0}cX# zWbw8qh?_O{d%&bO^IIEH8weyL!k@5miJo3yte$ouBl|XVFhLlJvcf4noK@CvS#{{) z>LW5Eb-8 zKqEju1PJ&a#}DhK~!NGw@pwzB|ZLznSnFN&2jx`sOinjfeRfqI}U~7g$zS z_MIJ*aMzgDBl`0%! zu|LH7eBZIl%E}7xrq2$K;kJ;k%{ZW7W#P3R%~>_~?lGnlxLQ+R{i2VfVav;I4HvfH za5(%zT!DDRe~tfuZ}^&ug{O6P9y@GeV%Bu^T#0`BKGV{mx>ryN1U4+BcrdfDiTo<@S0S z8o$5mxEILGd-5@U#v29eR@-SD!mO{~mu`HEAP1DPO)wgAkaL0v{`N6f}; z((gkX`2t5LFI@x<)jV!L0K*(x(>X<{5?PP?&eI3#Mok35f~T_7nG#yHrQHPw zJB2``)L+%IJ_(`gzN-F6}R|^%*Ot>(^{Oh&}n_^5lYR^T*KVLf)T|i z{4MA%t6c`#v>u6`&3bx+Ke1ToSE&lN(CX;uDEU}Y$hMwy5p%vFf)00%QGEq<9_jpf$Nck?7q;;te36i1 z>z-8kjCf7KdHCtIzt$=*wA`c_4A)^bG&KHX7`Ps<3~Ft(j7iiL*cv90pCl`dYFE@XGxJ>GBQxLk)mR2FK4l=Y#Ut9pt?i0cZEbGjw~+MEES7{CuX*5aQ7iqKdPz zA==oa{dv&H=-Wb)B-MDi$gxc5=Sqcp}Fmt$<(A1~H9aIN#t_ zsgbJ$E#@R~IuFuyZuB<-W90~2jb}!)O|8+pXGxT=l-BzNGh1L78F7w^JK2W~umhS@ z!GR=ngg*ahycRjBdh(Gaf(KQ*zr}a(s>7wplVWK|ahH7QQntmp)qSqf2-{!5nI&p` zq5WuHwZ#=F@Zhylj*=_2`%34_Fk@;O_A=9tnYF5TD)=IAMvB^`KgG@Fon_%5nU7?@Qef&z;Tr^V=8! z@MX=>dY?3=`R#qXrAM00zEUWuTSwF#`#%0H=nRgEnP;}-4ACv___Z;k?o|4n>B`AD zS6N-Ho;$Cqs*3X+me0R(KaN{O@9uFvQBv^S`o>1)1$A$WyLYo%)aQ~2)z-ZQ!86xq zgPldT^EgbNdAZRVSwo6)zTIcQ=8|L()&ax_cYg4e%uS_IrDbI;+@ok`nG>rB8NQ+`f&((-+Z)0>-hHn^QfP#O&mRxVL_{sv6`K?x*BI;}?Y z@we;wdSO+gmaoXXDyEX7qZ8uC!sLn}v=*Gk4x-EybV8y}chSdiH@`)Xn~UoT`5AR= z494YwA8NId!aT+%O~3p$ZIS|{R89!RT6;oDrEN1q*dY2V@%rMtsTDY)LMm4@eOV6M zBP5O>T8IOuB6Su`d)*=?q_0M-WD$u((J5JcMC-$C>8tS z*uAI?>5RQ1=t4^=W{hHQiABC>JYoC9%K|XWD0C9G-XlZ%_AcHVK8%`_FI*i{3GExL zavCl8olLwC#aGJqQcTasEtbXbCQtWfE1+Jzy6ysjs68I;Y*84b;0Vm_;hyhyLlW^?P1YsmP{qx4p z1V_05Qij{3Q=XPX97ovkG76=9hS2iWeF~ft^(W*N+8k_T4a5{uS%$;VZSPFgZ7>vMmnUAFo2yv^c*nkTXb+Tk7?64GBgSiB|d*m$OQ zx@H)s<4Yv*ikiLTk^sUqP!OUMFs2c5?XSHe#E4d5(6%rIpL5fG9*kR?Ic1V`U~>&4 zv*fqQW!qv!D1wPPbM~xTa6v!5Q)qqBriU_6CJ^9rQ! z^%gWgQrlR3*M$^|6VvmXhtQ64^5%7X0<4*%cwiGaJ?&5pJ1AeBNndH z2BTe1?by#BEmjz^D#t^}`naGe1NE`$3Ngf0;{Dx9XPm4D_hAX77;?Y`fk3GFQ51Vf zq@^e1Qu%=1obqEO-N_F!X_{M;hA-)iVBln~6%Kl?#yj ze%IP{B_23LF5P3*xDhDh^3cFYW7CjgVLgKVxr8ZNi=MDmG?xTdSv}xsN>+Eb#r)jd z-2KST5B1q;f-C8K0zM#-I4&RqH6MMJI>F6NT>5#u&0(P0I)hORZ8&zHq$>rO%IgBe zOXE}0K%utn$y29P)QQt^XEa}?|2O`8-EoLxR+t|!)&~vUThESW5SyQs7cK=^=9O}JGncCc z{Wgc$cqO4+-B@mUa>0JaV(X&wlO^)(g)+4GP=40oVujA4O6*OmDCAIMj@z?o!#0g_ zdtlS=8Ia`O0-UrgylC`s;D$q~=x!C3jz5Jj&nIDr`xn$s4%mCGC|O8dT0WLQ z6x^*H1}C(JD$~r9$oUGLW0cRa1T_Gn*}F}7f$?Wx9?ixEdTTFRaYKkjA*{`c$aBJbWz<$gMc2;}{}u&{FFoecZfGIPCGWu<7V3@g4qnM!Qm%Wn{` zH;v%LcoOB6LtSh-7B^ziSpA>y3ApszGXP4y__*cUgGtp6x=;TnwPDB6c}kYd*Jd0S zVvv#XQBh#G*bIM~jYw;0RL=>&JonSeC2t0@@nw5ocBXlDNRRjPQ5kNTVwlvAtK;s* zY=GoLdR)8H}^_3>$y2 z4(sMhd7#tnI*Q2qRm0q`3{u!PG86(RAiU8mRaj1i_%lxUTI6khe*PK=z}h}fP6i@Y z+N(Z>J;6@ryzc1vU3;~?#i2F}78rA8NCyBe97G+jzM>unLVE!}Q=8Oc#+ zOTIh!fCI6&QBqjW;Scen)TkP6r>63joGNQK>8Z5T2+ErJIewYk@VlO9I{jcKb4dGj znJ(F%*nTnX25_UBl_;Yc3`Q%_oXJ0t2L2rB$P2@~3B{E5!+99zph4LYC>4!Q9Zdyo z31E71iPdS75|>2^dZQBJJ>mBjoS@fx6RI~Si_JHRSGq(Ct6-V|8KF(^!@6(-{%y82 zKKWtxq{Y=>!yZ*nFuph@Z_SU6~vUl@2b9h|!I*O~z7Oezn z%A+T?*Djku)gE#)p05LawSU?Qxa!4!lN{>yrQhjZ0<2js!c_061BE!~lhY0wYYHf2 z=I`DBh5hG;aKl|lZS7vSbKe>N+20M9`ne>(;p`4A1=h;2=^_a-TXZ#IhxE~3B=D7r zU5?q5Pt)742>VIO40y($@#N8y5g>=Vcf|d^{rhyi8p^UV*j-Zplz1EeYAz|bv_**4 z_O;Ucc2yfVA-=x^iVgmeyp?ZE>(E!r0??b;e-AKOldSPhQ`X@#Cw;G=_5rMozAO;L0JKp zHmk@yh5-LHS=Bh$=Vs0|SzF2GL4|+X)`ZSf>!=W!q*DknQSOm5v>;*3oS(sUgNYnQmu)~C( zjlmjW0U*J_oH|&`L9|KuYBoStbOJXT3H1)2dyV@Go%WFgr4BXW=(Sr}&rq`ugGXZ84TZF$_=MC_uOSJA!tE71)AC-V*Bjz7-s_3O@KALt1?aY!Jtj+bf* zgW8=%5x?%A;Nc0o#eKDPj5Jq`4WaZdG@GN_)rL@0&WoyV*GzZ&_aU+R+HCGirvRju zR`*FX6N%(9C)!blhuoDa6eK*omd;dHxECsE6+^rxg5IkB7WXLw$W(W0oTg_tC~9ZE zqQA@Ehog=v&}l(lrbVx%oqxcp1s6rLOg~a*Tkb=-0|42V&an0S^>cbwF)uIgym@p1 zcu_uEa@4P#X%p2vT!>{jGQSM9cpJA2XcKeT<(7mh!~xXNOBeCGnPF5Dpp^dWyUGke zY@9o$9tXZHq37)1Ptxz8x?TXJ_;yc{Z zTnVWnioW=T=yCFNwgl3kF0g|Y?p%BC=}Vm_@5jzBKt^zHginyEil^S2Lt@YT8&_+0 zdFdaXdGE*Z+OOCpk%MT$N3MBT+SoMxg3z==&ivc@cLf>|_-lDAa@|zdz4?>y^Qsb2 z09P$QyN@QK=tVgHQ8i0z>qa$X|8k@E<4%AD%>J^brXArzo>vg3AG8AXtoINAvgZW+ zNO=cJ($dxzztVdf|8*`rOLFv5UVNE+kNal}8Fzd>w)XDs2~RWYH5+8}t&e$9UKTuDcQ^R{13Rfc;`WTr@-w{l^+CaX4H} ztKLv9&yFK=W7BlXzwUzP6Yj)b>R_w}r>SNW7?7;}i-_5SDk=b^t^ZWJTX1l2&51G_ z9KfpkCe?#_sOI|*S!i4;W2{K@p4Pp^{X%WgO;dKp*6gkjY{QqwqygGN;jrtNA3i!d z(q+5r{js!7HCod1?-tsKdYPX-zIQU2jg(FRU()!*dFIR+r+PY@Zfw2etwnq+#Q^N4 z7t?Ue{&OV7RRo}sU4G4?k>3vMM*pe>G==k;glUJx-~*FflL`7?`ib$L)Jo^#e=lXf z*>b@e2oxS{oq5?>tsZpq=FK((WUC$1-=StnhfzRU>-uljQVaHG9hYZl>9pbZS*5() zVsOKb*9)Tox$EDdH-z=&^;A}up@(h#=!s(EgmS%T)XZt!n4N~9krDW^$^#!f!LI-_cT-K*Zch|I|iLFn}hrnb2VxAIPZH<9P5%&TPw zzI+)jbvHGg3CP|~+c)**Y=#nnvM{m1Z+&SifVT)}x2j8uS!JE+Mb2 zmC@*L#8kPP^7@J^7)PvuBbyY&&HZzcS}k31+0NkFT20G)9MjP`&1@pO=|AC!ZyEp` z@pmC!QSC#2J{4#ht4W350whGiX(%A7fr!FZOGP_dfFZ>9ORAK0v{onW#|#+NAV;-R zxpOeOV6Cg6AmeTU8MmXaACdS}&<5Ay`)hdlM(eQIeu=Wq+$bAYIqEKjhPR+_x>M1M z)l)2&n8+;p!tF#mVU;nz$vo;_zUaZClEyHNzWHPerbZZsLFQ#Fujl%J3v%Tqc!_!k zLS<`h(pY2$1khMYmu-D?*NE5}Uk8ya-ud}jF1Nony;BQBRqDwMK5r2kMVLF)Gk zFl0z1WBv0fK-l@a+y|}uVC~(BN#x$ecX(%!u833vF@i0pj(63;#Hy}j81G;K4A^RP zv_9<66a56<+$1r{Br#4vwp)PU=-TOL%*lw#qXV}FC65IAWs=@G{fX6Be(%GL@KM9> zfz{AAb7ILy^ZWYgi6S|dPG4t>4We17`qo18Cojy0_mvVIA;X z3K_E#-a_p%Hjg=G@~j>3r@@edOK-^b&KvBQ_c%B>}N*eaOdNba_r8mdT0XN@f7SysMos6XZxuMDREXyzwSj59#4ez3_Vw%++XInSP)aMW$f7i>sf@yo7x z)(AJ=S`^3UWBq~ot8hrw|E_MH9?-h~IEf~N3)`OonsVyC-hm$anm900(X-Qa0VfvS zFl-d9Ju40r)jvb{Y=HxlsjNgn(&wnBF!`eXFLhxtp#8r`U!YZzfEfy)QNlokRsxAB z*Oa#Vxp96bg&*8tTQCv!$6%oOaH=+5yL&{@@YVwLDQ_iBJoVbGg8|=HJ|lmBtlAxv zpy{(Z10>-K3&{UTlj1)az*$#?`j5opdLB{1FuIo4;+lL>jr0og=YB;@^szeEBG?5L z5Cb||KbgBe>l)&D2*4;QWE-!?eb%EBz0RvAzRNDg{|X!6wErQWVUtL{{wG20KpTtp zGmp3Sy8-Q0!{_m{C5@!YRWu>;|4p_dD;Eof6BtHAKkgJxG#YG-9)xgBo>P^e=g#Y? zm>E^N#i^>c`apf8Zuf@ZpM&|nk1qVc?UU@)AB}B^nbCr@?*z7rApC*Re}uI059LnnxE`%XEU!%+4Zqdn|09 zwcU4hl_&}D!!tkmgYv_4Y7l)jUjqHzRq2M=Tgn*F;3uOYsBoKF4HldG{{0P03yT+N zhI>w;usQKHV3dEqGa+gjwmE3-)nA}FOMV{9S2l2iyKh2@Jz_m){u~ecAh;?R0Tw#& zqC~Q(smUrJ0NpZ{oR*d=ay7iWHEeMvp3mUt7^6p~#KOrb51=}ER0L%oy-?uWqtc&o zr^Sx{WxHGI>p&c=NZH~=@50HAho8WEyp=*v6%Xv+SPvr=7uKRt%BVSiz1YGZ=AaWC%w0hneJK>z>% literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..e66719029cc2454d2099d61ac1a21663ca12f80a GIT binary patch literal 3295 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 DAh(p= literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..270fbc9 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #FFFFFFFF + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..2b953ab --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + + F7cloud Mobile + Конференции + Открыть F7cloud Talk + + Сканирование QR-кода + Закрыть + Наведите камеру на QR-код + Держите QR-код целиком в рамке + Распознавание… (%1$d из %2$d) + Готово + Вспышка + Выкл. + diff --git a/app/src/main/res/xml/shortcuts.xml b/app/src/main/res/xml/shortcuts.xml new file mode 100644 index 0000000..c21873c --- /dev/null +++ b/app/src/main/res/xml/shortcuts.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..49843c1 --- /dev/null +++ b/build.gradle @@ -0,0 +1,13 @@ +plugins { + id 'com.android.application' version '8.13.2' apply false + id 'com.android.library' version '8.13.2' apply false + id 'org.jetbrains.kotlin.android' version '2.3.0' apply false + id 'org.jetbrains.kotlin.plugin.compose' version '2.3.0' apply false + id 'org.jetbrains.kotlin.kapt' version '2.3.0' apply false + id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.0' apply false + id 'org.jetbrains.kotlin.plugin.parcelize' version '2.3.0' apply false + id 'com.google.devtools.ksp' version '2.3.4' apply false + id 'com.google.gms.google-services' version '4.4.2' apply false +} + +ext.kotlinVersion = '2.3.0' diff --git a/core/auth/build.gradle b/core/auth/build.gradle new file mode 100644 index 0000000..98f382d --- /dev/null +++ b/core/auth/build.gradle @@ -0,0 +1,25 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'ru.forbion.f7cloud.core.auth' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + implementation project(':core:network') + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1' +} diff --git a/core/auth/src/main/AndroidManifest.xml b/core/auth/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/core/auth/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AppLockStore.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AppLockStore.kt new file mode 100644 index 0000000..61c2248 --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AppLockStore.kt @@ -0,0 +1,102 @@ +package ru.forbion.f7cloud.core.auth + +import android.content.Context +import java.security.MessageDigest + +class AppLockStore(context: Context) { + private val prefs = context.applicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE) + + fun isEnabled(): Boolean = prefs.getBoolean(KEY_ENABLED, false) + + fun useBiometric(): Boolean = prefs.getBoolean(KEY_BIOMETRIC, false) + + fun shouldOfferSetup(): Boolean = + !prefs.getBoolean(KEY_SETUP_OFFERED, false) && !isEnabled() + + fun markSetupOffered() { + prefs.edit().putBoolean(KEY_SETUP_OFFERED, true).apply() + } + + fun markBackgrounded(at: Long = System.currentTimeMillis()) { + prefs.edit().putLong(KEY_BACKGROUND_AT, at).apply() + } + + fun clearBackgroundMarker() { + prefs.edit().remove(KEY_BACKGROUND_AT).apply() + } + + /** Lock after the app stayed in background (process still alive) for at least [lockDelayMs]. */ + fun shouldRequireUnlock( + now: Long = System.currentTimeMillis(), + lockDelayMs: Long = DEFAULT_LOCK_DELAY_MS, + ): Boolean { + if (!isEnabled()) return false + val backgroundAt = prefs.getLong(KEY_BACKGROUND_AT, 0L) + if (backgroundAt <= 0L) return false + return now - backgroundAt >= lockDelayMs + } + + /** + * True once per process start (app was killed / fully closed and opened again). + * Always requires lock even if background timeout has not elapsed. + */ + fun consumeColdStart(): Boolean { + if (!coldStartPending) return false + coldStartPending = false + return isEnabled() + } + + fun enable(pin: String, biometric: Boolean) { + prefs.edit() + .putBoolean(KEY_ENABLED, true) + .putString(KEY_PIN_HASH, hashPin(pin)) + .putBoolean(KEY_BIOMETRIC, biometric) + .putBoolean(KEY_BIOMETRIC_ONLY, false) + .apply() + } + + fun enableBiometricOnly() { + prefs.edit() + .putBoolean(KEY_ENABLED, true) + .putBoolean(KEY_BIOMETRIC, true) + .putBoolean(KEY_BIOMETRIC_ONLY, true) + .remove(KEY_PIN_HASH) + .apply() + } + + fun isBiometricOnly(): Boolean = prefs.getBoolean(KEY_BIOMETRIC_ONLY, false) + + fun disable() { + prefs.edit() + .putBoolean(KEY_ENABLED, false) + .remove(KEY_PIN_HASH) + .putBoolean(KEY_BIOMETRIC, false) + .putBoolean(KEY_BIOMETRIC_ONLY, false) + .apply() + } + + fun verifyPin(pin: String): Boolean { + val stored = prefs.getString(KEY_PIN_HASH, null) ?: return false + return stored == hashPin(pin) + } + + private fun hashPin(pin: String): String { + val digest = MessageDigest.getInstance("SHA-256") + val bytes = digest.digest(pin.toByteArray(Charsets.UTF_8)) + return bytes.joinToString("") { "%02x".format(it) } + } + + companion object { + private const val PREFS = "f7_app_lock" + const val DEFAULT_LOCK_DELAY_MS = 60_000L + private const val KEY_ENABLED = "enabled" + private const val KEY_BACKGROUND_AT = "background_at" + private const val KEY_BIOMETRIC = "biometric" + private const val KEY_BIOMETRIC_ONLY = "biometric_only" + private const val KEY_PIN_HASH = "pin_hash" + private const val KEY_SETUP_OFFERED = "setup_offered" + + @Volatile + private var coldStartPending = true + } +} diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthErrors.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthErrors.kt new file mode 100644 index 0000000..49fdd4c --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthErrors.kt @@ -0,0 +1,55 @@ +package ru.forbion.f7cloud.core.auth + +import java.net.ConnectException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import java.security.cert.CertPathValidatorException +import javax.net.ssl.SSLException +import javax.net.ssl.SSLHandshakeException +import javax.net.ssl.SSLPeerUnverifiedException + +fun Throwable.toLoginErrorMessage(): String { + val msg = message.orEmpty() + if (this is SSLPeerUnverifiedException || + this is SSLHandshakeException || + this is CertPathValidatorException || + this is SSLException || + msg.contains("not verified", ignoreCase = true) || + msg.contains("CertificateException", ignoreCase = true) || + msg.contains("Trust anchor", ignoreCase = true) + ) { + return "Ошибка HTTPS: сертификат не совпадает с адресом сервера. " + + "Проверьте URL (https://ваш-домен). " + + "Для внутреннего dev-сервера без Let's Encrypt включите «Доверять сертификату»." + } + if (this is UnknownHostException) { + return "Сервер не найден. Проверьте адрес (например https://forbion.f7cloud.ru)." + } + if (this is ConnectException) { + return "Не удалось подключиться к серверу. Проверьте интернет и адрес." + } + if (this is SocketTimeoutException) { + return "Сервер не отвечает (таймаут)." + } + if (msg.contains("401", ignoreCase = true) || + msg.contains("Unauthorised", ignoreCase = true) || + msg.contains("997", ignoreCase = true) + ) { + return "Неверный логин или пароль. " + + "Проверьте учётные данные. При включённой 2FA нужен пароль приложения из настроек безопасности." + } + if (msg.startsWith("Auth failed:")) { + return msg.removePrefix("Auth failed: ").ifBlank { "Ошибка авторизации" } + } + return msg.ifBlank { "Ошибка входа" } +} + +fun normalizeServerUrl(raw: String): String { + val trimmed = raw.trim().trimEnd('/') + if (trimmed.isEmpty()) return trimmed + return when { + trimmed.startsWith("http://", ignoreCase = true) -> trimmed + trimmed.startsWith("https://", ignoreCase = true) -> trimmed + else -> "https://$trimmed" + } +} diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthSession.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthSession.kt new file mode 100644 index 0000000..554cddc --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthSession.kt @@ -0,0 +1,12 @@ +package ru.forbion.f7cloud.core.auth + +data class AuthSession( + val serverUrl: String, + val username: String, + /** Пароль учётной записи или пароль приложения (при 2FA). */ + val appPassword: String, + /** ID для WebDAV (`/remote.php/dav/files/{id}/`), из OCS cloud/user. */ + val davUserId: String? = null, + /** Только для тестовых серверов с самоподписанным сертификатом. */ + val trustAllCerts: Boolean = false, +) diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthStore.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthStore.kt new file mode 100644 index 0000000..b50661e --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthStore.kt @@ -0,0 +1,34 @@ +package ru.forbion.f7cloud.core.auth + +import android.content.Context + +class AuthStore(context: Context) { + private val prefs = context.getSharedPreferences("f7_auth", Context.MODE_PRIVATE) + + fun save(session: AuthSession) { + prefs.edit() + .putString("server_url", session.serverUrl.trimEnd('/')) + .putString("username", session.username.trim()) + .putString("app_password", session.appPassword) + .putBoolean("trust_all_certs", session.trustAllCerts) + .putString("dav_user_id", session.davUserId) + .apply() + } + + fun load(): AuthSession? { + val serverUrl = prefs.getString("server_url", null) ?: return null + val username = prefs.getString("username", null) ?: return null + val appPassword = prefs.getString("app_password", null) ?: return null + return AuthSession( + serverUrl = serverUrl, + username = username, + appPassword = appPassword, + trustAllCerts = prefs.getBoolean("trust_all_certs", false), + davUserId = prefs.getString("dav_user_id", null), + ) + } + + fun clear() { + prefs.edit().clear().apply() + } +} diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthVerifier.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthVerifier.kt new file mode 100644 index 0000000..9d70b84 --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/AuthVerifier.kt @@ -0,0 +1,47 @@ +package ru.forbion.f7cloud.core.auth + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import okhttp3.Request +import ru.forbion.f7cloud.core.network.NetworkFactory +import ru.forbion.f7cloud.core.network.applyOcsJson +import ru.forbion.f7cloud.core.network.isOcsSuccess +import ru.forbion.f7cloud.core.network.ocsData +import ru.forbion.f7cloud.core.network.ocsMeta +import ru.forbion.f7cloud.core.network.parseJsonObject + +object AuthVerifier { + suspend fun verify(session: AuthSession): Result { + return runCatching { + withContext(Dispatchers.IO) { + val client = NetworkFactory.newAuthedClient( + session.username, + session.appPassword, + session.trustAllCerts, + ) + val request = Request.Builder() + .url("${session.serverUrl.trimEnd('/')}/ocs/v2.php/cloud/user?format=json") + .applyOcsJson() + .build() + client.newCall(request).execute().use { response -> + if (!response.isSuccessful || response.body == null) { + error("Auth failed: HTTP ${response.code}") + } + val root = parseJsonObject(response.body!!.string(), "профиль пользователя") + val meta = root.ocsMeta() + if (!isOcsSuccess(meta)) { + val message = meta?.optString("message").orEmpty() + error("Auth failed: ${message.ifBlank { "HTTP ${response.code}" }}") + } + val userId = root.ocsData()?.optString("id").orEmpty().trim() + session.copy( + davUserId = userId.ifBlank { session.username }, + ) + } + } + }.fold( + onSuccess = { Result.success(it) }, + onFailure = { Result.failure(Exception(it.toLoginErrorMessage(), it)) }, + ) + } +} diff --git a/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/OcsUserResolver.kt b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/OcsUserResolver.kt new file mode 100644 index 0000000..61401bf --- /dev/null +++ b/core/auth/src/main/java/ru/forbion/f7cloud/core/auth/OcsUserResolver.kt @@ -0,0 +1,40 @@ +package ru.forbion.f7cloud.core.auth + +import okhttp3.Request +import ru.forbion.f7cloud.core.network.NetworkFactory +import ru.forbion.f7cloud.core.network.UnauthorizedException +import ru.forbion.f7cloud.core.network.applyOcsJson +import ru.forbion.f7cloud.core.network.isOcsSuccess +import ru.forbion.f7cloud.core.network.ocsData +import ru.forbion.f7cloud.core.network.ocsMeta +import ru.forbion.f7cloud.core.network.parseJsonObject + +object OcsUserResolver { + fun resolveDavUserId(session: AuthSession): String { + session.davUserId?.let { return it } + val client = NetworkFactory.newAuthedClient( + session.username, + session.appPassword, + session.trustAllCerts, + ) + val request = Request.Builder() + .url("${session.serverUrl.trimEnd('/')}/ocs/v2.php/cloud/user?format=json") + .applyOcsJson() + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) { + throw UnauthorizedException() + } + if (!response.isSuccessful || response.body == null) { + error("User profile HTTP ${response.code}") + } + val root = parseJsonObject(response.body!!.string(), "профиль пользователя") + val meta = root.ocsMeta() + if (!isOcsSuccess(meta)) { + error("User profile OCS error") + } + val id = root.ocsData()?.optString("id").orEmpty().trim() + return id.ifBlank { session.username } + } + } +} diff --git a/core/data/build.gradle b/core/data/build.gradle new file mode 100644 index 0000000..4572494 --- /dev/null +++ b/core/data/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'ru.forbion.f7cloud.core.data' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + implementation project(':core:auth') + implementation project(':core:database') + implementation project(':core:network') +} diff --git a/core/data/src/main/AndroidManifest.xml b/core/data/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/core/data/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core/database/build.gradle b/core/database/build.gradle new file mode 100644 index 0000000..8402d40 --- /dev/null +++ b/core/database/build.gradle @@ -0,0 +1,27 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'com.google.devtools.ksp' +} + +android { + namespace 'ru.forbion.f7cloud.core.database' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + api 'androidx.room:room-runtime:2.7.2' + implementation 'androidx.room:room-ktx:2.7.2' + ksp 'androidx.room:room-compiler:2.7.2' +} diff --git a/core/database/src/main/AndroidManifest.xml b/core/database/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/core/database/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactEntity.kt b/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactEntity.kt new file mode 100644 index 0000000..8972750 --- /dev/null +++ b/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactEntity.kt @@ -0,0 +1,27 @@ +package ru.forbion.f7cloud.core.database + +import androidx.room.Entity +import androidx.room.Index + +@Entity( + tableName = "contacts", + primaryKeys = ["accountKey", "uid"], + indices = [Index("accountKey")], +) +data class ContactEntity( + val accountKey: String, + val uid: String, + val displayName: String, + val email: String, + val phone: String, + val bookName: String, + val photoBase64: String = "", + val photoMimeType: String = "", + val organization: String = "", + val title: String = "", + val address: String = "", + val website: String = "", + val birthday: String = "", + val emails: String = "", + val phones: String = "", +) diff --git a/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactsDao.kt b/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactsDao.kt new file mode 100644 index 0000000..2f4d44c --- /dev/null +++ b/core/database/src/main/java/ru/forbion/f7cloud/core/database/ContactsDao.kt @@ -0,0 +1,46 @@ +package ru.forbion.f7cloud.core.database + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Transaction +import kotlinx.coroutines.flow.Flow + +@Dao +interface ContactsDao { + @Query( + """ + SELECT * FROM contacts + WHERE accountKey = :accountKey + ORDER BY displayName COLLATE NOCASE + """, + ) + fun observeAll(accountKey: String): Flow> + + @Query( + """ + SELECT * FROM contacts + WHERE accountKey = :accountKey + ORDER BY displayName COLLATE NOCASE + """, + ) + suspend fun getAll(accountKey: String): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(contacts: List) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(contact: ContactEntity) + + @Query("DELETE FROM contacts WHERE accountKey = :accountKey") + suspend fun deleteAll(accountKey: String) + + @Transaction + suspend fun replaceAll(accountKey: String, contacts: List) { + deleteAll(accountKey) + if (contacts.isNotEmpty()) { + insertAll(contacts) + } + } +} diff --git a/core/database/src/main/java/ru/forbion/f7cloud/core/database/F7Database.kt b/core/database/src/main/java/ru/forbion/f7cloud/core/database/F7Database.kt new file mode 100644 index 0000000..11f21fe --- /dev/null +++ b/core/database/src/main/java/ru/forbion/f7cloud/core/database/F7Database.kt @@ -0,0 +1,80 @@ +package ru.forbion.f7cloud.core.database + +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 + +@Database( + entities = [FileEntity::class, ContactEntity::class], + version = 4, + exportSchema = false, +) +abstract class F7Database : RoomDatabase() { + abstract fun filesDao(): FilesDao + abstract fun contactsDao(): ContactsDao + + companion object { + @Volatile + private var INSTANCE: F7Database? = null + + private val MIGRATION_1_2 = object : Migration(1, 2) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( + """ + CREATE TABLE IF NOT EXISTS contacts ( + accountKey TEXT NOT NULL, + uid TEXT NOT NULL, + displayName TEXT NOT NULL, + email TEXT NOT NULL, + phone TEXT NOT NULL, + bookName TEXT NOT NULL, + PRIMARY KEY(accountKey, uid) + ) + """.trimIndent(), + ) + db.execSQL( + "CREATE INDEX IF NOT EXISTS index_contacts_accountKey ON contacts(accountKey)", + ) + } + } + + private val MIGRATION_2_3 = object : Migration(2, 3) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL( + "ALTER TABLE contacts ADD COLUMN photoBase64 TEXT NOT NULL DEFAULT ''", + ) + db.execSQL( + "ALTER TABLE contacts ADD COLUMN photoMimeType TEXT NOT NULL DEFAULT ''", + ) + } + } + + private val MIGRATION_3_4 = object : Migration(3, 4) { + override fun migrate(db: SupportSQLiteDatabase) { + db.execSQL("ALTER TABLE contacts ADD COLUMN organization TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN title TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN address TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN website TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN birthday TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN emails TEXT NOT NULL DEFAULT ''") + db.execSQL("ALTER TABLE contacts ADD COLUMN phones TEXT NOT NULL DEFAULT ''") + } + } + + fun get(context: Context): F7Database { + return INSTANCE ?: synchronized(this) { + INSTANCE ?: Room.databaseBuilder( + context.applicationContext, + F7Database::class.java, + "f7cloud-mobile.db", + ) + .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4) + .build() + .also { INSTANCE = it } + } + } + } +} diff --git a/core/database/src/main/java/ru/forbion/f7cloud/core/database/FileEntity.kt b/core/database/src/main/java/ru/forbion/f7cloud/core/database/FileEntity.kt new file mode 100644 index 0000000..8138e8e --- /dev/null +++ b/core/database/src/main/java/ru/forbion/f7cloud/core/database/FileEntity.kt @@ -0,0 +1,14 @@ +package ru.forbion.f7cloud.core.database + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "files") +data class FileEntity( + @PrimaryKey(autoGenerate = true) + val id: Long = 0, + val serverUrl: String, + val username: String, + val name: String, + val isDirectory: Boolean, +) diff --git a/core/database/src/main/java/ru/forbion/f7cloud/core/database/FilesDao.kt b/core/database/src/main/java/ru/forbion/f7cloud/core/database/FilesDao.kt new file mode 100644 index 0000000..e67721d --- /dev/null +++ b/core/database/src/main/java/ru/forbion/f7cloud/core/database/FilesDao.kt @@ -0,0 +1,18 @@ +package ru.forbion.f7cloud.core.database + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query + +@Dao +interface FilesDao { + @Query("SELECT * FROM files WHERE serverUrl = :serverUrl AND username = :username ORDER BY isDirectory DESC, name ASC") + suspend fun list(serverUrl: String, username: String): List + + @Query("DELETE FROM files WHERE serverUrl = :serverUrl AND username = :username") + suspend fun clear(serverUrl: String, username: String) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(items: List) +} diff --git a/core/designsystem/build.gradle b/core/designsystem/build.gradle new file mode 100644 index 0000000..effec78 --- /dev/null +++ b/core/designsystem/build.gradle @@ -0,0 +1,35 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'org.jetbrains.kotlin.plugin.compose' +} + +android { + namespace 'ru.forbion.f7cloud.core.designsystem' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + + buildFeatures { + compose true + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + def composeBom = platform('androidx.compose:compose-bom:2025.02.00') + implementation composeBom + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.foundation:foundation' + implementation 'androidx.compose.material3:material3' + implementation 'io.coil-kt:coil-compose:2.6.0' + implementation 'io.coil-kt:coil-svg:2.6.0' +} diff --git a/core/designsystem/src/main/AndroidManifest.xml b/core/designsystem/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/core/designsystem/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/AppForegroundTracker.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/AppForegroundTracker.kt new file mode 100644 index 0000000..88186d6 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/AppForegroundTracker.kt @@ -0,0 +1,15 @@ +package ru.forbion.f7cloud.core.designsystem + +/** + * Updated from [F7MobileApp] via ProcessLifecycleOwner. + * Background polling loops should check this before hitting the network. + */ +object AppForegroundTracker { + @Volatile + var isForeground: Boolean = true + private set + + fun setForeground(foreground: Boolean) { + isForeground = foreground + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AppMenuSheet.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AppMenuSheet.kt new file mode 100644 index 0000000..3ccb614 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AppMenuSheet.kt @@ -0,0 +1,222 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.itemsIndexed +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import coil.compose.AsyncImage + +private val BottomBarReserve: Dp = 90.dp +private val MenuIconSize = 62.dp +private val MenuGridGap = 20.dp + +data class F7AppMenuItem( + val label: String, + val iconUrl: String, + val selected: Boolean, + val externalUrl: String? = null, +) + +@Composable +fun F7AppMenuSheet( + visible: Boolean, + serverUrl: String, + items: List, + onDismiss: () -> Unit, + onItemClick: (Int) -> Unit, + modifier: Modifier = Modifier, +) { + var searchQuery by remember(visible) { mutableStateOf("") } + val filteredItems = remember(items, searchQuery) { + val query = searchQuery.trim() + if (query.isBlank()) { + items + } else { + items.filter { it.label.contains(query, ignoreCase = true) } + } + } + val base = serverUrl.trimEnd('/') + + AnimatedVisibility( + visible = visible, + enter = fadeIn(tween(250)) + slideInVertically( + animationSpec = tween(350), + initialOffsetY = { it }, + ), + exit = fadeOut(tween(200)) + slideOutVertically( + animationSpec = tween(300), + targetOffsetY = { it }, + ), + modifier = modifier, + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(bottom = BottomBarReserve) + .navigationBarsPadding() + .background(F7Colors.Background) + .padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp), + ) { + F7AppMenuSearchField( + serverUrl = base, + value = searchQuery, + onValueChange = { searchQuery = it }, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 24.dp), + ) + LazyVerticalGrid( + columns = GridCells.Fixed(4), + horizontalArrangement = Arrangement.spacedBy(MenuGridGap), + verticalArrangement = Arrangement.spacedBy(MenuGridGap), + contentPadding = PaddingValues(horizontal = 2.dp), + modifier = Modifier.fillMaxSize(), + ) { + itemsIndexed( + items = filteredItems, + key = { index, item -> "${item.label}-$index" }, + ) { index, item -> + val originalIndex = items.indexOf(item) + Box( + modifier = Modifier.fillMaxWidth(), + contentAlignment = Alignment.TopCenter, + ) { + F7AppMenuGridItem( + item = item, + onClick = { + if (originalIndex >= 0) { + onItemClick(originalIndex) + } + }, + ) + } + } + } + } + } +} + +@Composable +private fun F7AppMenuSearchField( + serverUrl: String, + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .height(40.dp) + .clip(RoundedCornerShape(20.dp)) + .background(Color.White) + .border(1.dp, Color(0xFFE6E6E6), RoundedCornerShape(20.dp)), + contentAlignment = Alignment.CenterStart, + ) { + AsyncImage( + model = "$serverUrl/themes/forbion/images/header/search-glass.svg", + contentDescription = null, + modifier = Modifier + .padding(start = 10.dp) + .size(18.dp), + contentScale = ContentScale.Fit, + ) + BasicTextField( + value = value, + onValueChange = onValueChange, + singleLine = true, + textStyle = TextStyle( + fontSize = 14.sp, + color = F7Colors.TextPrimary, + ), + cursorBrush = SolidColor(F7Colors.Primary), + modifier = Modifier + .fillMaxWidth() + .padding(start = 40.dp, end = 14.dp), + decorationBox = { innerTextField -> + Box(contentAlignment = Alignment.CenterStart) { + if (value.isBlank()) { + Text( + text = "Поиск...", + style = MaterialTheme.typography.bodyMedium, + color = Color(0xFF808080), + ) + } + innerTextField() + } + }, + ) + } +} + +@Composable +private fun F7AppMenuGridItem( + item: F7AppMenuItem, + onClick: () -> Unit, +) { + Column( + modifier = Modifier + .width(MenuIconSize) + .clickable(onClick = onClick), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + AsyncImage( + model = item.iconUrl, + contentDescription = item.label, + modifier = Modifier.size(MenuIconSize), + contentScale = ContentScale.Fit, + ) + Text( + text = item.label, + style = MaterialTheme.typography.labelLarge.copy( + fontWeight = FontWeight.Bold, + fontSize = 12.sp, + lineHeight = 14.sp, + color = Color(0xFF151515), + ), + textAlign = TextAlign.Center, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AutoHideBottomBar.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AutoHideBottomBar.kt new file mode 100644 index 0000000..561aa31 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7AutoHideBottomBar.kt @@ -0,0 +1,72 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.delay + +private val BottomBarFloatOffset = 6.dp + +/** + * Bottom bar visibility — mirrors forbion [mobileBottomBarAutoHide] (4s idle hide). + */ +@Composable +fun F7AutoHideBottomBar( + enabled: Boolean, + pinned: Boolean, + activityNonce: Int, + modifier: Modifier = Modifier, + hideDelayMs: Long = 4000L, + content: @Composable () -> Unit, +) { + if (!enabled) return + + var visible by remember { mutableStateOf(true) } + + LaunchedEffect(enabled, pinned, activityNonce) { + if (pinned) { + visible = true + return@LaunchedEffect + } + visible = true + delay(hideDelayMs) + if (!pinned) { + visible = false + } + } + + Box( + modifier = modifier + .fillMaxWidth() + .navigationBarsPadding() + .padding(bottom = BottomBarFloatOffset), + contentAlignment = Alignment.BottomCenter, + ) { + AnimatedVisibility( + visible = visible, + enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }), + exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 }), + modifier = Modifier.wrapContentWidth(), + ) { + Box(contentAlignment = Alignment.BottomCenter) { + content() + } + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt new file mode 100644 index 0000000..70f8d7f --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7BottomBarConfig.kt @@ -0,0 +1,87 @@ +package ru.forbion.f7cloud.core.designsystem + +enum class F7BottomBarSlot { + Chats, + NavBack, + Create, + Profile, + Notifications, + Settings, + Menu, +} + +data class F7BottomBarConfig( + val slots: List, +) { + val buttonCount: Int get() = slots.size + + companion object { + fun forContext( + tabKey: String, + talkInRoom: Boolean, + ): F7BottomBarConfig = when (tabKey) { + "Talk" -> if (talkInRoom) { + F7BottomBarConfig(listOf(F7BottomBarSlot.Profile, F7BottomBarSlot.Notifications, F7BottomBarSlot.Menu)) + } else { + F7BottomBarConfig( + listOf( + F7BottomBarSlot.Chats, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Menu, + ), + ) + } + "Files" -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.NavBack, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Create, + F7BottomBarSlot.Settings, + F7BottomBarSlot.Menu, + ), + ) + "Contacts" -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.Create, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Menu, + ), + ) + "Tasks" -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.Create, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Menu, + ), + ) + "Support" -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.Create, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Menu, + ), + ) + "Mail", "Calendar" -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.NavBack, + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Settings, + F7BottomBarSlot.Menu, + ), + ) + else -> F7BottomBarConfig( + listOf( + F7BottomBarSlot.Profile, + F7BottomBarSlot.Notifications, + F7BottomBarSlot.Menu, + ), + ) + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Colors.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Colors.kt new file mode 100644 index 0000000..04f21de --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Colors.kt @@ -0,0 +1,45 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.ui.graphics.Color + +/** + * Palette from themes/forbion (mobile + f7support), light theme. + */ +object F7Colors { + val Primary = Color(0xFF70B62B) + val PrimaryHover = Color(0xFF6FAF2E) + val PrimaryDark = Color(0xFF5E922B) + val PrimaryLight = Color(0xFFECF9DE) + val PrimaryGradientStart = Color(0xFFC0FF7B) + val PrimaryGradientEnd = Color(0xFF7CBC3D) + + val Background = Color(0xFFFBFBFB) + val Surface = Color(0xFFFFFFFF) + val SurfaceMuted = Color(0xFFF5F5F5) + + val TextPrimary = Color(0xFF151515) + val TextSecondary = Color(0xFF808080) + val TextMuted = Color(0xFF8C8C8C) + val TextOnPrimary = Color(0xFFFFFFFF) + + val Border = Color(0xFFE6E6E6) + val BorderLight = Color(0xFFE0E0E0) + val SecondaryButtonBg = Color(0xFFFDFDFD) + val SecondaryButtonBorder = Color(0xFFE6E6E6) + + val Error = Color(0xFFD74642) + val ErrorBg = Color(0xFFFFE2E2) + + val StatusNew = Color(0xFF2B9AB6) + val StatusProgress = Color(0xFF70B62B) + val StatusClosed = Color(0xFF808080) + + val ChatBubbleIn = Color(0xFFFDFDFD) + val ChatBubbleOut = Color(0xFFE0F8C9) + val ChatBubbleSupport = Color(0xFFECF9DE) + val ChatText = Color(0xFF3F3F3F) + val ChatBackground = Color(0xFFE8EFE0) + val ChatDatePill = Color(0xFFF5F5F5) + val TalkComposerBorder = Color(0x3370B62B) + val TalkTopBarBorder = Color(0x3370B62B) +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Components.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Components.kt new file mode 100644 index 0000000..35667de --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Components.kt @@ -0,0 +1,585 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.TextButton +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onKeyEvent +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog + +/** + * Кнопки forbion (mobile): + * - [F7PrimaryButton] — градиент, CTA («Создать», «Войти», «Отправить») + * - [F7SolidPrimaryButton] — сплошной зелёный, диалоги NC + * - [F7SecondaryButton] — outline, «Обновить», «Назад», «Отмена» + * - [F7TextButton] — tertiary, текст без фона + */ + +@Composable +fun F7ScreenBackground(modifier: Modifier = Modifier, content: @Composable () -> Unit) { + Box( + modifier = modifier + .fillMaxSize() + .background(F7Colors.Background), + ) { + content() + } +} + +@Composable +fun F7ModuleScreen( + title: String? = null, + modifier: Modifier = Modifier, + loading: Boolean = false, + error: String? = null, + onRefresh: (() -> Unit)? = null, + headerActions: @Composable RowScope.() -> Unit = {}, + content: @Composable ColumnScope.() -> Unit, +) { + val showTitle = !title.isNullOrBlank() + val showHeader = showTitle || onRefresh != null + Column( + modifier = modifier + .fillMaxSize() + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + if (showHeader) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + if (showTitle) { + Text( + text = title.orEmpty(), + style = MaterialTheme.typography.titleLarge, + color = F7Colors.TextPrimary, + modifier = Modifier + .weight(1f) + .padding(end = 8.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } else { + Spacer(modifier = Modifier.weight(1f)) + } + Row( + modifier = Modifier.horizontalScroll(rememberScrollState()), + horizontalArrangement = Arrangement.spacedBy(6.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + headerActions() + if (onRefresh != null) { + F7HeaderActionButton( + text = "↻", + onClick = onRefresh, + enabled = !loading, + ) + } + } + } + } + if (loading) { + CircularProgressIndicator(color = F7Colors.Primary) + } + if (!error.isNullOrBlank()) { + Text(text = error, color = F7Colors.Error, style = MaterialTheme.typography.bodyMedium) + } + Column( + modifier = Modifier + .fillMaxWidth() + .weight(1f), + content = content, + ) + } +} + +@Composable +fun F7PrimaryButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + val shape = RoundedCornerShape(100.dp) + val gradient = Brush.linearGradient( + colors = listOf(F7Colors.PrimaryGradientStart, F7Colors.PrimaryGradientEnd), + ) + Button( + onClick = onClick, + enabled = enabled, + modifier = modifier + .heightIn(min = 44.dp) + .shadow( + elevation = 4.dp, + shape = shape, + spotColor = F7Colors.Primary.copy(alpha = 0.18f), + ambientColor = F7Colors.Primary.copy(alpha = 0.10f), + ), + shape = shape, + colors = ButtonDefaults.buttonColors( + containerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, + ), + contentPadding = androidx.compose.foundation.layout.PaddingValues(0.dp), + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .border(1.dp, F7Colors.Primary.copy(alpha = 0.22f), shape) + .background(brush = gradient, shape = shape) + .padding(horizontal = 18.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + color = F7Colors.TextOnPrimary, + style = MaterialTheme.typography.labelLarge, + ) + } + } +} + +@Composable +fun F7SolidPrimaryButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + Button( + onClick = onClick, + enabled = enabled, + modifier = modifier.heightIn(min = 40.dp), + shape = RoundedCornerShape(100.dp), + colors = ButtonDefaults.buttonColors( + containerColor = F7Colors.Primary, + contentColor = F7Colors.TextOnPrimary, + disabledContainerColor = F7Colors.Border, + disabledContentColor = F7Colors.TextSecondary, + ), + ) { + Text(text = text, style = MaterialTheme.typography.labelLarge) + } +} + +@Composable +fun F7HeaderActionButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + OutlinedButton( + onClick = onClick, + enabled = enabled, + modifier = modifier + .heightIn(min = 36.dp) + .widthIn(min = 36.dp, max = 52.dp), + shape = RoundedCornerShape(100.dp), + border = BorderStroke(1.dp, F7Colors.SecondaryButtonBorder), + colors = ButtonDefaults.outlinedButtonColors( + containerColor = F7Colors.SecondaryButtonBg, + contentColor = F7Colors.TextPrimary, + ), + contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = 8.dp, vertical = 4.dp), + ) { + Text( + text = text, + style = MaterialTheme.typography.labelLarge, + maxLines = 1, + ) + } +} + +@Composable +fun F7SecondaryButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + OutlinedButton( + onClick = onClick, + enabled = enabled, + modifier = modifier.heightIn(min = 40.dp), + shape = RoundedCornerShape(100.dp), + border = BorderStroke(1.dp, F7Colors.SecondaryButtonBorder), + colors = ButtonDefaults.outlinedButtonColors( + containerColor = F7Colors.SecondaryButtonBg, + contentColor = F7Colors.TextPrimary, + ), + ) { + Text(text = text, style = MaterialTheme.typography.labelLarge) + } +} + +@Composable +fun F7TextButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, +) { + TextButton( + onClick = onClick, + enabled = enabled, + modifier = modifier, + colors = ButtonDefaults.textButtonColors( + contentColor = F7Colors.TextPrimary, + disabledContentColor = F7Colors.TextSecondary, + ), + ) { + Text(text = text, style = MaterialTheme.typography.labelLarge) + } +} + +@Composable +fun F7AlertDialog( + title: String, + onDismiss: () -> Unit, + confirmText: String, + onConfirm: () -> Unit, + modifier: Modifier = Modifier, + dismissText: String = "Отмена", + confirmEnabled: Boolean = true, + content: @Composable ColumnScope.() -> Unit, +) { + Dialog(onDismissRequest = onDismiss) { + Surface( + modifier = modifier.widthIn(max = 400.dp), + shape = RoundedCornerShape(12.dp), + color = F7Colors.Surface, + ) { + Column( + modifier = Modifier.padding(20.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + Text(text = title, style = MaterialTheme.typography.titleMedium, color = F7Colors.TextPrimary) + content() + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.End), + ) { + F7SecondaryButton(text = dismissText, onClick = onDismiss) + F7SolidPrimaryButton( + text = confirmText, + onClick = onConfirm, + enabled = confirmEnabled, + ) + } + } + } + } +} + +@Composable +fun F7MessageComposer( + value: String, + onValueChange: (String) -> Unit, + onSend: () -> Unit, + modifier: Modifier = Modifier, + sending: Boolean = false, + label: String = "Сообщение", +) { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.Bottom, + ) { + F7OutlinedField( + value = value, + onValueChange = onValueChange, + label = label, + modifier = Modifier.weight(1f), + ) + F7PrimaryButton( + text = if (sending) "…" else "Отправить", + onClick = onSend, + enabled = value.isNotBlank() && !sending, + ) + } +} + +private val LINE_BREAK_CHARS = Regex("[\\r\\n\\u000B\\u000C\\u2028\\u2029\\u0085]") + +private fun stripLineBreaks(text: String): String = text.replace(LINE_BREAK_CHARS, "") + +private fun Modifier.consumeEnterKey(onEnter: () -> Unit): Modifier = this + .onPreviewKeyEvent { event -> + if (event.type == KeyEventType.KeyDown && event.isEnterKey()) { + onEnter() + true + } else { + false + } + } + .onKeyEvent { event -> + if (event.type == KeyEventType.KeyDown && event.isEnterKey()) { + onEnter() + true + } else { + false + } + } + +private fun androidx.compose.ui.input.key.KeyEvent.isEnterKey(): Boolean = + key == Key.Enter || key == Key.NumPadEnter + +@Composable +fun F7OutlinedField( + value: String, + onValueChange: (String) -> Unit, + label: String, + modifier: Modifier = Modifier, + minLines: Int = 1, + visualTransformation: VisualTransformation = VisualTransformation.None, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + onEnter: (() -> Unit)? = null, +) { + val singleLine = minLines <= 1 + val mergedKeyboardOptions = if (singleLine) { + keyboardOptions.copy( + capitalization = KeyboardCapitalization.None, + autoCorrectEnabled = false, + ) + } else { + keyboardOptions + } + OutlinedTextField( + value = value, + onValueChange = { newValue -> + if (!singleLine) { + onValueChange(newValue) + return@OutlinedTextField + } + val hadLineBreak = LINE_BREAK_CHARS.containsMatchIn(newValue) + val stripped = stripLineBreaks(newValue) + if (stripped != value) { + onValueChange(stripped) + } else if (stripped != newValue) { + onValueChange(stripped) + } + if (hadLineBreak) { + onEnter?.invoke() + } + }, + modifier = modifier + .fillMaxWidth() + .then(if (onEnter != null && singleLine) Modifier.consumeEnterKey(onEnter) else Modifier), + label = { Text(label) }, + minLines = if (singleLine) 1 else minLines, + visualTransformation = visualTransformation, + keyboardOptions = mergedKeyboardOptions, + keyboardActions = keyboardActions, + singleLine = singleLine, + maxLines = if (singleLine) 1 else minLines, + shape = RoundedCornerShape(100.dp), + colors = OutlinedTextFieldDefaults.colors( + focusedBorderColor = F7Colors.Primary, + unfocusedBorderColor = F7Colors.Border, + focusedContainerColor = Color(0xFFFDFDFD), + unfocusedContainerColor = Color(0xFFFDFDFD), + cursorColor = F7Colors.Primary, + ), + ) +} + +@Composable +fun F7ListCard( + modifier: Modifier = Modifier, + selected: Boolean = false, + onClick: (() -> Unit)? = null, + content: @Composable ColumnScope.() -> Unit, +) { + val shape = RoundedCornerShape(8.dp) + Column( + modifier = modifier + .fillMaxWidth() + .clip(shape) + .background(F7Colors.Surface) + .border( + width = if (selected) 2.dp else 1.dp, + color = if (selected) F7Colors.PrimaryGradientEnd else F7Colors.Border, + shape = shape, + ) + .then(if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier) + .padding(12.dp), + content = content, + ) +} + +@Composable +fun F7ChatBubble( + text: String, + outgoing: Boolean, + subtitle: String? = null, + modifier: Modifier = Modifier, +) { + val bg = if (outgoing) F7Colors.ChatBubbleOut else F7Colors.ChatBubbleIn + val align = if (outgoing) Alignment.CenterEnd else Alignment.CenterStart + Box(modifier = modifier.fillMaxWidth(), contentAlignment = align) { + Column( + modifier = Modifier + .fillMaxWidth(0.88f) + .clip(RoundedCornerShape(8.dp)) + .background(bg) + .border(1.dp, F7Colors.Border.copy(alpha = 0.5f), RoundedCornerShape(8.dp)) + .padding(horizontal = 12.dp, vertical = 8.dp), + ) { + if (!subtitle.isNullOrBlank()) { + Text( + text = subtitle, + style = MaterialTheme.typography.labelSmall, + color = F7Colors.TextSecondary, + ) + } + Text(text = text, style = MaterialTheme.typography.bodyMedium, color = F7Colors.ChatText) + } + } +} + +@Composable +fun F7TicketCard( + ticketNumber: String, + subject: String, + status: String, + preview: String, + hasUnread: Boolean, + selected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val statusColor = when { + status.equals("Новый", ignoreCase = true) -> F7Colors.StatusNew + status.equals("В работе", ignoreCase = true) -> F7Colors.StatusProgress + else -> F7Colors.StatusClosed + } + F7ListCard(modifier = modifier, selected = selected, onClick = onClick) { + Row( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(4.dp)) + .background(F7Colors.SurfaceMuted) + .padding(8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = subject, + style = MaterialTheme.typography.titleSmall, + color = F7Colors.TextPrimary, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f), + ) + F7StatusChip(text = status, color = statusColor) + } + Text( + text = "#$ticketNumber", + style = MaterialTheme.typography.labelSmall, + color = F7Colors.TextSecondary, + modifier = Modifier.padding(top = 6.dp), + ) + if (preview.isNotBlank()) { + Text( + text = preview, + style = MaterialTheme.typography.bodyMedium, + color = F7Colors.TextSecondary, + maxLines = 3, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.padding(top = 8.dp), + ) + } + if (hasUnread) { + Text( + text = "Новое", + color = F7Colors.Primary, + style = MaterialTheme.typography.labelMedium, + modifier = Modifier.padding(top = 6.dp), + ) + } + } +} + +@Composable +fun F7StatusChip(text: String, color: Color) { + Text( + text = text, + modifier = Modifier + .clip(RoundedCornerShape(100.dp)) + .background(color) + .padding(horizontal = 12.dp, vertical = 4.dp), + color = F7Colors.TextOnPrimary, + style = MaterialTheme.typography.labelSmall, + ) +} + +@Composable +fun F7AppScaffold( + modifier: Modifier = Modifier, + bottomBar: @Composable () -> Unit = {}, + content: @Composable (Modifier) -> Unit, +) { + Box(modifier = modifier.fillMaxSize()) { + F7ScreenBackground(modifier = Modifier.fillMaxSize()) { + content( + Modifier + .fillMaxSize() + .f7SafeTopInsets(), + ) + } + Box( + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth(), + contentAlignment = Alignment.BottomCenter, + ) { + bottomBar() + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7FloatingPanel.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7FloatingPanel.kt new file mode 100644 index 0000000..b3ad000 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7FloatingPanel.kt @@ -0,0 +1,90 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * Popup panel above the bottom bar — matches forbion mobile web + * (#header-menu-notifications, #header-menu-user-menu). + */ +@Composable +fun F7FloatingPanel( + visible: Boolean, + onDismiss: () -> Unit, + modifier: Modifier = Modifier, + bottomOffset: Dp = 80.dp, + fullHeight: Boolean = false, + contentPadding: PaddingValues = PaddingValues(16.dp), + content: @Composable ColumnScope.() -> Unit, +) { + AnimatedVisibility( + visible = visible, + enter = fadeIn() + slideInVertically(initialOffsetY = { it / 4 }), + exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 4 }), + ) { + Box(modifier = Modifier.fillMaxSize()) { + Box( + modifier = Modifier + .fillMaxSize() + .padding(bottom = bottomOffset) + .background(Color.Black.copy(alpha = 0.18f)) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onDismiss, + ), + ) + Column( + modifier = modifier + .align(Alignment.BottomStart) + .padding(start = 16.dp, end = 12.dp, bottom = bottomOffset) + .then(if (fullHeight) Modifier.statusBarsPadding() else Modifier) + .navigationBarsPadding() + .fillMaxWidth() + .then(if (fullHeight) Modifier.fillMaxHeight() else Modifier) + .shadow( + elevation = 12.dp, + shape = RoundedCornerShape(16.dp), + spotColor = Color.Black.copy(alpha = 0.12f), + ) + .clip(RoundedCornerShape(16.dp)) + .background(F7Colors.SecondaryButtonBg) + .border(1.dp, F7Colors.Border, RoundedCornerShape(16.dp)) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = {}, + ) + .padding(contentPadding), + content = content, + ) + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt new file mode 100644 index 0000000..3779b3e --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7MobileBottomBar.kt @@ -0,0 +1,188 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage + +data class F7BottomBarActions( + val onChatsClick: () -> Unit = {}, + val onNavBackClick: () -> Unit = {}, + val onCreateClick: () -> Unit = {}, + val onProfileClick: () -> Unit = {}, + val onNotificationsClick: () -> Unit = {}, + val onSettingsClick: () -> Unit = {}, + val onMenuClick: () -> Unit = {}, +) + +private val BottomBarButtonSize = 55.dp +private val BottomBarIconSize = 24.dp +private val BottomBarGap = 8.dp +private val BottomBarOuterPaddingH = 6.dp +private val BottomBarOuterPaddingV = 6.dp +private val BottomBarButtonShape = RoundedCornerShape(100.dp) +private val BottomBarBorderBrush = Brush.linearGradient( + listOf(Color(0x33C0FF7B), Color(0x3370B62B)), +) +private val BottomBarHighlightBrush = Brush.linearGradient( + listOf(Color(0x33C0FF7B), Color(0x3370B62B)), +) + +@Composable +fun F7MobileBottomBar( + serverUrl: String, + userId: String, + config: F7BottomBarConfig, + actions: F7BottomBarActions, + menuOpen: Boolean = false, + chatsHighlighted: Boolean = false, + navBackHighlighted: Boolean = false, + showNotificationBadge: Boolean = false, + modifier: Modifier = Modifier, +) { + val base = serverUrl.trimEnd('/') + val pillShape = RoundedCornerShape(percent = 50) + Row( + modifier = modifier + .wrapContentWidth() + .shadow( + elevation = 2.dp, + shape = pillShape, + spotColor = Color(0xFFE6E6E6), + ) + .clip(pillShape) + .background(Color(0xFFF5F5F5)) + .padding( + horizontal = BottomBarOuterPaddingH, + vertical = BottomBarOuterPaddingV, + ), + horizontalArrangement = Arrangement.spacedBy(BottomBarGap), + verticalAlignment = Alignment.CenterVertically, + ) { + config.slots.forEach { slot -> + when (slot) { + F7BottomBarSlot.Chats -> F7BottomBarIconSlot( + iconUrl = if (chatsHighlighted) { + "$base/themes/forbion/images/header/chat-icon-green.svg" + } else { + "$base/themes/forbion/images/header/chat-icon-gray.svg" + }, + contentDescription = "Чаты", + highlighted = chatsHighlighted, + onClick = actions.onChatsClick, + ) + F7BottomBarSlot.NavBack -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/sidebar-chevron-left.svg", + contentDescription = "Папки", + highlighted = navBackHighlighted, + iconRotation = if (navBackHighlighted) 180f else 0f, + onClick = actions.onNavBackClick, + ) + F7BottomBarSlot.Create -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/green-plus.svg", + contentDescription = "Создать", + onClick = actions.onCreateClick, + ) + F7BottomBarSlot.Profile -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/profile-menu-icon-big.svg", + contentDescription = "Профиль", + onClick = actions.onProfileClick, + ) + F7BottomBarSlot.Notifications -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/not-menu-icon-big.svg", + contentDescription = "Уведомления", + showBadge = showNotificationBadge, + onClick = actions.onNotificationsClick, + ) + F7BottomBarSlot.Settings -> F7BottomBarIconSlot( + iconUrl = "$base/themes/forbion/images/header/setting-menu-icon.svg", + contentDescription = "Настройки", + onClick = actions.onSettingsClick, + ) + F7BottomBarSlot.Menu -> F7BottomBarIconSlot( + iconUrl = if (menuOpen) { + "$base/themes/forbion/images/header/menu-burger-green.svg" + } else { + "$base/themes/forbion/images/header/menu-burger-gray.svg" + }, + contentDescription = "Меню", + highlighted = menuOpen, + onClick = actions.onMenuClick, + ) + } + } + } +} + +@Composable +private fun F7BottomBarIconSlot( + iconUrl: String, + contentDescription: String, + onClick: () -> Unit, + highlighted: Boolean = false, + iconRotation: Float = 0f, + showBadge: Boolean = false, +) { + val bg = if (highlighted) BottomBarHighlightBrush else null + Box( + modifier = Modifier + .size(BottomBarButtonSize) + .clip(BottomBarButtonShape) + .then( + if (bg != null) { + Modifier.background(bg, BottomBarButtonShape) + } else { + Modifier.background(Color(0x99FFFFFF), BottomBarButtonShape) + }, + ) + .border( + width = 1.dp, + brush = BottomBarBorderBrush, + shape = BottomBarButtonShape, + ) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onClick, + ), + contentAlignment = Alignment.Center, + ) { + AsyncImage( + model = iconUrl, + contentDescription = contentDescription, + modifier = Modifier + .size(BottomBarIconSize) + .graphicsLayer { rotationZ = iconRotation }, + contentScale = ContentScale.Fit, + ) + if (showBadge) { + Box( + Modifier + .align(Alignment.TopEnd) + .padding(top = 10.dp, end = 10.dp) + .size(8.dp) + .clip(BottomBarButtonShape) + .background(Color(0xFFE53935)), + ) + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7NotificationRow.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7NotificationRow.kt new file mode 100644 index 0000000..05402a7 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7NotificationRow.kt @@ -0,0 +1,141 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import coil.compose.AsyncImage +import coil.request.ImageRequest +import okhttp3.Credentials + +private fun TextStyle.doubled(): TextStyle = copy( + fontSize = fontSize * 2, + lineHeight = lineHeight * 2, +) + +@Composable +fun F7NotificationRow( + subject: String, + message: String, + relativeTime: String, + iconUrl: String?, + closeIconUrl: String, + authHeader: String?, + onClick: () -> Unit, + onDismiss: () -> Unit, + showDivider: Boolean, + modifier: Modifier = Modifier, +) { + val context = LocalContext.current + Column( + modifier = modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(horizontal = 16.dp, vertical = 16.dp), + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically, + ) { + if (relativeTime.isNotBlank()) { + Text( + text = relativeTime, + style = MaterialTheme.typography.labelSmall.doubled(), + fontWeight = FontWeight.Medium, + color = F7Colors.TextSecondary.copy(alpha = 0.55f), + ) + } + Box( + modifier = Modifier + .padding(start = 8.dp) + .size(44.dp) + .clip(CircleShape) + .clickable(onClick = onDismiss), + contentAlignment = Alignment.Center, + ) { + AsyncImage( + model = closeIconUrl, + contentDescription = "Закрыть", + modifier = Modifier.size(28.dp), + ) + } + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + horizontalArrangement = Arrangement.spacedBy(14.dp), + verticalAlignment = Alignment.Top, + ) { + Box( + modifier = Modifier + .size(64.dp) + .clip(CircleShape) + .background(F7Colors.SurfaceMuted), + contentAlignment = Alignment.Center, + ) { + val model = if (!iconUrl.isNullOrBlank()) { + ImageRequest.Builder(context) + .data(iconUrl) + .apply { + authHeader?.let { addHeader("Authorization", it) } + } + .build() + } else { + null + } + if (model != null) { + AsyncImage( + model = model, + contentDescription = null, + modifier = Modifier.size(36.dp), + contentScale = ContentScale.Fit, + ) + } + } + Text( + text = subject, + style = MaterialTheme.typography.bodyMedium.doubled(), + fontWeight = FontWeight.SemiBold, + color = F7Colors.TextPrimary, + modifier = Modifier.weight(1f), + ) + } + if (message.isNotBlank()) { + Text( + text = message, + style = MaterialTheme.typography.bodySmall.doubled(), + fontWeight = FontWeight.Medium, + color = F7Colors.TextSecondary.copy(alpha = 0.7f), + maxLines = 6, + overflow = TextOverflow.Ellipsis, + modifier = Modifier + .fillMaxWidth() + .padding(start = 78.dp, top = 6.dp), + ) + } + } + if (showDivider) { + HorizontalDivider(color = F7Colors.Border, thickness = 1.dp) + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7OverlayNavigation.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7OverlayNavigation.kt new file mode 100644 index 0000000..06564dd --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7OverlayNavigation.kt @@ -0,0 +1,108 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.gestures.awaitEachGesture +import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.compositionLocalOf +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.PointerEventPass +import androidx.compose.ui.input.pointer.pointerInput + +interface F7OverlayNavigationScope { + fun registerDismissHandler(handler: () -> Boolean): () -> Unit + + fun dismissTopOverlay(): Boolean +} + +private class F7OverlayNavigationScopeImpl : F7OverlayNavigationScope { + private val handlers = mutableStateListOf<() -> Boolean>() + + override fun registerDismissHandler(handler: () -> Boolean): () -> Unit { + handlers.add(handler) + return { handlers.remove(handler) } + } + + override fun dismissTopOverlay(): Boolean { + for (index in handlers.indices.reversed()) { + if (handlers[index]()) { + return true + } + } + return false + } +} + +val LocalF7OverlayNavigation = compositionLocalOf { null } + +@Composable +fun F7OverlayNavigationProvider( + onSwipeDismiss: () -> Boolean, + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + val scope = remember { F7OverlayNavigationScopeImpl() } + CompositionLocalProvider(LocalF7OverlayNavigation provides scope) { + androidx.compose.foundation.layout.Box( + modifier = modifier.f7SwipeFromRightToDismiss { + if (scope.dismissTopOverlay()) return@f7SwipeFromRightToDismiss + onSwipeDismiss() + }, + ) { + content() + } + } +} + +@Composable +fun F7OverlayDismissHandler( + enabled: Boolean, + onDismiss: () -> Unit, +) { + val scope = LocalF7OverlayNavigation.current ?: return + DisposableEffect(enabled, scope, onDismiss) { + if (!enabled) { + return@DisposableEffect onDispose {} + } + val unregister = scope.registerDismissHandler { + onDismiss() + true + } + onDispose(unregister) + } +} + +fun Modifier.f7SwipeFromRightToDismiss( + enabled: Boolean = true, + edgeFraction: Float = 0.24f, + dismissDistanceFraction: Float = 0.14f, + onDismiss: () -> Unit, +): Modifier { + if (!enabled) return this + return pointerInput(Unit) { + val edgeStartPx = size.width * (1f - edgeFraction) + val dismissDistancePx = size.width * dismissDistanceFraction + awaitEachGesture { + val down = awaitFirstDown(requireUnconsumed = false, pass = PointerEventPass.Initial) + if (down.position.x < edgeStartPx) return@awaitEachGesture + + var dragLeft = 0f + while (true) { + val event = awaitPointerEvent(pass = PointerEventPass.Initial) + val change = event.changes.firstOrNull { it.id == down.id } ?: break + if (!change.pressed) break + val delta = change.position.x - change.previousPosition.x + if (delta < 0f) { + dragLeft += -delta + } + if (dragLeft >= dismissDistancePx) { + onDismiss() + break + } + } + } + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7RelativeTime.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7RelativeTime.kt new file mode 100644 index 0000000..f3b9378 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7RelativeTime.kt @@ -0,0 +1,34 @@ +package ru.forbion.f7cloud.core.designsystem + +import java.time.Instant +import java.time.LocalDate +import java.time.ZoneId +import java.time.format.DateTimeFormatter +import java.time.temporal.ChronoUnit +import java.util.Locale + +fun formatNotificationRelativeTime(isoDatetime: String): String { + if (isoDatetime.isBlank()) return "" + val instant = runCatching { Instant.parse(isoDatetime) }.getOrNull() ?: return "" + val zone = ZoneId.systemDefault() + val date = instant.atZone(zone).toLocalDate() + val today = LocalDate.now(zone) + val days = ChronoUnit.DAYS.between(date, today) + return when { + days == 0L -> "сегодня" + days == 1L -> "вчера" + days == 2L -> "позавчера" + days in 3..6 -> "$days ${daysLabel(days)} назад" + else -> DateTimeFormatter.ofPattern("d MMM", Locale("ru")).format(date) + } +} + +private fun daysLabel(days: Long): String { + val mod10 = (days % 10).toInt() + val mod100 = (days % 100).toInt() + return when { + mod10 == 1 && mod100 != 11 -> "день" + mod10 in 2..4 && mod100 !in 12..14 -> "дня" + else -> "дней" + } +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Theme.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Theme.kt new file mode 100644 index 0000000..263eeae --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Theme.kt @@ -0,0 +1,37 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private val F7LightScheme = lightColorScheme( + primary = F7Colors.Primary, + onPrimary = F7Colors.TextOnPrimary, + primaryContainer = F7Colors.PrimaryLight, + onPrimaryContainer = F7Colors.TextPrimary, + secondary = F7Colors.PrimaryDark, + onSecondary = F7Colors.TextOnPrimary, + background = F7Colors.Background, + onBackground = F7Colors.TextPrimary, + surface = F7Colors.Surface, + onSurface = F7Colors.TextPrimary, + surfaceVariant = F7Colors.SurfaceMuted, + onSurfaceVariant = F7Colors.TextSecondary, + outline = F7Colors.Border, + error = F7Colors.Error, + onError = Color.White, + errorContainer = F7Colors.ErrorBg, + onErrorContainer = F7Colors.TextPrimary, +) + +@Composable +fun F7Theme( + content: @Composable () -> Unit, +) { + MaterialTheme( + colorScheme = F7LightScheme, + typography = F7Typography, + content = content, + ) +} diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Typography.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Typography.kt new file mode 100644 index 0000000..9c366e4 --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7Typography.kt @@ -0,0 +1,27 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp +import ru.forbion.f7cloud.core.designsystem.R + +val RalewayFamily = FontFamily( + Font(R.font.raleway_medium, FontWeight.Medium), + Font(R.font.raleway_semibold, FontWeight.SemiBold), +) + +val F7Typography = Typography( + displayLarge = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.SemiBold, fontSize = 24.sp, lineHeight = 28.sp), + titleLarge = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.SemiBold, fontSize = 24.sp, lineHeight = 28.sp), + titleMedium = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 20.sp), + titleSmall = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp), + bodyLarge = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 16.sp, lineHeight = 20.sp), + bodyMedium = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp), + bodySmall = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 12.sp, lineHeight = 16.sp), + labelLarge = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp), + labelMedium = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 12.sp, lineHeight = 16.sp), + labelSmall = TextStyle(fontFamily = RalewayFamily, fontWeight = FontWeight.Medium, fontSize = 11.sp, lineHeight = 14.sp), +) diff --git a/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7WindowInsets.kt b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7WindowInsets.kt new file mode 100644 index 0000000..dd3660b --- /dev/null +++ b/core/designsystem/src/main/java/ru/forbion/f7cloud/core/designsystem/F7WindowInsets.kt @@ -0,0 +1,22 @@ +package ru.forbion.f7cloud.core.designsystem + +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.navigationBars +import androidx.compose.foundation.layout.only +import androidx.compose.foundation.layout.safeDrawing +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +/** Top + horizontal safe area (status bar, display cutout on foldables / punch-hole). */ +@Composable +fun Modifier.f7SafeTopInsets(): Modifier = windowInsetsPadding( + WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal), +) + +/** Bottom navigation bar / gesture area when the app bottom bar is hidden. */ +@Composable +fun Modifier.f7SafeBottomInsets(): Modifier = windowInsetsPadding( + WindowInsets.navigationBars, +) diff --git a/core/designsystem/src/main/res/font/raleway_medium.ttf b/core/designsystem/src/main/res/font/raleway_medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c6fa5335220df924a1293a4b37078b448f12cf5b GIT binary patch literal 164128 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 z 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 literal 0 HcmV?d00001 diff --git a/core/designsystem/src/main/res/font/raleway_semibold.ttf b/core/designsystem/src/main/res/font/raleway_semibold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..33969e8558009027421748910fb952d447cc4650 GIT binary patch literal 311856 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

0LX$`->m8 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 z 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 YMe+k=W{_bo@~33>CBxq3=M;zk2j1$H>Hq)$ literal 0 HcmV?d00001 diff --git a/core/network/build.gradle b/core/network/build.gradle new file mode 100644 index 0000000..7203ec7 --- /dev/null +++ b/core/network/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'ru.forbion.f7cloud.core.network' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1' + implementation 'org.json:json:20240303' + api 'com.squareup.okhttp3:okhttp:4.12.0' +} diff --git a/core/network/src/main/AndroidManifest.xml b/core/network/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/core/network/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/BasicAuthInterceptor.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/BasicAuthInterceptor.kt new file mode 100644 index 0000000..03b4da3 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/BasicAuthInterceptor.kt @@ -0,0 +1,17 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.Credentials +import okhttp3.Interceptor +import okhttp3.Response + +class BasicAuthInterceptor( + private val username: String, + private val appPassword: String, +) : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val req = chain.request().newBuilder() + .header("Authorization", Credentials.basic(username, appPassword)) + .build() + return chain.proceed(req) + } +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalDavClient.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalDavClient.kt new file mode 100644 index 0000000..a2cf608 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalDavClient.kt @@ -0,0 +1,1050 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import org.xmlpull.v1.XmlPullParser +import org.xmlpull.v1.XmlPullParserFactory +import java.net.URI +import java.net.URLDecoder +import java.time.Instant +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.ZoneId +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.util.UUID +import java.util.regex.Pattern + +data class DavCalendar( + val href: String, + val displayName: String, + val color: String? = null, +) + +data class DavEvent( + val uid: String, + val href: String, + val etag: String, + val summary: String, + val startLabel: String, + val startEpochMilli: Long, + val endEpochMilli: Long, + val calendarName: String, + val calendarHref: String, + val allDay: Boolean, + val lastModifiedEpochMilli: Long, + val description: String = "", + val location: String = "", + val rrule: String = "", + val categories: List = emptyList(), + val status: String = "CONFIRMED", + val classification: String = "PUBLIC", + val attendees: List = emptyList(), + val organizerEmail: String = "", + val organizerName: String = "", + val alarms: List = emptyList(), + val conferenceUri: String = "", +) + +data class DavTrashEvent( + val uid: String, + val href: String, + val etag: String, + val summary: String, + val deletedAt: String, + val calendarUri: String, + val calendarData: String, +) + +data class DavTask( + val uid: String, + val href: String, + val etag: String, + val summary: String, + val status: String, + val due: String, + val dueRaw: String, + val priority: Int, + val percentComplete: Int, + val description: String, + val calendarName: String, + val calendarHref: String, +) { + val isCompleted: Boolean + get() = status.equals("COMPLETED", ignoreCase = true) || percentComplete >= 100 +} + +object CalDavClient { + private val icsSummary = Pattern.compile("SUMMARY:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsDtStart = Pattern.compile("DTSTART[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsDtEnd = Pattern.compile("DTEND[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsDue = Pattern.compile("DUE[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsStatus = Pattern.compile("STATUS:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsUid = Pattern.compile("UID:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsDtStamp = Pattern.compile("DTSTAMP[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsLastModified = Pattern.compile("LAST-MODIFIED[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsPriority = Pattern.compile("PRIORITY:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsPercent = Pattern.compile("PERCENT-COMPLETE:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsDescription = Pattern.compile("DESCRIPTION:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val icsLocation = Pattern.compile("LOCATION:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + + fun calendarsBase(serverUrl: String, userId: String): String { + val base = serverUrl.trimEnd('/') + val encodedUser = userId.trim().trimEnd('/').split('/').joinToString("/") { segment -> + java.net.URLEncoder.encode(segment, Charsets.UTF_8.name()).replace("+", "%20") + } + return "$base/remote.php/dav/calendars/$encodedUser/" + } + + fun listCalendars(client: OkHttpClient, baseUrl: String): List { + val body = """ + + + + + """.trimIndent() + val xml = propfind(client, baseUrl, depth = 1, body) + return parseCalendars(xml, baseUrl) + } + + fun queryEvents( + client: OkHttpClient, + calendar: DavCalendar, + daysAhead: Int = 30, + ): List { + val now = Instant.now() + return queryEventsInRange( + client, + calendar, + now, + now.plusSeconds(daysAhead.toLong() * 86400L), + ) + } + + fun queryEventsInRange( + client: OkHttpClient, + calendar: DavCalendar, + rangeStart: Instant, + rangeEnd: Instant, + ): List { + val startStr = formatCalDavTime(rangeStart) + val endStr = formatCalDavTime(rangeEnd) + val body = """ + + + + + + + + + + + + """.trimIndent() + val href = calendar.href.trimEnd('/') + "/" + val xml = report(client, href, body) + return parseCalendarQueryResponses(xml, calendar) + } + + fun createEvent( + client: OkHttpClient, + calendar: DavCalendar, + summary: String, + start: LocalDateTime, + durationMinutes: Long = 60, + allDay: Boolean = false, + description: String = "", + location: String = "", + end: LocalDateTime? = null, + ): String { + val zone = ZoneId.systemDefault() + val startZoned = if (allDay) { + start.toLocalDate().atStartOfDay(zone) + } else { + start.atZone(zone) + } + val endZoned = when { + allDay -> start.toLocalDate().plusDays(1).atStartOfDay(zone) + end != null -> end.atZone(zone) + else -> startZoned.plusMinutes(durationMinutes) + } + val uid = "${UUID.randomUUID()}@f7cloud.mobile" + val ics = buildVEventIcs( + uid = uid, + summary = summary, + startEpochMilli = startZoned.toInstant().toEpochMilli(), + endEpochMilli = endZoned.toInstant().toEpochMilli(), + allDay = allDay, + description = description, + location = location, + ) + val url = calendar.href.trimEnd('/') + "/$uid.ics" + val req = Request.Builder() + .url(url) + .header("If-None-Match", "*") + .put(ics.toRequestBody("text/calendar; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV create event HTTP ${response.code}") + } + } + return uid + } + + fun updateEvent( + client: OkHttpClient, + calendar: DavCalendar, + href: String, + etag: String, + data: CalendarEventData, + ) { + putEventIcs(client, href, etag.ifBlank { "*" }, CalendarIcs.build(data)) + } + + fun updateEvent( + client: OkHttpClient, + calendar: DavCalendar, + href: String, + etag: String, + uid: String, + summary: String, + startEpochMilli: Long, + endEpochMilli: Long, + allDay: Boolean, + description: String = "", + location: String = "", + ) { + updateEvent( + client, + calendar, + href, + etag, + CalendarEventData( + uid = uid, + summary = summary, + description = description, + location = location, + startEpochMilli = startEpochMilli, + endEpochMilli = endEpochMilli, + allDay = allDay, + ), + ) + } + + fun deleteEvent(client: OkHttpClient, href: String, etag: String) { + val req = Request.Builder() + .url(href) + .header("If-Match", etag) + .delete() + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 204 && response.code != 404) { + error("CalDAV delete event HTTP ${response.code}") + } + } + } + + fun fetchEventByHref(client: OkHttpClient, href: String): DavEvent? { + val body = """ + + + + + """.trimIndent() + val xml = propfind(client, href, depth = 0, body) + val cal = DavCalendar(href.substringBeforeLast('/').substringBeforeLast('/') + "/", "") + return parseCalendarQueryResponses(xml, cal).firstOrNull() + } + + fun putEventIcs( + client: OkHttpClient, + url: String, + etag: String?, + ics: String, + ) { + val builder = Request.Builder() + .url(url) + .put(ics.toRequestBody("text/calendar; charset=utf-8".toMediaType())) + if (!etag.isNullOrBlank()) { + builder.header("If-Match", etag) + } else { + builder.header("If-None-Match", "*") + } + client.newCall(builder.build()).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV put event HTTP ${response.code}") + } + } + } + + fun createCalendar( + client: OkHttpClient, + baseUrl: String, + calendarUri: String, + displayName: String, + withTasks: Boolean = false, + ): DavCalendar { + val url = baseUrl.trimEnd('/') + "/" + calendarUri.trim('/') + "/" + val components = if (withTasks) { + """""" + } else { + """""" + } + val body = """ + + + + + ${escapeXml(displayName)} + $components + + + + """.trimIndent() + val req = Request.Builder() + .url(url) + .method("MKCALENDAR", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV create calendar HTTP ${response.code}") + } + } + return DavCalendar(href = url, displayName = displayName) + } + + fun createSubscription( + client: OkHttpClient, + baseUrl: String, + subscriptionUri: String, + displayName: String, + sourceUrl: String, + ): DavCalendar { + val url = baseUrl.trimEnd('/') + "/" + subscriptionUri.trim('/') + "/" + val body = """ + + + + + ${escapeXml(displayName)} + + ${escapeXml(sourceUrl)} + + + + """.trimIndent() + val req = Request.Builder() + .url(url) + .method("MKCOL", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV subscribe calendar HTTP ${response.code}") + } + } + return DavCalendar(href = url, displayName = displayName) + } + + fun listTrash(client: OkHttpClient, baseUrl: String): List { + val trashUrl = baseUrl.trimEnd('/') + "/trashbin/objects/" + val body = """ + + + + + + + + + + """.trimIndent() + val xml = propfind(client, trashUrl, depth = 1, body) + return parseTrashResponses(xml, trashUrl) + } + + fun restoreTrashEvent(client: OkHttpClient, trashHref: String, objectName: String) { + val base = trashHref.substringBefore("/trashbin/") + val destination = "$base/trashbin/restore/$objectName" + moveResource(client, trashHref, destination) + } + + fun purgeTrashEvent(client: OkHttpClient, href: String, etag: String) { + deleteEvent(client, href, etag) + } + + fun importEvents( + client: OkHttpClient, + calendar: DavCalendar, + icsContent: String, + ): Int { + val events = CalendarIcs.parseAll(icsContent) + var count = 0 + for (event in events) { + val uid = event.uid.ifBlank { CalendarIcs.newUid() } + val url = calendar.href.trimEnd('/') + "/$uid.ics" + putEventIcs(client, url, null, CalendarIcs.build(event.copy(uid = uid))) + count++ + } + return count + } + + private fun moveResource(client: OkHttpClient, sourceHref: String, destinationHref: String) { + val req = Request.Builder() + .url(sourceHref) + .method("MOVE", null) + .header("Destination", destinationHref) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV move HTTP ${response.code}") + } + } + } + + private fun parseTrashResponses(xml: String, trashUrl: String): List { + val parser = newParser(xml) + val out = mutableListOf() + var inResponse = false + var href = "" + var etag = "" + var deletedAt = "" + var calendarUri = "" + var calendarData = StringBuilder() + var inCalendarData = false + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + etag = "" + deletedAt = "" + calendarUri = "" + calendarData = StringBuilder() + } + "href" -> if (inResponse) href = parser.readText().trim() + "getetag" -> if (inResponse) etag = parser.readText().trim().trim('"') + "deleted-at" -> if (inResponse) deletedAt = parser.readText().trim() + "calendar-uri" -> if (inResponse) calendarUri = parser.readText().trim() + "calendar-data" -> { + inCalendarData = true + calendarData = StringBuilder() + } + } + XmlPullParser.TEXT -> if (inCalendarData) calendarData.append(parser.text) + XmlPullParser.END_TAG -> when (parser.localTag()) { + "calendar-data" -> inCalendarData = false + "response" -> { + if (inResponse && href.isNotBlank() && href.endsWith(".ics")) { + val fullHref = resolveHref(trashUrl, href) + val parsed = CalendarIcs.parseSingle(calendarData.toString()) + out += DavTrashEvent( + uid = parsed?.uid ?: href.substringAfterLast('/').removeSuffix(".ics"), + href = fullHref, + etag = etag, + summary = parsed?.summary ?: "(без названия)", + deletedAt = deletedAt, + calendarUri = calendarUri, + calendarData = calendarData.toString(), + ) + } + inResponse = false + } + } + } + parser.next() + } + return out + } + + private fun escapeXml(text: String): String = + text.replace("&", "&").replace("<", "<").replace(">", ">") + + private fun buildVEventIcs(data: CalendarEventData): String = CalendarIcs.build(data) + + private fun buildVEventIcs( + uid: String, + summary: String, + startEpochMilli: Long, + endEpochMilli: Long, + allDay: Boolean, + description: String = "", + location: String = "", + ): String = CalendarIcs.build( + CalendarEventData( + uid = uid, + summary = summary, + description = description, + location = location, + startEpochMilli = startEpochMilli, + endEpochMilli = endEpochMilli, + allDay = allDay, + ), + ) + + private fun parseCalendarQueryResponses(xml: String, calendar: DavCalendar): List { + val parser = newParser(xml) + val out = mutableListOf() + var inResponse = false + var href = "" + var etag = "" + var calendarData = StringBuilder() + var inCalendarData = false + val calendarHref = calendar.href + val calendarName = calendar.displayName + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + etag = "" + calendarData = StringBuilder() + } + "href" -> if (inResponse) href = parser.readText().trim() + "getetag" -> if (inResponse) etag = parser.readText().trim().trim('"') + "calendar-data" -> { + inCalendarData = true + calendarData = StringBuilder() + } + } + XmlPullParser.TEXT -> if (inCalendarData) calendarData.append(parser.text) + XmlPullParser.END_TAG -> when (parser.localTag()) { + "calendar-data" -> inCalendarData = false + "response" -> { + if (inResponse && href.isNotBlank() && calendarData.isNotEmpty()) { + val fullHref = resolveHref(calendarHref, href) + parseVEvent( + ics = calendarData.toString(), + calendarName = calendarName, + calendarHref = calendarHref, + href = fullHref, + etag = etag, + )?.let { out += it } + } + inResponse = false + } + } + } + parser.next() + } + return out + } + + private fun parseVEvent( + ics: String, + calendarName: String, + calendarHref: String, + href: String, + etag: String, + ): DavEvent? { + val parsed = CalendarIcs.parseSingle(ics) ?: return null + val startRaw = extractIcs(icsDtStart, ics) + val lastModified = listOf( + parseIcsInstant(extractIcs(icsDtStamp, ics)), + parseIcsInstant(extractIcs(icsLastModified, ics)), + ).filterNotNull().maxOrNull() ?: Instant.ofEpochMilli(parsed.startEpochMilli) + return DavEvent( + uid = parsed.uid, + href = href, + etag = etag, + summary = parsed.summary, + startLabel = formatIcsDateTime(startRaw.ifBlank { "" }), + startEpochMilli = parsed.startEpochMilli, + endEpochMilli = parsed.endEpochMilli, + calendarName = calendarName, + calendarHref = calendarHref, + allDay = parsed.allDay, + lastModifiedEpochMilli = lastModified.toEpochMilli(), + description = parsed.description, + location = parsed.location, + rrule = parsed.rrule, + categories = parsed.categories, + status = parsed.status, + classification = parsed.classification, + attendees = parsed.attendees, + organizerEmail = parsed.organizerEmail, + organizerName = parsed.organizerName, + alarms = parsed.alarms, + conferenceUri = parsed.conferenceUri, + ) + } + + fun parseIcsInstant(raw: String): Instant? { + val value = raw.trim() + if (value.isBlank()) return null + return runCatching { + when { + value.contains('T') -> { + val clean = value.replace("Z", "", ignoreCase = true).take(15) + LocalDateTime.parse(clean, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")) + .toInstant(ZoneOffset.UTC) + } + value.length >= 8 -> { + LocalDate.parse(value.take(8), DateTimeFormatter.BASIC_ISO_DATE) + .atStartOfDay(ZoneOffset.UTC) + .toInstant() + } + else -> null + } + }.getOrNull() + } + + private fun formatIcsUtc(instant: Instant): String = formatCalDavTime(instant) + + private fun formatIcsLocal(zoned: ZonedDateTime): String = + zoned.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")) + + private fun escapeIcsText(text: String): String = + text.replace("\\", "\\\\") + .replace("\n", "\\n") + .replace(",", "\\,") + .replace(";", "\\;") + + private fun unescapeIcsText(text: String): String = + text.replace("\\n", "\n") + .replace("\\,", ",") + .replace("\\;", ";") + .replace("\\\\", "\\") + + fun queryTasks(client: OkHttpClient, calendar: DavCalendar): List { + val body = """ + + + + + + + + + + """.trimIndent() + val href = calendar.href.trimEnd('/') + "/" + val xml = report(client, href, body) + return parseCalendarQueryResponsesForTasks(xml, calendar) + } + + fun createTask( + client: OkHttpClient, + calendar: DavCalendar, + summary: String, + dueDate: LocalDate? = null, + priority: Int = 0, + description: String = "", + ): DavTask { + val uid = "${UUID.randomUUID()}@f7cloud.mobile" + val ics = buildVTodoIcs( + uid = uid, + summary = summary, + status = "NEEDS-ACTION", + dueRaw = dueDate?.format(DateTimeFormatter.BASIC_ISO_DATE).orEmpty(), + priority = priority, + percentComplete = 0, + description = description, + ) + val url = calendar.href.trimEnd('/') + "/$uid.ics" + val req = Request.Builder() + .url(url) + .header("If-None-Match", "*") + .put(ics.toRequestBody("text/calendar; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("CalDAV create task HTTP ${response.code}") + } + } + val dueRaw = dueDate?.format(DateTimeFormatter.BASIC_ISO_DATE).orEmpty() + return DavTask( + uid = uid, + href = url, + etag = "", + summary = summary, + status = "NEEDS-ACTION", + due = formatIcsDateTime(dueRaw), + dueRaw = dueRaw, + priority = priority, + percentComplete = 0, + description = description, + calendarName = calendar.displayName, + calendarHref = calendar.href, + ) + } + + fun updateTask( + client: OkHttpClient, + task: DavTask, + summary: String = task.summary, + status: String = task.status, + dueRaw: String = task.dueRaw, + priority: Int = task.priority, + percentComplete: Int = task.percentComplete, + description: String = task.description, + ) { + val ics = buildVTodoIcs( + uid = task.uid, + summary = summary, + status = status, + dueRaw = dueRaw, + priority = priority, + percentComplete = percentComplete, + description = description, + ) + val req = Request.Builder() + .url(task.href) + .header("If-Match", task.etag.ifBlank { "*" }) + .put(ics.toRequestBody("text/calendar; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 204) { + error("CalDAV update task HTTP ${response.code}") + } + } + } + + fun deleteTask(client: OkHttpClient, task: DavTask) { + val req = Request.Builder() + .url(task.href) + .header("If-Match", task.etag.ifBlank { "*" }) + .delete() + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 204 && response.code != 404) { + error("CalDAV delete task HTTP ${response.code}") + } + } + } + + fun toggleTaskComplete(client: OkHttpClient, task: DavTask, completed: Boolean) { + updateTask( + client = client, + task = task, + status = if (completed) "COMPLETED" else "NEEDS-ACTION", + percentComplete = if (completed) 100 else 0, + ) + } + + /** Человекочитаемая дата из DTSTART/DUE (20250603T100000Z → 03.06.2026 10:00). */ + fun formatIcsDateTime(raw: String): String { + val value = raw.trim() + if (value.isBlank()) return "" + return runCatching { + when { + value.length >= 15 && value[8] == 'T' -> { + val dt = LocalDateTime.parse( + value.take(15), + DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss"), + ) + dt.atOffset(ZoneOffset.UTC).format( + DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"), + ) + } + value.length >= 8 -> { + LocalDate.parse(value.take(8), DateTimeFormatter.BASIC_ISO_DATE) + .format(DateTimeFormatter.ofPattern("dd.MM.yyyy")) + } + else -> value + } + }.getOrDefault(value) + } + + private fun propfind(client: OkHttpClient, url: String, depth: Int, body: String): String { + val req = Request.Builder() + .url(url) + .header("Depth", depth.toString()) + .method("PROPFIND", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + return execute(client, req) + } + + private fun report(client: OkHttpClient, url: String, body: String): String { + val req = Request.Builder() + .url(url) + .header("Depth", "1") + .method("REPORT", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + return execute(client, req) + } + + private fun execute(client: OkHttpClient, req: Request): String { + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + val code = response.code + if (code !in 200..299 && code != 207) { + error("CalDAV error HTTP $code") + } + val xml = response.body?.string().orEmpty() + if (xml.isBlank()) { + error("CalDAV empty response") + } + return xml + } + } + + private fun formatCalDavTime(instant: java.time.Instant): String { + return DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'") + .withZone(ZoneOffset.UTC) + .format(instant) + } + + private fun parseCalendars(xml: String, baseUrl: String): List { + val parser = newParser(xml) + val out = mutableListOf() + val basePath = baseUrl.toDavPath() + var inResponse = false + var href = "" + var displayName = "" + var calendarColor: String? = null + var isCollection = false + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + displayName = "" + calendarColor = null + isCollection = false + } + "collection" -> if (inResponse) isCollection = true + "displayname" -> if (inResponse) displayName = parser.readText().trim() + "calendar-color" -> if (inResponse) calendarColor = parser.readText().trim() + "href" -> if (inResponse) href = parser.readText().trim() + } + XmlPullParser.END_TAG -> if (parser.localTag() == "response" && inResponse) { + if (isCollection && href.isNotBlank()) { + val full = resolveHref(baseUrl, href) + val fullPath = full.toDavPath() + if (fullPath != basePath && + fullPath.startsWith(basePath) && + isUserCalendar(fullPath, basePath) + ) { + val name = displayName.ifBlank { + fullPath.removePrefix(basePath).trim('/').substringAfterLast('/') + } + out += DavCalendar(href = full, displayName = name, color = calendarColor) + } + } + inResponse = false + } + } + parser.next() + } + return out.distinctBy { it.href } + } + + private fun isUserCalendar(fullPath: String, basePath: String): Boolean { + val rel = fullPath.removePrefix(basePath).trim('/').lowercase() + if (rel.isBlank()) return false + val segment = rel.substringBefore('/') + return segment !in SKIP_CALENDAR_SEGMENTS + } + + private val SKIP_CALENDAR_SEGMENTS = setOf( + "inbox", + "outbox", + "trashbin", + "archive", + "deleted", + "system", + "contact_birthdays", + "contacts", + ) + + private fun resolveHref(baseUrl: String, href: String): String { + if (href.startsWith("http")) return href + if (href.startsWith("/")) { + val server = baseUrl.substringBefore("/remote.php") + return server + href + } + return baseUrl.trimEnd('/') + "/" + href.trimStart('/') + } + + private fun parseCalendarQueryResponsesForTasks(xml: String, calendar: DavCalendar): List { + val parser = newParser(xml) + val out = mutableListOf() + var inResponse = false + var href = "" + var etag = "" + var calendarData = StringBuilder() + var inCalendarData = false + val calendarHref = calendar.href + val calendarName = calendar.displayName + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + etag = "" + calendarData = StringBuilder() + } + "href" -> if (inResponse) href = parser.readText().trim() + "getetag" -> if (inResponse) etag = parser.readText().trim().trim('"') + "calendar-data" -> { + inCalendarData = true + calendarData = StringBuilder() + } + } + XmlPullParser.TEXT -> if (inCalendarData) calendarData.append(parser.text) + XmlPullParser.END_TAG -> when (parser.localTag()) { + "calendar-data" -> inCalendarData = false + "response" -> { + if (inResponse && href.isNotBlank() && calendarData.isNotEmpty()) { + val fullHref = resolveHref(calendarHref, href) + parseVTodo( + ics = calendarData.toString(), + calendarName = calendarName, + calendarHref = calendarHref, + href = fullHref, + etag = etag, + )?.let { out += it } + } + inResponse = false + } + } + } + parser.next() + } + return out + } + + private fun parseVTodo( + ics: String, + calendarName: String, + calendarHref: String, + href: String, + etag: String, + ): DavTask? { + val uid = extractIcs(icsUid, ics) + if (uid.isBlank()) return null + val dueRaw = extractIcs(icsDue, ics) + val percent = extractIcs(icsPercent, ics).toIntOrNull() ?: 0 + val status = extractIcs(icsStatus, ics).ifBlank { "NEEDS-ACTION" } + return DavTask( + uid = uid, + href = href, + etag = etag, + summary = extractIcs(icsSummary, ics).ifBlank { "(без названия)" }, + status = status, + due = formatIcsDateTime(dueRaw), + dueRaw = dueRaw, + priority = extractIcs(icsPriority, ics).toIntOrNull() ?: 0, + percentComplete = percent, + description = extractIcs(icsDescription, ics), + calendarName = calendarName, + calendarHref = calendarHref, + ) + } + + private fun buildVTodoIcs( + uid: String, + summary: String, + status: String, + dueRaw: String, + priority: Int, + percentComplete: Int, + description: String, + ): String { + val now = Instant.now() + return buildString { + appendLine("BEGIN:VCALENDAR") + appendLine("VERSION:2.0") + appendLine("PRODID:-//F7cloud Mobile//EN") + appendLine("BEGIN:VTODO") + appendLine("UID:$uid") + appendLine("DTSTAMP:${formatIcsUtc(now)}") + appendLine("SUMMARY:${escapeIcsText(summary)}") + appendLine("STATUS:$status") + if (dueRaw.isNotBlank()) { + if (dueRaw.contains('T')) { + appendLine("DUE:${dueRaw.replace("Z", "", ignoreCase = true)}") + } else { + appendLine("DUE;VALUE=DATE:${dueRaw.take(8)}") + } + } + if (priority > 0) { + appendLine("PRIORITY:$priority") + } + if (percentComplete > 0) { + appendLine("PERCENT-COMPLETE:$percentComplete") + } + if (description.isNotBlank()) { + appendLine("DESCRIPTION:${escapeIcsText(description)}") + } + appendLine("END:VTODO") + appendLine("END:VCALENDAR") + } + } + + private fun parseCalendarData(xml: String, map: (String) -> T?): List { + val parser = newParser(xml) + val out = mutableListOf() + var inCalendarData = false + val data = StringBuilder() + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> if (parser.localTag() == "calendar-data") { + inCalendarData = true + data.clear() + } + XmlPullParser.TEXT -> if (inCalendarData) data.append(parser.text) + XmlPullParser.END_TAG -> if (parser.localTag() == "calendar-data" && inCalendarData) { + val ics = data.toString() + map(ics)?.let { out += it } + inCalendarData = false + } + } + parser.next() + } + return out + } + + /** Marker in Android event description for sync mapping. */ + const val F7CLOUD_UID_MARKER_PREFIX = "F7CLOUD_UID:" + + fun extractIcs(pattern: Pattern, ics: String): String { + val m = pattern.matcher(ics) + return if (m.find()) m.group(1)?.trim().orEmpty() else "" + } + + private fun newParser(xml: String): XmlPullParser { + val parser = XmlPullParserFactory.newInstance().newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true) + parser.setInput(xml.reader()) + return parser + } + + private fun XmlPullParser.localTag(): String = name.substringAfter(':') + + private fun XmlPullParser.readText(): String { + if (next() != XmlPullParser.TEXT) return "" + return text.orEmpty() + } + + private fun String.toDavPath(): String { + val path = if (contains("://")) { + URI(this).path.orEmpty() + } else { + this + } + return try { + URLDecoder.decode(path, Charsets.UTF_8.name()).trim('/') + } catch (_: Exception) { + path.trim('/') + } + } +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalendarIcs.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalendarIcs.kt new file mode 100644 index 0000000..a7fc937 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CalendarIcs.kt @@ -0,0 +1,276 @@ +package ru.forbion.f7cloud.core.network + +import java.time.Instant +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.ZoneId +import java.time.ZoneOffset +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.util.UUID +import java.util.regex.Pattern + +data class CalendarAttendeeData( + val email: String, + val displayName: String = "", + val partStat: String = "NEEDS-ACTION", + val role: String = "REQ-PARTICIPANT", + val rsvp: Boolean = true, +) + +data class CalendarAlarmData( + val minutesBefore: Int, + val action: String = "DISPLAY", +) + +data class CalendarEventData( + val uid: String, + val summary: String, + val description: String = "", + val location: String = "", + val startEpochMilli: Long, + val endEpochMilli: Long, + val allDay: Boolean = false, + val rrule: String = "", + val categories: List = emptyList(), + val status: String = "CONFIRMED", + val classification: String = "PUBLIC", + val attendees: List = emptyList(), + val organizerEmail: String = "", + val organizerName: String = "", + val alarms: List = emptyList(), + val conferenceUri: String = "", +) + +object CalendarIcs { + private val veventBlock = Pattern.compile("BEGIN:VEVENT([\\s\\S]*?)END:VEVENT", Pattern.CASE_INSENSITIVE) + private val linePattern = Pattern.compile("^([A-Z0-9-]+)(?:;[^:]*)?:(.*)$", Pattern.MULTILINE) + + fun parseAll(ics: String): List { + val unfolded = unfold(ics) + val blocks = veventBlock.matcher(unfolded) + val out = mutableListOf() + while (blocks.find()) { + parseVEventBlock(blocks.group(1) ?: continue)?.let { out += it } + } + return out + } + + fun parseSingle(ics: String): CalendarEventData? { + return parseAll(ics).firstOrNull() + } + + fun build(data: CalendarEventData): String = buildString { + appendLine("BEGIN:VCALENDAR") + appendLine("VERSION:2.0") + appendLine("PRODID:-//F7cloud Mobile//EN") + appendLine("CALSCALE:GREGORIAN") + append(serializeVEvent(data)) + appendLine("END:VCALENDAR") + } + + private fun parseVEventBlock(block: String): CalendarEventData? { + val lines = parseLines(block) + val uid = lines["UID"]?.trim().orEmpty() + if (uid.isBlank()) return null + val dtStartRaw = lines["DTSTART"].orEmpty() + val start = parseIcsInstant(dtStartRaw) ?: return null + val allDay = !dtStartRaw.contains('T') + val endRaw = lines["DTEND"] + val end = if (endRaw != null) { + parseIcsInstant(endRaw) ?: start.plusSeconds(if (allDay) 86400 else 3600) + } else { + start.plusSeconds(if (allDay) 86400 else 3600) + } + val attendees = lines.entries + .filter { it.key.startsWith("ATTENDEE") } + .mapNotNull { parseAttendeeLine(it.key, it.value) } + val organizer = lines["ORGANIZER"].orEmpty() + val (orgEmail, orgName) = parseOrganizer(organizer) + val alarms = parseAlarms(block) + val conference = lines.entries + .firstOrNull { it.key.startsWith("CONFERENCE") } + ?.value + ?.trim() + .orEmpty() + val location = unescape(lines["LOCATION"].orEmpty()) + val talkUrl = conference.ifBlank { + if (location.contains("/call/")) location else "" + } + return CalendarEventData( + uid = uid, + summary = unescape(lines["SUMMARY"].orEmpty()).ifBlank { "(без названия)" }, + description = unescape(lines["DESCRIPTION"].orEmpty()), + location = location, + startEpochMilli = start.toEpochMilli(), + endEpochMilli = end.toEpochMilli(), + allDay = allDay, + rrule = lines["RRULE"].orEmpty(), + categories = lines["CATEGORIES"]?.split(',')?.map { unescape(it.trim()) }?.filter { it.isNotBlank() }.orEmpty(), + status = lines["STATUS"]?.trim().orEmpty().ifBlank { "CONFIRMED" }, + classification = lines["CLASS"]?.trim().orEmpty().ifBlank { "PUBLIC" }, + attendees = attendees, + organizerEmail = orgEmail, + organizerName = orgName, + alarms = alarms, + conferenceUri = talkUrl, + ) + } + + private fun serializeVEvent(data: CalendarEventData): String = buildString { + val zone = ZoneId.systemDefault() + val tzId = zone.id.replace(":", "\\:") + val now = Instant.now() + appendLine("BEGIN:VEVENT") + appendLine("UID:${data.uid}") + appendLine("DTSTAMP:${formatUtc(now)}") + val startZ = Instant.ofEpochMilli(data.startEpochMilli).atZone(zone) + val endZ = Instant.ofEpochMilli(data.endEpochMilli).atZone(zone) + if (data.allDay) { + appendLine("DTSTART;VALUE=DATE:${startZ.format(DateTimeFormatter.BASIC_ISO_DATE)}") + appendLine("DTEND;VALUE=DATE:${endZ.format(DateTimeFormatter.BASIC_ISO_DATE)}") + } else { + appendLine("DTSTART;TZID=$tzId:${formatLocal(startZ)}") + appendLine("DTEND;TZID=$tzId:${formatLocal(endZ)}") + } + appendLine("SUMMARY:${escape(data.summary)}") + if (data.description.isNotBlank()) appendLine("DESCRIPTION:${escape(data.description)}") + if (data.location.isNotBlank()) appendLine("LOCATION:${escape(data.location)}") + if (data.rrule.isNotBlank()) appendLine("RRULE:${data.rrule}") + if (data.categories.isNotEmpty()) { + appendLine("CATEGORIES:${data.categories.joinToString(",") { escape(it) }}") + } + appendLine("STATUS:${data.status}") + appendLine("CLASS:${data.classification}") + val orgEmail = data.organizerEmail + if (orgEmail.isNotBlank()) { + val cn = if (data.organizerName.isNotBlank()) ";CN=${escape(data.organizerName)}" else "" + appendLine("ORGANIZER;CUTYPE=INDIVIDUAL$cn:mailto:$orgEmail") + } + data.attendees.forEach { attendee -> + val cn = if (attendee.displayName.isNotBlank()) ";CN=${escape(attendee.displayName)}" else "" + val rsvp = if (attendee.rsvp) ";RSVP=TRUE" else "" + appendLine( + "ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=${attendee.role};PARTSTAT=${attendee.partStat}$rsvp$cn:mailto:${attendee.email}", + ) + } + val talk = data.conferenceUri.ifBlank { + if (data.location.contains("/call/")) data.location else "" + } + if (talk.isNotBlank()) { + appendLine("CONFERENCE;FEATURE=PHONE,VIDEO;VALUE=URI:$talk") + if (data.location.isBlank()) appendLine("LOCATION:$talk") + } + data.alarms.forEach { alarm -> + appendLine("BEGIN:VALARM") + appendLine("ACTION:${alarm.action}") + appendLine("TRIGGER:-PT${alarm.minutesBefore}M") + appendLine("DESCRIPTION:${escape(data.summary)}") + appendLine("END:VALARM") + } + appendLine("END:VEVENT") + } + + fun newUid(): String = "${UUID.randomUUID()}@f7cloud.mobile" + + fun parseIcsInstant(raw: String): Instant? { + val value = raw.trim() + if (value.isBlank()) return null + return runCatching { + when { + value.contains('T') -> { + val clean = value.replace("Z", "", ignoreCase = true).take(15) + LocalDateTime.parse(clean, DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")) + .atZone(ZoneId.systemDefault()).toInstant() + } + value.length >= 8 -> { + LocalDate.parse(value.take(8), DateTimeFormatter.BASIC_ISO_DATE) + .atStartOfDay(ZoneId.systemDefault()).toInstant() + } + else -> null + } + }.getOrNull() + } + + private fun parseLines(block: String): Map { + val map = mutableMapOf() + unfold(block).lineSequence().forEach { line -> + val m = linePattern.matcher(line.trim()) + if (m.find()) { + val key = m.group(1)?.uppercase().orEmpty() + val value = m.group(2).orEmpty() + map[key] = if (map.containsKey(key)) "${map[key]}\n$value" else value + } + } + return map + } + + private fun parseAttendeeLine(key: String, value: String): CalendarAttendeeData? { + val email = value.substringAfter("mailto:", value).trim() + if (email.isBlank()) return null + val cn = Regex("CN=([^;:]+)", RegexOption.IGNORE_CASE).find(key)?.groupValues?.get(1)?.let(::unescape) + val partStat = Regex("PARTSTAT=([^;:]+)", RegexOption.IGNORE_CASE).find(key)?.groupValues?.get(1) ?: "NEEDS-ACTION" + val role = Regex("ROLE=([^;:]+)", RegexOption.IGNORE_CASE).find(key)?.groupValues?.get(1) ?: "REQ-PARTICIPANT" + val rsvp = !key.contains("RSVP=FALSE", ignoreCase = true) + return CalendarAttendeeData(email = email, displayName = cn.orEmpty(), partStat = partStat, role = role, rsvp = rsvp) + } + + private fun parseOrganizer(value: String): Pair { + val email = value.substringAfter("mailto:", value).trim() + val cn = Regex("CN=([^;:]+)", RegexOption.IGNORE_CASE).find(value)?.groupValues?.get(1)?.let(::unescape).orEmpty() + return email to cn + } + + private fun parseAlarms(block: String): List { + val alarmPattern = Pattern.compile("BEGIN:VALARM([\\s\\S]*?)END:VALARM", Pattern.CASE_INSENSITIVE) + val matcher = alarmPattern.matcher(block) + val out = mutableListOf() + while (matcher.find()) { + val lines = parseLines(matcher.group(1).orEmpty()) + val trigger = lines["TRIGGER"].orEmpty() + val minutes = parseTriggerMinutes(trigger) + if (minutes != null) { + out += CalendarAlarmData(minutesBefore = minutes, action = lines["ACTION"] ?: "DISPLAY") + } + } + return out + } + + private fun parseTriggerMinutes(trigger: String): Int? { + val t = trigger.trim() + val relative = Regex("-PT(\\d+)M", RegexOption.IGNORE_CASE).find(t)?.groupValues?.get(1)?.toIntOrNull() + if (relative != null) return relative + val hours = Regex("-PT(\\d+)H", RegexOption.IGNORE_CASE).find(t)?.groupValues?.get(1)?.toIntOrNull() + if (hours != null) return hours * 60 + val days = Regex("-P(\\d+)D", RegexOption.IGNORE_CASE).find(t)?.groupValues?.get(1)?.toIntOrNull() + if (days != null) return days * 24 * 60 + return null + } + + private fun unfold(raw: String): String { + val normalized = raw.replace("\r\n", "\n").replace('\r', '\n') + val lines = normalized.split('\n') + val unfolded = StringBuilder() + for (line in lines) { + if (line.startsWith(' ') || line.startsWith('\t')) { + if (unfolded.isNotEmpty()) unfolded.append(line.drop(1)) + } else { + if (unfolded.isNotEmpty()) unfolded.append('\n') + unfolded.append(line) + } + } + return unfolded.toString() + } + + private fun escape(text: String): String = + text.replace("\\", "\\\\").replace("\n", "\\n").replace(",", "\\,").replace(";", "\\;") + + private fun unescape(text: String): String = + text.replace("\\n", "\n").replace("\\,", ",").replace("\\;", ";").replace("\\\\", "\\") + + private fun formatUtc(instant: Instant): String = + instant.atZone(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'")) + + private fun formatLocal(zoned: ZonedDateTime): String = + zoned.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss")) +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/CardDavClient.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CardDavClient.kt new file mode 100644 index 0000000..1b3dd30 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/CardDavClient.kt @@ -0,0 +1,441 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import org.xmlpull.v1.XmlPullParser +import org.xmlpull.v1.XmlPullParserFactory +import java.net.URLDecoder +import java.util.Base64 +import java.util.UUID +import java.util.regex.Pattern + +data class DavContact( + val uid: String, + val displayName: String, + val email: String, + val phone: String, + val bookName: String, + val photoBase64: String = "", + val photoMimeType: String = "", + val organization: String = "", + val title: String = "", + val address: String = "", + val website: String = "", + val birthday: String = "", + val emails: String = "", + val phones: String = "", +) + +object CardDavClient { + private val fnPattern = Pattern.compile("FN[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val nPattern = Pattern.compile("N[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val emailPattern = Pattern.compile("EMAIL[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val telPattern = Pattern.compile("TEL[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val uidPattern = Pattern.compile("UID[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val orgPattern = Pattern.compile("ORG[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val titlePattern = Pattern.compile("TITLE[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val urlPattern = Pattern.compile("URL[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val adrPattern = Pattern.compile("ADR[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + private val bdayPattern = Pattern.compile("BDAY[^:]*:([^\\r\\n]+)", Pattern.CASE_INSENSITIVE) + + private val genericNames = setOf( + "contact", + "carddav", + "card dav", + "unknown", + "vcard", + ) + + fun listContacts( + client: OkHttpClient, + serverUrl: String, + userId: String, + limitPerBook: Int = 500, + ): List { + val base = davAddressBooksBaseUrl(serverUrl, userId) + val books = listAddressBooks(client, base) + val out = mutableListOf() + var fetchFailed = false + for (book in books) { + runCatching { fetchContactsFromBook(client, book, limitPerBook) } + .onSuccess { out += it } + .onFailure { fetchFailed = true } + } + if (out.isEmpty() && fetchFailed) { + error("Не удалось загрузить контакты") + } + return out.distinctBy { "${it.uid}|${it.email}" } + } + + fun createContact( + client: OkHttpClient, + serverUrl: String, + userId: String, + displayName: String, + email: String, + phone: String = "", + ): DavContact { + val base = davAddressBooksBaseUrl(serverUrl, userId) + val books = listAddressBooks(client, base) + val book = books.firstOrNull() + ?: error("Не найдена адресная книга") + val (bookUrl, bookName) = book + val uid = UUID.randomUUID().toString() + val vcard = buildVCard(uid, displayName, email, phone) + val url = bookUrl.trimEnd('/') + "/$uid.vcf" + val req = Request.Builder() + .url(url) + .put(vcard.toRequestBody("text/vcard; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("Не удалось создать контакт (HTTP ${response.code})") + } + } + return DavContact( + uid = uid, + displayName = displayName.trim(), + email = email.trim(), + phone = phone.trim(), + bookName = bookName, + ) + } + + private fun buildVCard(uid: String, displayName: String, email: String, phone: String): String { + val fn = displayName.trim() + val parts = fn.split(Regex("\\s+"), limit = 2) + val given = parts.getOrNull(0).orEmpty() + val family = parts.getOrNull(1).orEmpty() + return buildString { + append("BEGIN:VCARD\n") + append("VERSION:3.0\n") + append("UID:$uid\n") + append("FN:$fn\n") + append("N:$family;$given;;;\n") + if (email.isNotBlank()) { + append("EMAIL;TYPE=INTERNET:$email\n") + } + if (phone.isNotBlank()) { + append("TEL;TYPE=CELL:$phone\n") + } + append("END:VCARD\n") + } + } + + private fun listAddressBooks(client: OkHttpClient, baseUrl: String): List> { + val body = """ + + + + + """.trimIndent() + val xml = propfind(client, baseUrl, depth = 1, body) + val parsed = parseAddressBooks(xml, baseUrl) + return parsed.ifEmpty { + listOf(resolveHref(baseUrl, "contacts") to "Contacts") + } + } + + private fun fetchContactsFromBook( + client: OkHttpClient, + book: Pair, + limit: Int, + ): List { + val (href, bookName) = book + val url = href.trimEnd('/') + "/" + val body = """ + + + + + """.trimIndent() + val xml = propfind(client, url, depth = 1, body) + return parseContacts(xml, bookName).take(limit) + } + + private fun propfind(client: OkHttpClient, url: String, depth: Int, body: String): String { + val req = Request.Builder() + .url(url) + .header("Depth", depth.toString()) + .method("PROPFIND", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + client.newCall(req).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + val code = response.code + if (code !in 200..299 && code != 207) { + error("CardDAV error HTTP $code") + } + val xml = response.body?.string().orEmpty() + if (xml.isBlank()) { + error("CardDAV empty response") + } + return xml + } + } + + private fun parseAddressBooks(xml: String, baseUrl: String): List> { + val parser = newParser(xml) + val out = mutableListOf>() + val basePath = baseUrl.toDavPath() + var inResponse = false + var href = "" + var displayName = "" + var isCollection = false + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + displayName = "" + isCollection = false + } + "collection" -> if (inResponse) isCollection = true + "displayname" -> if (inResponse) displayName = parser.readText().trim() + "href" -> if (inResponse) href = parser.readText().trim() + } + XmlPullParser.END_TAG -> if (parser.localTag() == "response" && inResponse) { + if (isCollection && href.isNotBlank()) { + val full = resolveHref(baseUrl, href) + val fullPath = full.toDavPath() + if (fullPath != basePath && + fullPath.startsWith(basePath) && + !fullPath.contains("/system/") + ) { + val name = displayName.ifBlank { + fullPath.removePrefix(basePath).trim('/').substringAfterLast('/') + } + out += full to name + } + } + inResponse = false + } + } + parser.next() + } + return out + } + + private fun parseContacts(xml: String, bookName: String): List { + val parser = newParser(xml) + val out = mutableListOf() + var inAddressData = false + val data = StringBuilder() + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> if (parser.localTag() == "address-data") { + inAddressData = true + data.clear() + } + XmlPullParser.TEXT -> if (inAddressData) data.append(parser.text) + XmlPullParser.END_TAG -> if (parser.localTag() == "address-data" && inAddressData) { + val vcard = unfoldVCard(data.toString()) + val uid = extract(uidPattern, vcard).ifBlank { + vcard.hashCode().toString() + } + val name = resolveContactName(vcard) + val allEmails = extractAll(emailPattern, vcard) + val allPhones = extractAll(telPattern, vcard) + val email = allEmails.firstOrNull().orEmpty() + val phone = allPhones.firstOrNull().orEmpty() + val photo = parseContactPhoto(vcard) + if (name.isNotBlank() || email.isNotBlank()) { + out += DavContact( + uid = uid, + displayName = name, + email = email, + phone = phone, + bookName = bookName, + photoBase64 = photo?.base64.orEmpty(), + photoMimeType = photo?.mimeType.orEmpty(), + organization = formatOrganization(extract(orgPattern, vcard)), + title = extract(titlePattern, vcard), + address = formatAddress(extract(adrPattern, vcard)), + website = extract(urlPattern, vcard), + birthday = formatBirthday(extract(bdayPattern, vcard)), + emails = allEmails.joinToString("\n"), + phones = allPhones.joinToString("\n"), + ) + } + inAddressData = false + } + } + parser.next() + } + return out + } + + private fun unfoldVCard(raw: String): String { + val normalized = raw.replace("\r\n", "\n").replace('\r', '\n') + val lines = normalized.split('\n') + val unfolded = StringBuilder() + for (line in lines) { + if (line.startsWith(' ') || line.startsWith('\t')) { + if (unfolded.isNotEmpty()) { + unfolded.append(line.drop(1)) + } + } else { + if (unfolded.isNotEmpty()) unfolded.append('\n') + unfolded.append(line) + } + } + return unfolded.toString() + } + + private fun resolveHref(baseUrl: String, href: String): String { + if (href.startsWith("http")) return href + if (href.startsWith("/")) { + val server = baseUrl.substringBefore("/remote.php") + return server + href + } + return baseUrl.trimEnd('/') + "/" + href.trimStart('/') + } + + private fun extract(pattern: Pattern, text: String): String { + val m = pattern.matcher(text) + return if (m.find()) m.group(1)?.trim().orEmpty() else "" + } + + private fun extractAll(pattern: Pattern, text: String): List { + val m = pattern.matcher(text) + val out = mutableListOf() + while (m.find()) { + m.group(1)?.trim()?.takeIf { it.isNotBlank() }?.let { out += it } + } + return out.distinct() + } + + private fun formatOrganization(raw: String): String { + if (raw.isBlank()) return "" + return raw.split(';').firstOrNull()?.trim().orEmpty() + } + + private fun formatAddress(raw: String): String { + if (raw.isBlank()) return "" + val parts = raw.split(';') + return listOf( + parts.getOrNull(2).orEmpty(), + parts.getOrNull(3).orEmpty(), + parts.getOrNull(4).orEmpty(), + parts.getOrNull(5).orEmpty(), + parts.getOrNull(6).orEmpty(), + ) + .map { it.trim() } + .filter { it.isNotBlank() } + .joinToString(", ") + } + + private fun formatBirthday(raw: String): String { + val value = raw.trim() + if (value.isBlank()) return "" + if (value.length == 8 && value.all { it.isDigit() }) { + return "${value.substring(6, 8)}.${value.substring(4, 6)}.${value.substring(0, 4)}" + } + return value + } + + private fun resolveContactName(vcard: String): String { + val fn = extract(fnPattern, vcard) + if (fn.isNotBlank() && !isGenericName(fn)) return fn + val nRaw = extract(nPattern, vcard) + if (nRaw.isNotBlank()) { + val parts = nRaw.split(';') + val family = parts.getOrNull(0).orEmpty().trim() + val given = parts.getOrNull(1).orEmpty().trim() + val additional = parts.getOrNull(2).orEmpty().trim() + val composed = listOf(given, additional, family) + .filter { it.isNotBlank() } + .joinToString(" ") + if (composed.isNotBlank() && !isGenericName(composed)) return composed + } + val email = extract(emailPattern, vcard) + if (email.isNotBlank()) return email.substringBefore('@') + return fn.ifBlank { "" } + } + + private fun isGenericName(name: String): Boolean { + val normalized = name.trim().lowercase() + if (normalized.isBlank()) return true + return genericNames.contains(normalized) + } + + private data class ParsedContactPhoto( + val base64: String, + val mimeType: String, + ) + + private fun parseContactPhoto(vcard: String): ParsedContactPhoto? { + val line = vcard.lineSequence() + .firstOrNull { it.startsWith("PHOTO", ignoreCase = true) } + ?: return null + val colon = line.indexOf(':') + if (colon < 0) return null + val header = line.substring(0, colon) + val payload = line.substring(colon + 1).trim() + if (payload.isBlank()) return null + + if (payload.startsWith("data:", ignoreCase = true)) { + val mime = payload.substringAfter("data:", "") + .substringBefore(';') + .ifBlank { "image/jpeg" } + val base64 = payload.substringAfter("base64,", "") + return encodePhotoBase64(base64, mime) + } + if (header.contains("VALUE=URI", ignoreCase = true)) { + return null + } + val mime = when { + header.contains("TYPE=PNG", ignoreCase = true) || + header.contains("MEDIATYPE=image/png", ignoreCase = true) -> "image/png" + header.contains("TYPE=GIF", ignoreCase = true) || + header.contains("MEDIATYPE=image/gif", ignoreCase = true) -> "image/gif" + header.contains("TYPE=WEBP", ignoreCase = true) || + header.contains("MEDIATYPE=image/webp", ignoreCase = true) -> "image/webp" + else -> "image/jpeg" + } + return encodePhotoBase64(payload, mime) + } + + private fun encodePhotoBase64(raw: String, mimeType: String): ParsedContactPhoto? { + val normalized = raw.replace("\\s".toRegex(), "") + if (normalized.isBlank()) return null + val bytes = runCatching { + Base64.getDecoder().decode(normalized) + }.getOrNull() ?: return null + if (bytes.isEmpty()) return null + return ParsedContactPhoto( + base64 = Base64.getEncoder().encodeToString(bytes), + mimeType = mimeType, + ) + } + + private fun newParser(xml: String): XmlPullParser { + val parser = XmlPullParserFactory.newInstance().newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true) + parser.setInput(xml.reader()) + return parser + } + + private fun XmlPullParser.localTag(): String = name.substringAfter(':') + + private fun XmlPullParser.readText(): String { + if (next() != XmlPullParser.TEXT) return "" + return text.orEmpty() + } + + private fun String.toDavPath(): String { + val path = if (contains("://")) { + java.net.URI(this).path.orEmpty() + } else { + this + } + return try { + URLDecoder.decode(path, Charsets.UTF_8.name()).trim('/') + } catch (_: Exception) { + path.trim('/') + } + } +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/DavClient.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/DavClient.kt new file mode 100644 index 0000000..4dcf45c --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/DavClient.kt @@ -0,0 +1,300 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody +import org.xmlpull.v1.XmlPullParser +import org.xmlpull.v1.XmlPullParserFactory +import java.net.URLDecoder + +object DavClient { + data class DavEntry( + val name: String, + val href: String, + val isDirectory: Boolean, + val fileId: Long? = null, + val lastModified: Long? = null, + val size: Long? = null, + val mimeType: String? = null, + val favorite: Boolean = false, + ) + + fun mkcol(client: OkHttpClient, folderUrl: String) { + val request = Request.Builder() + .url(folderUrl) + .method("MKCOL", null) + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) { + throw UnauthorizedException() + } + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("DAV MKCOL HTTP ${response.code}") + } + } + } + + fun put( + client: OkHttpClient, + fileUrl: String, + body: RequestBody, + ) { + val request = Request.Builder() + .url(fileUrl) + .put(body) + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) { + throw UnauthorizedException() + } + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("DAV upload HTTP ${response.code}") + } + } + } + + fun propfind(client: OkHttpClient, folderUrl: String, depth: Int = 1): List { + val body = """ + + + + + + + + + + + + + """.trimIndent() + val request = Request.Builder() + .url(folderUrl) + .header("Depth", depth.toString()) + .method("PROPFIND", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + return client.newCall(request).execute().use { response -> + if (response.code == 401) { + throw UnauthorizedException() + } + val code = response.code + if (code !in 200..299 && code != 207) { + error("DAV error HTTP $code") + } + val xml = response.body?.string().orEmpty() + if (xml.isBlank()) { + error("DAV empty response") + } + parseMultiStatus(xml, folderUrl) + } + } + + private fun parseMultiStatus(xml: String, folderUrl: String): List { + val parser = XmlPullParserFactory.newInstance().newPullParser() + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true) + parser.setInput(xml.reader()) + + val folderPath = folderUrl.toDavPath() + val result = mutableListOf() + + var inResponse = false + var href = "" + var displayName = "" + var isCollection = false + var fileId: Long? = null + var lastModified: Long? = null + var size: Long? = null + var mimeType: String? = null + var favorite = false + + while (parser.eventType != XmlPullParser.END_DOCUMENT) { + when (parser.eventType) { + XmlPullParser.START_TAG -> { + when (parser.localTag()) { + "response" -> { + inResponse = true + href = "" + displayName = "" + isCollection = false + fileId = null + lastModified = null + size = null + mimeType = null + favorite = false + } + "href" -> if (inResponse) href = parser.readText() + "displayname" -> if (inResponse) displayName = parser.readText() + "collection" -> if (inResponse) isCollection = true + "getlastmodified" -> if (inResponse) { + lastModified = parseHttpDate(parser.readText()) + } + "getcontentlength" -> if (inResponse) { + parser.readText().toLongOrNull()?.let { size = it } + } + "getcontenttype" -> if (inResponse) { + mimeType = parser.readText().trim().ifBlank { null } + } + "fileid" -> if (inResponse) { + parser.readText().toLongOrNull()?.let { fileId = it } + } + "favorite" -> if (inResponse) { + favorite = parser.readText().trim() == "1" + } + } + } + XmlPullParser.END_TAG -> { + if (parser.localTag() == "response" && inResponse) { + inResponse = false + val entryPath = href.decodeHrefPath() + if (entryPath.isNotBlank() && entryPath != folderPath && entryPath.startsWith(folderPath)) { + val relative = entryPath.removePrefix(folderPath).trim('/') + if (relative.isNotBlank() && !relative.contains('/')) { + val name = displayName.trim().ifBlank { + relative.substringAfterLast('/') + } + if (name.isNotBlank() && name != "." && name != "..") { + result += DavEntry( + name = name, + href = href, + isDirectory = isCollection, + fileId = fileId, + lastModified = lastModified, + size = size, + mimeType = mimeType, + favorite = favorite, + ) + } + } + } + } + } + } + parser.next() + } + return result.sortedWith(compareByDescending { it.isDirectory }.thenBy { it.name.lowercase() }) + } + + fun delete(client: OkHttpClient, resourceUrl: String) { + val request = Request.Builder() + .url(resourceUrl) + .delete() + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 204) { + error("DAV DELETE HTTP ${response.code}") + } + } + } + + fun move(client: OkHttpClient, sourceUrl: String, destinationUrl: String) { + val request = Request.Builder() + .url(sourceUrl) + .method("MOVE", null) + .header("Destination", destinationUrl) + .header("Overwrite", "T") + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 201 && response.code != 204) { + error("DAV MOVE HTTP ${response.code}") + } + } + } + + fun setFavorite(client: OkHttpClient, resourceUrl: String, favorite: Boolean) { + val value = if (favorite) "1" else "0" + val body = """ + + + + + $value + + + + """.trimIndent() + val request = Request.Builder() + .url(resourceUrl) + .method("PROPPATCH", body.toRequestBody("application/xml; charset=utf-8".toMediaType())) + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (response.code !in 200..299 && response.code != 207) { + error("DAV PROPPATCH HTTP ${response.code}") + } + } + } + + private fun parseHttpDate(raw: String): Long? { + val trimmed = raw.trim() + if (trimmed.isBlank()) return null + return try { + val format = java.text.SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", java.util.Locale.US) + format.parse(trimmed)?.time + } catch (_: Exception) { + null + } + } + + private fun XmlPullParser.localTag(): String = name.substringAfter(':') + + private fun XmlPullParser.readText(): String { + if (next() != XmlPullParser.TEXT) return "" + return text.orEmpty() + } + + private fun String.decodeHrefPath(): String { + val path = try { + URLDecoder.decode(this, Charsets.UTF_8.name()) + } catch (_: Exception) { + this + } + return path.substringBefore('?').trim('/') + } + + private fun String.toDavPath(): String { + val path = if (contains("://")) { + java.net.URI(this).path.orEmpty() + } else { + this + } + return path.decodeHrefPath() + } +} + +fun davFilesBaseUrl(serverUrl: String, userId: String): String { + val base = serverUrl.trimEnd('/') + val encodedUser = userId.split('/').joinToString("/") { segment -> + java.net.URLEncoder.encode(segment, Charsets.UTF_8.name()).replace("+", "%20") + } + return "$base/remote.php/dav/files/$encodedUser/" +} + +fun davFolderUrl(serverUrl: String, userId: String, relativePath: String): String { + val base = davFilesBaseUrl(serverUrl, userId) + if (relativePath.isBlank()) return base + val encodedPath = relativePath.trim('/').split('/').joinToString("/") { segment -> + java.net.URLEncoder.encode(segment, Charsets.UTF_8.name()).replace("+", "%20") + } + return "$base$encodedPath/" +} + +fun davFileUrl(serverUrl: String, userId: String, relativePath: String): String { + val base = davFilesBaseUrl(serverUrl, userId) + if (relativePath.isBlank()) error("Путь к файлу пуст") + val encodedPath = relativePath.trim('/').split('/').joinToString("/") { segment -> + java.net.URLEncoder.encode(segment, Charsets.UTF_8.name()).replace("+", "%20") + } + return "$base$encodedPath" +} + +fun davAddressBooksBaseUrl(serverUrl: String, userId: String): String { + val base = serverUrl.trimEnd('/') + val encodedUser = userId.split('/').joinToString("/") { segment -> + java.net.URLEncoder.encode(segment, Charsets.UTF_8.name()).replace("+", "%20") + } + return "$base/remote.php/dav/addressbooks/users/$encodedUser/" +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/LoginFlowClient.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/LoginFlowClient.kt new file mode 100644 index 0000000..a50df7d --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/LoginFlowClient.kt @@ -0,0 +1,255 @@ +package ru.forbion.f7cloud.core.network + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.withContext +import okhttp3.Cookie +import okhttp3.CookieJar +import okhttp3.Credentials +import okhttp3.FormBody +import okhttp3.HttpUrl +import okhttp3.OkHttpClient +import okhttp3.Request +import org.json.JSONObject +import java.net.URLDecoder + +data class QrLoginResult( + val serverUrl: String, + val username: String, + val appPassword: String, +) + +object LoginFlowClient { + /** F7cloud mobile QR scheme. */ + const val F7_LOGIN_PREFIX = "f7://login/" + const val F7_OTP_PREFIX = "f7://onetime-login/" + + /** Browser login flow v2 landing URL prefix (QR on web login page). */ + private val BROWSER_FLOW_REGEX = Regex("""/login/v2/flow/([A-Za-z0-9]+)""") + + /** True when the scanned text looks like a complete F7 or browser login QR payload. */ + fun isCompleteQrPayload(qrData: String): Boolean { + val trimmed = qrData.trim() + return when { + trimmed.startsWith(F7_LOGIN_PREFIX) || trimmed.startsWith(F7_OTP_PREFIX) -> + parseCredentialParams(extractParams(trimmed)) != null + isBrowserLoginFlowUrl(trimmed) -> + (trimmed.startsWith("http://", ignoreCase = true) || + trimmed.startsWith("https://", ignoreCase = true)) && + BROWSER_FLOW_REGEX.containsMatchIn(trimmed) + else -> false + } + } + + suspend fun completeQrLogin(qrData: String, trustAllCerts: Boolean = false): QrLoginResult? = + withContext(Dispatchers.IO) { + when { + isBrowserLoginFlowUrl(qrData) -> null + else -> when (val payload = extractPayload(qrData)) { + null -> null + QrPayload.DirectLogin -> parseDirectLogin(extractParams(qrData)) + QrPayload.OneTimeLogin -> parseOneTimeLogin(extractParams(qrData), trustAllCerts) + } + } + } + + /** + * Approve browser login after scanning Login Flow v2 QR (logged-in mobile user). + */ + suspend fun approveBrowserLoginFromQr( + qrData: String, + username: String, + appPassword: String, + trustAllCerts: Boolean = false, + ): Boolean = withContext(Dispatchers.IO) { + val flowUrl = qrData.trim() + val landingUrl = normalizeBrowserFlowUrl(flowUrl) ?: return@withContext false + val cookies = mutableListOf() + val cookieJar = object : CookieJar { + override fun saveFromResponse(url: HttpUrl, list: List) { + cookies.removeAll { existing -> + list.any { it.name == existing.name && it.domain == existing.domain && it.path == existing.path } + } + cookies.addAll(list) + } + + override fun loadForRequest(url: HttpUrl): List = + cookies.filter { it.matches(url) } + } + val client = OkHttpClient.Builder() + .cookieJar(cookieJar) + .followRedirects(true) + .applyUnsafeSslIfNeeded(trustAllCerts) + .build() + + val landingHtml = client.newCall( + Request.Builder().url(landingUrl).get().build(), + ).execute().use { response -> + if (!response.isSuccessful) return@withContext false + response.body?.string().orEmpty() + } + + val stateToken = STATE_TOKEN_REGEX.find(landingHtml)?.groupValues?.get(1)?.trim().orEmpty() + if (stateToken.isBlank()) return@withContext false + + val requestToken = REQUEST_TOKEN_REGEX.find(landingHtml)?.groupValues?.get(1)?.trim().orEmpty() + val base = extractServerBase(landingUrl) + val apptokenUrl = "$base/login/v2/apptoken" + val form = FormBody.Builder() + .add("stateToken", stateToken) + .add("user", username) + .add("password", appPassword) + if (requestToken.isNotBlank()) { + form.add("requesttoken", requestToken) + } + + client.newCall( + Request.Builder() + .url(apptokenUrl) + .post(form.build()) + .build(), + ).execute().use { response -> + response.isSuccessful || response.code == 200 + } + } + + private fun isBrowserLoginFlowUrl(qrData: String): Boolean = + BROWSER_FLOW_REGEX.containsMatchIn(qrData) + + private fun extractServerBase(url: String): String { + val trimmed = url.trim() + return when { + trimmed.contains("/index.php") -> trimmed.substringBefore("/index.php") + trimmed.contains("/login/v2") -> trimmed.substringBefore("/login/v2") + else -> { + val schemeEnd = trimmed.indexOf("://") + if (schemeEnd == -1) return trimmed.trimEnd('/') + val pathStart = trimmed.indexOf('/', schemeEnd + 3) + if (pathStart == -1) trimmed else trimmed.substring(0, pathStart) + } + }.trimEnd('/') + } + + private fun normalizeBrowserFlowUrl(qrData: String): String? { + val trimmed = qrData.trim() + if (trimmed.startsWith("http://", ignoreCase = true) || trimmed.startsWith("https://", ignoreCase = true)) { + return trimmed + } + return null + } + + private val STATE_TOKEN_REGEX = Regex("""name=["']stateToken["']\s+value=["']([^"']+)["']""", RegexOption.IGNORE_CASE) + private val REQUEST_TOKEN_REGEX = Regex("""name=["']requesttoken["']\s+value=["']([^"']+)["']""", RegexOption.IGNORE_CASE) + + private enum class QrPayload { DirectLogin, OneTimeLogin } + + private fun extractPayload(qrData: String): QrPayload? = when { + qrData.startsWith(F7_LOGIN_PREFIX) -> QrPayload.DirectLogin + qrData.startsWith(F7_OTP_PREFIX) -> QrPayload.OneTimeLogin + else -> null + } + + private fun extractParams(qrData: String): String { + val prefix = when { + qrData.startsWith(F7_LOGIN_PREFIX) -> F7_LOGIN_PREFIX + qrData.startsWith(F7_OTP_PREFIX) -> F7_OTP_PREFIX + else -> return qrData + } + return qrData.removePrefix(prefix) + } + + private fun parseDirectLogin(params: String): QrLoginResult? { + val parsed = parseCredentialParams(params) ?: return null + return QrLoginResult(parsed.server.trimEnd('/'), parsed.user, parsed.password) + } + + private fun parseOneTimeLogin(params: String, trustAllCerts: Boolean): QrLoginResult? { + val parsed = parseCredentialParams(params) ?: return null + val client = OkHttpClient.Builder().applyUnsafeSslIfNeeded(trustAllCerts).build() + val credentials = Credentials.basic(parsed.user, parsed.password) + val url = "${parsed.server.trimEnd('/')}/ocs/v2.php/core/getapppassword-onetime" + val request = Request.Builder() + .url(url) + .header("Authorization", credentials) + .header("OCS-APIRequest", "true") + .header("Accept", "application/json") + .build() + client.newCall(request).execute().use { response -> + if (!response.isSuccessful) return null + val body = response.body?.string().orEmpty() + val appPassword = JSONObject(body) + .optJSONObject("ocs") + ?.optJSONObject("data") + ?.optString("apppassword") + .orEmpty() + if (appPassword.isBlank()) return null + return QrLoginResult(parsed.server.trimEnd('/'), parsed.user, appPassword) + } + } + + private data class CredentialParams( + val server: String, + val user: String, + val password: String, + ) + + private fun parseCredentialParams(params: String): CredentialParams? { + val values = params.split('&') + if (values.isEmpty() || values.size > 3) return null + var server = "" + var user = "" + var password = "" + values.forEach { value -> + when { + value.startsWith("user:") -> user = decode(value.removePrefix("user:")) + value.startsWith("server:") -> server = decode(value.removePrefix("server:")) + value.startsWith("password:") -> password = decode(value.removePrefix("password:")) + } + } + if (server.isBlank() || user.isBlank() || password.isBlank()) return null + return CredentialParams(server, user, password) + } + + suspend fun pollBrowserLogin(serverUrl: String, trustAllCerts: Boolean = false): QrLoginResult? = + withContext(Dispatchers.IO) { + val base = serverUrl.trimEnd('/') + val client = OkHttpClient.Builder().applyUnsafeSslIfNeeded(trustAllCerts).build() + val startRequest = Request.Builder() + .url("$base/index.php/login/v2") + .post(FormBody.Builder().build()) + .header("Clear-Site-Data", "cookies") + .build() + val startBody = client.newCall(startRequest).execute().use { response -> + if (!response.isSuccessful) return@withContext null + response.body?.string().orEmpty() + } + val json = JSONObject(startBody) + val poll = json.optJSONObject("poll") ?: return@withContext null + val token = poll.optString("token") + val pollUrl = poll.optString("endpoint") + if (token.isBlank() || pollUrl.isBlank()) return@withContext null + repeat(120) { + val pollRequest = Request.Builder() + .url(pollUrl) + .post(FormBody.Builder().add("token", token).build()) + .build() + val result = client.newCall(pollRequest).execute().use { response -> + if (!response.isSuccessful) return@use null + val body = response.body?.string().orEmpty() + if (body.isBlank()) return@use null + val obj = JSONObject(body) + QrLoginResult( + serverUrl = obj.optString("server", base).trimEnd('/'), + username = obj.optString("loginName"), + appPassword = obj.optString("appPassword"), + ).takeIf { it.username.isNotBlank() && it.appPassword.isNotBlank() } + } + if (result != null) return@withContext result + delay(250) + } + null + } + + private fun decode(value: String): String = + runCatching { URLDecoder.decode(value, Charsets.UTF_8.name()) }.getOrDefault(value) +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/NetworkFactory.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/NetworkFactory.kt new file mode 100644 index 0000000..a5f8485 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/NetworkFactory.kt @@ -0,0 +1,35 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.OkHttpClient +import java.util.concurrent.TimeUnit + +object NetworkFactory { + fun newAuthedClient( + username: String, + appPassword: String, + trustAllCerts: Boolean = false, + callTimeoutSeconds: Long = 30, + readTimeoutSeconds: Long = 30, + ): OkHttpClient { + return OkHttpClient.Builder() + .callTimeout(callTimeoutSeconds, TimeUnit.SECONDS) + .connectTimeout(20, TimeUnit.SECONDS) + .readTimeout(readTimeoutSeconds, TimeUnit.SECONDS) + .applyUnsafeSslIfNeeded(trustAllCerts) + .addInterceptor(BasicAuthInterceptor(username, appPassword)) + .build() + } + + /** Collabora / richdocuments: cold start and WOPI can be slow on mobile networks. */ + fun newAuthedClientForOffice( + username: String, + appPassword: String, + trustAllCerts: Boolean = false, + ): OkHttpClient = newAuthedClient( + username = username, + appPassword = appPassword, + trustAllCerts = trustAllCerts, + callTimeoutSeconds = 120, + readTimeoutSeconds = 120, + ) +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/NotificationsRepository.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/NotificationsRepository.kt new file mode 100644 index 0000000..8ec64a8 --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/NotificationsRepository.kt @@ -0,0 +1,95 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.Request +import org.json.JSONArray +import org.json.JSONObject +data class F7Notification( + val id: Long, + val subject: String, + val message: String, + val datetime: String, + val link: String, + val app: String, + val icon: String = "", +) + +class NotificationsRepository { + fun load( + serverUrl: String, + username: String, + appPassword: String, + trustAllCerts: Boolean = false, + limit: Int = 50, + ): List { + val client = NetworkFactory.newAuthedClient(username, appPassword, trustAllCerts) + val url = "${serverUrl.trimEnd('/')}/ocs/v2.php/apps/notifications/api/v2/notifications" + + "?format=json&limit=$limit" + val request = Request.Builder() + .url(url) + .header("OCS-APIRequest", "true") + .header("Accept", "application/json") + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (!response.isSuccessful || response.body == null) { + error("Уведомления HTTP ${response.code}") + } + val ocs = JSONObject(response.body!!.string()).optJSONObject("ocs") + ?: error("Некорректный ответ уведомлений") + val meta = ocs.optJSONObject("meta") + if (meta?.optString("status").equals("failure", ignoreCase = true)) { + error(meta?.optString("message").orEmpty().ifBlank { "Ошибка уведомлений" }) + } + val data = ocs.opt("data") + val array = when (data) { + is JSONArray -> data + is JSONObject -> JSONArray().put(data) + else -> JSONArray() + } + return parseNotifications(array) + } + } + + private fun parseNotifications(array: JSONArray): List { + val out = mutableListOf() + for (i in 0 until array.length()) { + val obj = array.optJSONObject(i) ?: continue + val id = obj.optLong("notification_id", 0L) + if (id <= 0L) continue + val subject = obj.optString("subject").ifBlank { obj.optString("app") } + out += F7Notification( + id = id, + subject = subject, + message = obj.optString("message"), + datetime = obj.optString("datetime"), + link = obj.optString("link"), + app = obj.optString("app"), + icon = obj.optString("icon"), + ) + } + return out + } + + fun dismiss( + serverUrl: String, + username: String, + appPassword: String, + notificationId: Long, + trustAllCerts: Boolean = false, + ) { + val client = NetworkFactory.newAuthedClient(username, appPassword, trustAllCerts) + val url = "${serverUrl.trimEnd('/')}/ocs/v2.php/apps/notifications/api/v2/notifications/$notificationId" + val request = Request.Builder() + .url(url) + .delete() + .header("OCS-APIRequest", "true") + .header("Accept", "application/json") + .build() + client.newCall(request).execute().use { response -> + if (response.code == 401) throw UnauthorizedException() + if (!response.isSuccessful) { + error("Уведомления HTTP ${response.code}") + } + } + } +} diff --git a/core/network/src/main/java/ru/forbion/f7cloud/core/network/OcsJson.kt b/core/network/src/main/java/ru/forbion/f7cloud/core/network/OcsJson.kt new file mode 100644 index 0000000..52d805d --- /dev/null +++ b/core/network/src/main/java/ru/forbion/f7cloud/core/network/OcsJson.kt @@ -0,0 +1,51 @@ +package ru.forbion.f7cloud.core.network + +import okhttp3.Request +import org.json.JSONArray +import org.json.JSONObject + +fun Request.Builder.applyOcsJson(): Request.Builder = + header("OCS-APIRequest", "true") + .header("Accept", "application/json") + +fun parseJsonObject(body: String, what: String = "ответ сервера"): JSONObject { + val trimmed = body.trim() + if (trimmed.isEmpty()) { + error("Пустой $what") + } + if (trimmed.startsWith("( + object : X509TrustManager { + override fun checkClientTrusted(chain: Array?, authType: String?) = Unit + override fun checkServerTrusted(chain: Array?, authType: String?) = Unit + override fun getAcceptedIssuers(): Array = emptyArray() + }, + ) + val sslContext = SSLContext.getInstance("TLS") + sslContext.init(null, trustAll, SecureRandom()) + val trustManager = trustAll[0] as X509TrustManager + sslSocketFactory(sslContext.socketFactory, trustManager) + hostnameVerifier { _, _ -> true } + return this +} diff --git a/core/push/build.gradle b/core/push/build.gradle new file mode 100644 index 0000000..cf593f5 --- /dev/null +++ b/core/push/build.gradle @@ -0,0 +1,28 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' +} + +android { + namespace 'ru.forbion.f7cloud.core.push' + compileSdk 36 + + defaultConfig { + minSdk 26 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = '17' + } +} + +dependencies { + implementation project(':core:auth') + implementation 'com.google.firebase:firebase-messaging:24.0.1' + implementation 'androidx.core:core-ktx:1.15.0' + implementation 'androidx.core:core:1.15.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1' +} diff --git a/core/push/src/main/AndroidManifest.xml b/core/push/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9da85ab --- /dev/null +++ b/core/push/src/main/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7CallActionReceiver.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7CallActionReceiver.kt new file mode 100644 index 0000000..b20361c --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7CallActionReceiver.kt @@ -0,0 +1,20 @@ +package ru.forbion.f7cloud.core.push + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +/** Handles Decline on incoming Talk call notifications. */ +class F7CallActionReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != ACTION_DECLINE) return + val roomToken = intent.getStringExtra(EXTRA_ROOM_TOKEN) + F7IncomingCallQueue.dismissAndShowNext(context, roomToken) + } + + companion object { + const val ACTION_DECLINE = "ru.forbion.f7cloud.action.DECLINE_CALL" + const val EXTRA_NOTIFICATION_ID = "notificationId" + const val EXTRA_ROOM_TOKEN = "roomToken" + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7FirebaseMessagingService.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7FirebaseMessagingService.kt new file mode 100644 index 0000000..48f8e72 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7FirebaseMessagingService.kt @@ -0,0 +1,113 @@ +package ru.forbion.f7cloud.core.push + +import android.Manifest +import android.content.pm.PackageManager +import android.os.Build +import android.os.PowerManager +import android.util.Log +import androidx.core.content.ContextCompat +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.RemoteMessage +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import ru.forbion.f7cloud.core.auth.AuthStore + +class F7FirebaseMessagingService : FirebaseMessagingService() { + override fun onNewToken(token: String) { + Log.i(TAG, "FCM token refreshed") + val session = AuthStore(this).load() + if (session != null) { + CoroutineScope(Dispatchers.IO).launch { + val code = F7PushRegistrar.registerBlocking(this@F7FirebaseMessagingService, session, token) + Log.i(TAG, "push register result: $code") + } + } + super.onNewToken(token) + } + + override fun onMessageReceived(message: RemoteMessage) { + val data = message.data + Log.i(TAG, "FCM data keys=${data.keys} priority=${message.priority}") + + val type = data["type"] + val clickUrl = data["acceptUrl"] + ?: data["url"] + ?: data["clickUrl"] + ?: data["link"] + val priority = data["priority"] + val highPriority = priority.equals("high", ignoreCase = true) + val title = message.notification?.title + ?: data["title"] + ?: "F7cloud" + val body = message.notification?.body + ?: data["body"] + ?: "" + + // Only explicit call pushes should ring — Talk recording/chat links may also contain "/call/". + val isCall = type == "call" + + val pushEvent = F7PushEventParser.parse(data, title, body) + F7PushEventHub.publish(pushEvent) + + if (isCall) { + if (!canPostNotifications()) { + Log.w(TAG, "POST_NOTIFICATIONS denied — incoming call UI blocked") + } + val wakeLock = (getSystemService(POWER_SERVICE) as? PowerManager) + ?.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "f7cloud:incoming_call") + ?.apply { acquire(30_000L) } + try { + val shown = F7IncomingCallQueue.enqueue( + context = this, + title = title, + body = body, + acceptUrl = data["acceptUrl"] ?: clickUrl, + roomToken = data["roomToken"], + roomDisplayName = data["roomDisplayName"], + ) + Log.i(TAG, "Incoming call enqueued: title=$title room=${data["roomToken"]} shown=$shown") + } catch (t: Throwable) { + Log.e(TAG, "Incoming call notification failed", t) + } finally { + wakeLock?.let { if (it.isHeld) it.release() } + } + return + } + + try { + if (!canPostNotifications()) { + Log.w(TAG, "POST_NOTIFICATIONS denied — message notification skipped") + return + } + F7PushNotificationHelper.show( + context = this, + title = title, + body = body, + openUrl = clickUrl, + highPriority = highPriority, + type = type, + channelHint = data["channel"], + roomToken = data["roomToken"], + messageId = data["messageId"], + ) + Log.i(TAG, "Message notification shown: $title") + } catch (t: Throwable) { + Log.e(TAG, "Message notification failed", t) + } + } + + private fun canPostNotifications(): Boolean { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + return true + } + return ContextCompat.checkSelfPermission( + this, + Manifest.permission.POST_NOTIFICATIONS, + ) == PackageManager.PERMISSION_GRANTED + } + + companion object { + private const val TAG = "F7Push" + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallQueue.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallQueue.kt new file mode 100644 index 0000000..9779983 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallQueue.kt @@ -0,0 +1,448 @@ +package ru.forbion.f7cloud.core.push + +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build +import android.util.Log +import androidx.core.app.NotificationCompat +import androidx.core.app.Person +import org.json.JSONArray +import org.json.JSONObject +import ru.forbion.f7cloud.core.auth.AuthStore + +/** + * Shows one incoming Talk call at a time; further calls wait in a FIFO queue. + */ +object F7IncomingCallQueue { + private const val TAG = "F7IncomingCallQueue" + private const val PREFS = "f7push_call_queue" + private const val KEY_QUEUE = "queue" + private const val KEY_ACTIVE_TOKEN = "active_token" + private const val KEY_ACTIVE_AT = "active_at" + const val ACTIVE_NOTIFICATION_ID = 5000 + private const val ACTIVE_RING_TTL_MS = 3 * 60 * 1000L + + private val lock = Any() + + fun enqueue( + context: Context, + title: String, + body: String, + acceptUrl: String?, + roomToken: String?, + roomDisplayName: String? = null, + ): Boolean { + val token = normalizeToken(roomToken, acceptUrl, title) + val displayName = TalkCallPushLabels.resolveRoomDisplayName(title, body, roomDisplayName) + synchronized(lock) { + val prefs = prefs(context) + expireStaleActiveLocked(prefs) + + val call = PendingCall(token, title, body, acceptUrl, displayName) + val active = prefs.getString(KEY_ACTIVE_TOKEN, "").orEmpty() + + if (token == active) { + // Duplicate FCM for the same room — refresh UI only, do not re-ring. + val shown = showNotification(context, call, waiting = 0, alert = false) + if (shown) { + touchActive(prefs) + } + return shown + } + + val queue = readQueue(prefs) + if (containsToken(queue, token)) { + return false + } + + if (active.isEmpty()) { + setActive(prefs, token) + val shown = showNotification(context, call, waiting = 0) + if (!shown) { + prefs.edit().remove(KEY_ACTIVE_TOKEN).remove(KEY_ACTIVE_AT).apply() + } + return shown + } + + queue.put(call.toJson()) + prefs.edit().putString(KEY_QUEUE, queue.toString()).apply() + Log.d(TAG, "Call queued: $token, queue size=${queue.length()}") + return false + } + } + + fun dismissAndShowNext(context: Context, roomToken: String?) { + synchronized(lock) { + val prefs = prefs(context) + val active = prefs.getString(KEY_ACTIVE_TOKEN, "").orEmpty() + var queue = readQueue(prefs) + + if (!roomToken.isNullOrBlank()) { + val token = roomToken.trim() + if (token != active) { + queue = removeToken(queue, token) + prefs.edit().putString(KEY_QUEUE, queue.toString()).apply() + return + } + } + + cancelNotification(context) + prefs.edit().remove(KEY_ACTIVE_TOKEN).remove(KEY_ACTIVE_AT).apply() + + if (queue.length() == 0) { + prefs.edit().remove(KEY_QUEUE).apply() + return + } + + runCatching { + val next = PendingCall.fromJson(queue.getJSONObject(0)) + val rest = JSONArray() + for (i in 1 until queue.length()) { + rest.put(queue.get(i)) + } + prefs.edit().putString(KEY_QUEUE, rest.toString()).apply() + if (showNotification(context, next, rest.length())) { + setActive(prefs, next.roomToken) + } + }.onFailure { + Log.w(TAG, "Failed to parse queued call", it) + prefs.edit().remove(KEY_QUEUE).apply() + } + } + } + + fun clearAll(context: Context) { + synchronized(lock) { + val prefs = prefs(context) + cancelNotification(context) + prefs.edit().remove(KEY_QUEUE).remove(KEY_ACTIVE_TOKEN).apply() + } + } + + private fun showNotification( + context: Context, + call: PendingCall, + waiting: Int, + alert: Boolean = true, + ): Boolean { + F7NotificationChannels.ensureAll(context) + val body = if (waiting > 0) { + call.body + "\n" + context.resources.getQuantityString( + R.plurals.call_queue_waiting, + waiting, + waiting, + ) + } else { + call.body + } + + val joinUrl = resolveJoinUrl(context, call) ?: run { + Log.w(TAG, "Cannot resolve join URL for call ${call.roomToken}") + return false + } + + val intents = buildPendingIntents(context, call, joinUrl) + if (alert) { + runCatching { F7IncomingCallRinger.start(context, call.roomToken) } + .onFailure { Log.w(TAG, "Ringtone start failed", it) } + } + + val posted = runCatching { + postCallStyleNotification(context, call, body, intents, alert) + }.onFailure { + Log.w(TAG, "CallStyle notification failed, using fallback", it) + }.isSuccess || runCatching { + postFallbackNotification(context, call, body, intents, alert) + }.onFailure { + Log.e(TAG, "Fallback call notification failed", it) + }.isSuccess + + if (!posted) { + F7IncomingCallRinger.stop() + } + return posted + } + + private data class CallPendingIntents( + val accept: PendingIntent, + val preview: PendingIntent, + val decline: PendingIntent, + val fullScreen: PendingIntent, + ) + + private fun buildPendingIntents( + context: Context, + call: PendingCall, + joinUrl: String, + ): CallPendingIntents { + val requestCode = ACTIVE_NOTIFICATION_ID + kotlin.math.abs(call.roomToken.hashCode() % 10000) + val accept = PendingIntent.getActivity( + context, + requestCode, + incomingCallIntent(context, call, joinUrl, autoAccept = true), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + val preview = PendingIntent.getActivity( + context, + requestCode + 50000, + incomingCallIntent(context, call, joinUrl, autoAccept = false), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + val declineIntent = Intent(context, F7CallActionReceiver::class.java).apply { + action = F7CallActionReceiver.ACTION_DECLINE + putExtra(F7CallActionReceiver.EXTRA_NOTIFICATION_ID, ACTIVE_NOTIFICATION_ID) + putExtra(F7CallActionReceiver.EXTRA_ROOM_TOKEN, call.roomToken) + } + val decline = PendingIntent.getBroadcast( + context, + ACTIVE_NOTIFICATION_ID + 1, + declineIntent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + val fullScreen = PendingIntent.getActivity( + context, + requestCode + 60000, + incomingCallIntent(context, call, joinUrl, autoAccept = false), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + return CallPendingIntents(accept, preview, decline, fullScreen) + } + + private fun postCallStyleNotification( + context: Context, + call: PendingCall, + body: String, + intents: CallPendingIntents, + alert: Boolean, + ) { + val caller = Person.Builder() + .setName(call.displayName.ifBlank { call.title.ifBlank { context.getString(R.string.incoming_call_subtitle) } }) + .build() + + val canFullScreen = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + context.getSystemService(NotificationManager::class.java) + ?.canUseFullScreenIntent() != false + } else { + true + } + + val callStyle = NotificationCompat.CallStyle.forIncomingCall( + caller, + intents.decline, + intents.accept, + ) + + val notification = NotificationCompat.Builder(context, F7NotificationChannels.CALLS) + .setSmallIcon(android.R.drawable.stat_sys_phone_call) + .setContentTitle(call.displayName.ifBlank { call.title }) + .setContentText(body) + .setStyle(callStyle) + .setCategory(NotificationCompat.CATEGORY_CALL) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setOngoing(true) + .setAutoCancel(false) + .setOnlyAlertOnce(true) + .setSound(null) + .setDefaults(0) + .setVibrate(null) + .setContentIntent(intents.preview) + .apply { + if (canFullScreen) { + setFullScreenIntent(intents.fullScreen, true) + } + } + .build() + + context.getSystemService(NotificationManager::class.java) + ?.notify(ACTIVE_NOTIFICATION_ID, notification) + ?: throw IllegalStateException("NotificationManager unavailable") + } + + private fun postFallbackNotification( + context: Context, + call: PendingCall, + body: String, + intents: CallPendingIntents, + alert: Boolean, + ) { + val canFullScreen = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + context.getSystemService(NotificationManager::class.java) + ?.canUseFullScreenIntent() != false + } else { + true + } + + val notification = NotificationCompat.Builder(context, F7NotificationChannels.CALLS) + .setSmallIcon(android.R.drawable.stat_sys_phone_call) + .setContentTitle(call.displayName.ifBlank { call.title }) + .setContentText(body) + .setStyle(NotificationCompat.BigTextStyle().bigText(body)) + .setCategory(NotificationCompat.CATEGORY_CALL) + .setPriority(NotificationCompat.PRIORITY_MAX) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setOngoing(true) + .setAutoCancel(false) + .setOnlyAlertOnce(true) + .setSound(null) + .setDefaults(0) + .setVibrate(null) + .setContentIntent(intents.preview) + .apply { + if (canFullScreen) { + setFullScreenIntent(intents.fullScreen, true) + } + } + .addAction(0, context.getString(R.string.call_action_accept), intents.accept) + .addAction(0, context.getString(R.string.call_action_decline), intents.decline) + .build() + + context.getSystemService(NotificationManager::class.java) + ?.notify(ACTIVE_NOTIFICATION_ID, notification) + ?: throw IllegalStateException("NotificationManager unavailable") + } + + private fun resolveJoinUrl(context: Context, call: PendingCall): String? { + val raw = call.acceptUrl?.takeIf { it.isNotBlank() } + ?: AuthStore(context).load()?.let { session -> + buildCallUrl(session.serverUrl, call.roomToken) + } + ?: return null + return stripDirectCallHash(raw) + } + + private fun buildCallUrl(serverBase: String, roomToken: String): String { + val base = serverBase.trimEnd('/') + return "$base/call/${roomToken.trim()}" + } + + private fun stripDirectCallHash(url: String): String { + val hash = url.indexOf('#') + return if (hash >= 0) url.substring(0, hash) else url + } + + private fun prefs(context: Context) = + context.applicationContext.getSharedPreferences(PREFS, Context.MODE_PRIVATE) + + private fun setActive(prefs: android.content.SharedPreferences, token: String) { + prefs.edit() + .putString(KEY_ACTIVE_TOKEN, token) + .putLong(KEY_ACTIVE_AT, System.currentTimeMillis()) + .apply() + } + + private fun touchActive(prefs: android.content.SharedPreferences) { + prefs.edit().putLong(KEY_ACTIVE_AT, System.currentTimeMillis()).apply() + } + + private fun expireStaleActiveLocked(prefs: android.content.SharedPreferences) { + val active = prefs.getString(KEY_ACTIVE_TOKEN, "").orEmpty() + if (active.isEmpty()) return + val activeAt = prefs.getLong(KEY_ACTIVE_AT, 0L) + if (activeAt <= 0L || System.currentTimeMillis() - activeAt > ACTIVE_RING_TTL_MS) { + Log.w(TAG, "Clearing stale active call: $active") + prefs.edit().remove(KEY_ACTIVE_TOKEN).remove(KEY_ACTIVE_AT).apply() + } + } + + private fun normalizeToken(roomToken: String?, acceptUrl: String?, fallback: String): String { + extractTokenFromUrl(acceptUrl)?.let { return it } + roomToken?.trim()?.takeIf { it.isNotBlank() }?.let { return it } + return "call:${kotlin.math.abs(fallback.hashCode())}" + } + + private fun extractTokenFromUrl(url: String?): String? { + if (url.isNullOrBlank()) return null + val path = runCatching { android.net.Uri.parse(url).path }.getOrNull() ?: url + val marker = "/call/" + val idx = path.indexOf(marker) + if (idx < 0) return null + val rest = path.substring(idx + marker.length) + val end = rest.indexOfFirst { it == '/' || it == '?' || it == '#' }.let { if (it < 0) rest.length else it } + return rest.substring(0, end).ifBlank { null } + } + + private fun cancelNotification(context: Context) { + F7IncomingCallRinger.stop() + context.getSystemService(NotificationManager::class.java) + ?.cancel(ACTIVE_NOTIFICATION_ID) + } + + private fun readQueue(prefs: android.content.SharedPreferences): JSONArray { + val raw = prefs.getString(KEY_QUEUE, "[]").orEmpty() + return runCatching { JSONArray(raw) }.getOrDefault(JSONArray()) + } + + private fun containsToken(queue: JSONArray, token: String): Boolean { + for (i in 0 until queue.length()) { + runCatching { + if (token == queue.getJSONObject(i).optString("roomToken")) return true + } + } + return false + } + + private fun removeToken(queue: JSONArray, token: String): JSONArray { + val next = JSONArray() + for (i in 0 until queue.length()) { + runCatching { + val item = queue.getJSONObject(i) + if (token != item.optString("roomToken")) { + next.put(item) + } + } + } + return next + } + + private data class PendingCall( + val roomToken: String, + val title: String, + val body: String, + val acceptUrl: String?, + val displayName: String, + ) { + fun toJson(): JSONObject = JSONObject().apply { + put("roomToken", roomToken) + put("title", title) + put("body", body) + put("displayName", displayName) + if (acceptUrl != null) put("acceptUrl", acceptUrl) + } + + companion object { + fun fromJson(o: JSONObject): PendingCall = PendingCall( + roomToken = o.getString("roomToken"), + title = o.optString("title", ""), + body = o.optString("body", ""), + acceptUrl = if (o.has("acceptUrl")) o.optString("acceptUrl") else null, + displayName = o.optString("displayName", ""), + ) + } + } + + private const val INCOMING_CALL_ACTIVITY = "ru.forbion.f7cloud.mobile.CallIncomingActivity" + + private fun incomingCallIntent( + context: Context, + call: PendingCall, + joinUrl: String, + autoAccept: Boolean, + ): Intent = Intent().apply { + setClassName(context, INCOMING_CALL_ACTIVITY) + action = PushIntents.ACTION_OPEN_CALL + addFlags( + Intent.FLAG_ACTIVITY_NEW_TASK or + Intent.FLAG_ACTIVITY_CLEAR_TOP or + Intent.FLAG_ACTIVITY_SINGLE_TOP, + ) + putExtra(PushIntents.EXTRA_ACCEPT_URL, joinUrl) + putExtra(PushIntents.EXTRA_ROOM_TOKEN, call.roomToken) + putExtra(PushIntents.EXTRA_CALL_TITLE, call.title) + putExtra(PushIntents.EXTRA_CALL_BODY, call.body) + putExtra(PushIntents.EXTRA_ROOM_DISPLAY_NAME, call.displayName) + putExtra(PushIntents.EXTRA_AUTO_ACCEPT, autoAccept) + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallRinger.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallRinger.kt new file mode 100644 index 0000000..b106806 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7IncomingCallRinger.kt @@ -0,0 +1,119 @@ +package ru.forbion.f7cloud.core.push + +import android.content.Context +import android.media.AudioAttributes +import android.media.MediaPlayer +import android.media.RingtoneManager +import android.util.Log + +/** + * Loops the default ringtone while an incoming call waits for Accept/Decline. + * Debounced per call token so duplicate FCM / notification updates do not restart audio. + */ +object F7IncomingCallRinger { + private const val TAG = "F7IncomingCallRinger" + private const val RING_PREFS = "f7_call_ring_guard" + private const val KEY_LAST_TOKEN = "last_token" + private const val KEY_LAST_AT = "last_at" + private const val RING_DEBOUNCE_MS = 90_000L + + private val lock = Any() + private var player: MediaPlayer? = null + private var ringing = false + private var activeToken: String? = null + + fun isPlaying(): Boolean = synchronized(lock) { + runCatching { player?.isPlaying == true }.getOrDefault(false) + } + + fun shouldAlert(context: Context, callToken: String): Boolean { + if (callToken.isBlank()) return false + synchronized(lock) { + if (runCatching { player?.isPlaying == true }.getOrDefault(false)) { + return false + } + val prefs = context.applicationContext.getSharedPreferences(RING_PREFS, Context.MODE_PRIVATE) + val now = System.currentTimeMillis() + val lastToken = prefs.getString(KEY_LAST_TOKEN, "").orEmpty() + val lastAt = prefs.getLong(KEY_LAST_AT, 0L) + if (callToken == lastToken && now - lastAt < RING_DEBOUNCE_MS) { + return false + } + prefs.edit() + .putString(KEY_LAST_TOKEN, callToken) + .putLong(KEY_LAST_AT, now) + .apply() + return true + } + } + + fun start(context: Context, callToken: String) { + if (!shouldAlert(context, callToken)) { + return + } + synchronized(lock) { + ringing = true + activeToken = callToken + stopLocked(keepFlag = true) + val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE) + if (uri == null) { + Log.w(TAG, "No default ringtone URI") + stopLocked() + return + } + val appContext = context.applicationContext + runCatching { + player = MediaPlayer().apply { + setDataSource(appContext, uri) + isLooping = true + setAudioAttributes( + AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build(), + ) + setOnPreparedListener { prepared -> + synchronized(lock) { + if (!ringing) { + runCatching { prepared.release() } + return@setOnPreparedListener + } + runCatching { prepared.start() } + .onFailure { + Log.w(TAG, "Ringtone start failed", it) + stopLocked() + } + } + } + setOnErrorListener { _, what, extra -> + Log.w(TAG, "Ringtone error what=$what extra=$extra") + synchronized(lock) { stopLocked() } + true + } + prepareAsync() + } + }.onFailure { + Log.w(TAG, "Ringtone prepare failed", it) + stopLocked() + } + } + } + + fun stop() { + synchronized(lock) { + stopLocked() + } + } + + private fun stopLocked(keepFlag: Boolean = false) { + if (!keepFlag) { + ringing = false + activeToken = null + } + player?.runCatching { + if (isPlaying) stop() + release() + } + player = null + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7NotificationChannels.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7NotificationChannels.kt new file mode 100644 index 0000000..ec4f94d --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7NotificationChannels.kt @@ -0,0 +1,72 @@ +package ru.forbion.f7cloud.core.push + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.media.AudioAttributes +import android.media.RingtoneManager +import android.os.Build + +object F7NotificationChannels { + const val MESSAGES = "f7_mobile_messages" + /** Silent channel: ringtone is played only by [F7IncomingCallRinger]. */ + const val CALLS = "f7_mobile_calls_v3" + + /** Channel IDs referenced in FCM payloads from f7push server (background tray). */ + private const val SERVER_MESSAGES = "f7cloud_messages_v2" + private const val SERVER_CALLS = "f7cloud_calls_v2" + + fun ensureAll(context: Context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return + val manager = context.getSystemService(NotificationManager::class.java) ?: return + val audio = AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build() + val notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) + val ringtoneAudio = AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build() + val ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE) + + fun create( + id: String, + name: String, + importance: Int, + vibration: LongArray, + sound: android.net.Uri?, + soundAttrs: AudioAttributes, + ) { + manager.createNotificationChannel( + NotificationChannel(id, name, importance).apply { + description = name + enableLights(true) + enableVibration(true) + vibrationPattern = vibration + if (sound != null) { + setSound(sound, soundAttrs) + } + setShowBadge(true) + lockscreenVisibility = android.app.Notification.VISIBILITY_PUBLIC + }, + ) + } + + val messagesName = context.getString(R.string.notification_channel_messages) + val callsName = context.getString(R.string.notification_channel_calls) + val msgVibration = longArrayOf(0, 250, 150, 250) + val callVibration = longArrayOf(0, 500, 200, 500) + + create(MESSAGES, messagesName, NotificationManager.IMPORTANCE_HIGH, msgVibration, notificationSound, audio) + create(SERVER_MESSAGES, messagesName, NotificationManager.IMPORTANCE_HIGH, msgVibration, notificationSound, audio) + create(CALLS, callsName, NotificationManager.IMPORTANCE_HIGH, longArrayOf(0), null, audio) + create(SERVER_CALLS, callsName, NotificationManager.IMPORTANCE_HIGH, longArrayOf(0), null, audio) + } + + fun resolveChannel(channelHint: String?, highPriority: Boolean): String { + if (channelHint == CALLS || channelHint == SERVER_CALLS) return CALLS + if (channelHint == MESSAGES || channelHint == SERVER_MESSAGES) return MESSAGES + return if (highPriority) CALLS else MESSAGES + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEvent.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEvent.kt new file mode 100644 index 0000000..3e10ab4 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEvent.kt @@ -0,0 +1,43 @@ +package ru.forbion.f7cloud.core.push + +sealed class F7PushEvent { + abstract val url: String? + + data class Call( + val title: String, + val body: String, + val roomToken: String?, + val acceptUrl: String?, + override val url: String?, + ) : F7PushEvent() + + data class Mail( + val title: String, + val body: String, + val mailboxId: Int?, + val messageId: Int?, + override val url: String?, + ) : F7PushEvent() + + data class Talk( + val title: String, + val body: String, + val roomToken: String?, + val messageId: Long?, + override val url: String?, + ) : F7PushEvent() + + data class Files( + val title: String, + val body: String, + val fileId: Long?, + override val url: String?, + ) : F7PushEvent() + + data class Notification( + val title: String, + val body: String, + val source: String?, + override val url: String?, + ) : F7PushEvent() +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventHub.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventHub.kt new file mode 100644 index 0000000..70601e1 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventHub.kt @@ -0,0 +1,17 @@ +package ru.forbion.f7cloud.core.push + +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow + +/** + * In-app bridge for FCM payloads — lets open screens refresh without waiting for user action. + */ +object F7PushEventHub { + private val _events = MutableSharedFlow(extraBufferCapacity = 32) + val events: SharedFlow = _events.asSharedFlow() + + fun publish(event: F7PushEvent) { + _events.tryEmit(event) + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventParser.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventParser.kt new file mode 100644 index 0000000..dd31f23 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushEventParser.kt @@ -0,0 +1,82 @@ +package ru.forbion.f7cloud.core.push + +object F7PushEventParser { + fun parse( + data: Map, + title: String, + body: String, + ): F7PushEvent { + val type = data["type"]?.lowercase() + val source = data["source"]?.lowercase() + val url = data["acceptUrl"] + ?: data["url"] + ?: data["clickUrl"] + ?: data["link"] + val lowerUrl = url?.lowercase().orEmpty() + + if (type == "call") { + return F7PushEvent.Call( + title = title, + body = body, + roomToken = data["roomToken"], + acceptUrl = data["acceptUrl"] ?: url, + url = url, + ) + } + + if (type == "mail" || source == "mail" || + lowerUrl.contains("/apps/f7mail") || lowerUrl.contains("/apps/mail") + ) { + return F7PushEvent.Mail( + title = title, + body = body, + mailboxId = data["mailboxId"]?.toIntOrNull() + ?: Regex("""/box/(\d+)""", RegexOption.IGNORE_CASE).find(lowerUrl) + ?.groupValues?.get(1)?.toIntOrNull(), + messageId = data["messageId"]?.toIntOrNull() + ?: Regex("""/thread/(\d+)""", RegexOption.IGNORE_CASE).find(lowerUrl) + ?.groupValues?.get(1)?.toIntOrNull(), + url = url, + ) + } + + if (type == "chat" || source == "spreed" || lowerUrl.contains("/apps/spreed")) { + val roomToken = data["roomToken"] + ?: extractTalkRoomToken(url) + val messageId = data["messageId"]?.toLongOrNull() + ?: Regex("""#message_(\d+)""").find(url.orEmpty())?.groupValues?.get(1)?.toLongOrNull() + return F7PushEvent.Talk( + title = title, + body = body, + roomToken = roomToken, + messageId = messageId, + url = url, + ) + } + + if (source == "files" || lowerUrl.contains("/apps/files") || lowerUrl.contains("/remote.php/dav/files")) { + return F7PushEvent.Files( + title = title, + body = body, + fileId = data["fileId"]?.toLongOrNull() + ?: Regex("""fileid=(\d+)""", RegexOption.IGNORE_CASE).find(lowerUrl) + ?.groupValues?.get(1)?.toLongOrNull(), + url = url, + ) + } + + return F7PushEvent.Notification( + title = title, + body = body, + source = source ?: data["source"], + url = url, + ) + } + + private fun extractTalkRoomToken(url: String?): String? { + if (url.isNullOrBlank()) return null + Regex("""/spreed/([a-z0-9]+)""", RegexOption.IGNORE_CASE).find(url)?.groupValues?.get(1)?.let { return it } + Regex("""/call/([a-z0-9]+)""", RegexOption.IGNORE_CASE).find(url)?.groupValues?.get(1)?.let { return it } + return null + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushIntentExtras.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushIntentExtras.kt new file mode 100644 index 0000000..677d240 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushIntentExtras.kt @@ -0,0 +1,49 @@ +package ru.forbion.f7cloud.core.push + +import android.content.Intent +import android.os.Bundle + +object F7PushIntentExtras { + fun dataMap(extras: Bundle?): Map { + if (extras == null) return emptyMap() + return buildMap { + for (key in extras.keySet()) { + if (key.startsWith("google.") || key == "from" || key == "collapse_key") continue + extras.getString(key)?.takeIf { it.isNotBlank() }?.let { put(key, it) } + } + } + } + + fun resolveOpenUrl(intent: Intent?): String? { + if (intent == null) return null + intent.getStringExtra(PushIntents.EXTRA_OPEN_URL)?.takeIf { it.isNotBlank() }?.let { return it } + val data = dataMap(intent.extras) + return data["acceptUrl"] + ?: data["url"] + ?: data["clickUrl"] + ?: data["link"] + } + + fun resolveRoomToken(intent: Intent?): String? { + intent?.getStringExtra(PushIntents.EXTRA_ROOM_TOKEN)?.takeIf { it.isNotBlank() }?.let { return it } + return dataMap(intent?.extras)["roomToken"] + } + + fun resolveMessageId(intent: Intent?): String? { + intent?.getStringExtra(PushIntents.EXTRA_MESSAGE_ID)?.takeIf { it.isNotBlank() }?.let { return it } + return dataMap(intent?.extras)["messageId"] + } + + fun publishEventFromIntent(intent: Intent?) { + val data = dataMap(intent?.extras) + if (data.isEmpty()) return + val title = data["title"] ?: "F7cloud" + val body = data["body"] ?: "" + F7PushEventHub.publish(F7PushEventParser.parse(data, title, body)) + } + + fun isFcmLaunch(intent: Intent?): Boolean { + val extras = intent?.extras ?: return false + return extras.containsKey("google.message_id") || dataMap(extras).isNotEmpty() + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushNotificationHelper.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushNotificationHelper.kt new file mode 100644 index 0000000..b5235f7 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushNotificationHelper.kt @@ -0,0 +1,63 @@ +package ru.forbion.f7cloud.core.push + +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import androidx.core.app.NotificationCompat + +object F7PushNotificationHelper { + fun show( + context: Context, + title: String, + body: String, + openUrl: String?, + highPriority: Boolean, + type: String?, + channelHint: String? = null, + roomToken: String? = null, + messageId: String? = null, + ) { + F7NotificationChannels.ensureAll(context) + val manager = context.getSystemService(NotificationManager::class.java) ?: return + val launch = context.packageManager.getLaunchIntentForPackage(context.packageName) + val pending = if (launch != null) { + val intent = Intent(launch) + if (!openUrl.isNullOrBlank()) { + intent.putExtra(PushIntents.EXTRA_OPEN_URL, openUrl) + } + if (!roomToken.isNullOrBlank()) { + intent.putExtra(PushIntents.EXTRA_ROOM_TOKEN, roomToken) + } + if (!messageId.isNullOrBlank()) { + intent.putExtra(PushIntents.EXTRA_MESSAGE_ID, messageId) + } + PendingIntent.getActivity( + context, + 1001, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, + ) + } else { + null + } + val channel = F7NotificationChannels.resolveChannel(channelHint, highPriority || type == "call") + val priority = if (channel == F7NotificationChannels.CALLS) { + NotificationCompat.PRIORITY_HIGH + } else { + NotificationCompat.PRIORITY_DEFAULT + } + val iconRes = context.applicationInfo.icon.takeIf { it != 0 } + ?: android.R.drawable.stat_notify_chat + val notification = NotificationCompat.Builder(context, channel) + .setSmallIcon(iconRes) + .setContentTitle(title) + .setContentText(body) + .setStyle(NotificationCompat.BigTextStyle().bigText(body)) + .setAutoCancel(true) + .setPriority(priority) + .setContentIntent(pending) + .build() + manager.notify((System.currentTimeMillis() % Int.MAX_VALUE).toInt(), notification) + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushRegistrar.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushRegistrar.kt new file mode 100644 index 0000000..6d98c89 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/F7PushRegistrar.kt @@ -0,0 +1,90 @@ +package ru.forbion.f7cloud.core.push + +import android.content.Context +import android.util.Log +import org.json.JSONObject +import ru.forbion.f7cloud.core.auth.AuthSession +import java.io.BufferedReader +import java.io.InputStream +import java.io.InputStreamReader +import java.io.OutputStream +import java.net.HttpURLConnection +import java.net.URL +import java.nio.charset.StandardCharsets +import java.util.UUID + +object F7PushRegistrar { + private const val TAG = "F7PushRegistrar" + private const val PREFS = "f7push" + private const val KEY_DEVICE_ID = "device_id" + + fun getDeviceId(context: Context): String { + val prefs = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE) + val existing = prefs.getString(KEY_DEVICE_ID, null) + if (!existing.isNullOrBlank()) { + return existing + } + val id = UUID.randomUUID().toString() + prefs.edit().putString(KEY_DEVICE_ID, id).apply() + return id + } + + fun registerBlocking( + context: Context, + session: AuthSession, + fcmToken: String, + ): Int { + val endpoint = session.serverUrl.trimEnd('/') + "/ocs/v2.php/apps/f7push/api/v1/devices" + val body = JSONObject() + .put("deviceId", getDeviceId(context)) + .put("fcmToken", fcmToken) + .put("platform", "android") + .put("clientApp", "f7cloud-mobile") + .toString() + return try { + postJson(endpoint, session, body) + } catch (t: Throwable) { + Log.w(TAG, "register failed", t) + 0 + } + } + + private fun postJson(endpoint: String, session: AuthSession, json: String): Int { + val conn = URL(endpoint).openConnection() as HttpURLConnection + conn.connectTimeout = 15000 + conn.readTimeout = 15000 + conn.requestMethod = "POST" + conn.doOutput = true + conn.setRequestProperty("Content-Type", "application/json; charset=utf-8") + conn.setRequestProperty("Accept", "application/json") + conn.setRequestProperty("OCS-APIRequest", "true") + val basic = android.util.Base64.encodeToString( + "${session.username}:${session.appPassword}".toByteArray(StandardCharsets.UTF_8), + android.util.Base64.NO_WRAP + ) + conn.setRequestProperty("Authorization", "Basic $basic") + + val payload = json.toByteArray(StandardCharsets.UTF_8) + conn.setFixedLengthStreamingMode(payload.size) + val out: OutputStream = conn.outputStream + out.write(payload) + out.close() + + val code = conn.responseCode + drainQuietly(if (code >= 400) conn.errorStream else conn.inputStream) + conn.disconnect() + return code + } + + private fun drainQuietly(stream: InputStream?) { + if (stream == null) return + try { + BufferedReader(InputStreamReader(stream, StandardCharsets.UTF_8)).use { reader -> + while (reader.readLine() != null) { + // no-op + } + } + } catch (_: Exception) { + } + } +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/PushIntents.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/PushIntents.kt new file mode 100644 index 0000000..e7ba203 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/PushIntents.kt @@ -0,0 +1,13 @@ +package ru.forbion.f7cloud.core.push + +object PushIntents { + const val EXTRA_OPEN_URL = "ru.forbion.f7cloud.mobile.OPEN_URL" + const val ACTION_OPEN_CALL = "ru.forbion.f7cloud.action.OPEN_CALL" + const val EXTRA_ACCEPT_URL = "ru.forbion.f7cloud.mobile.ACCEPT_URL" + const val EXTRA_ROOM_TOKEN = "ru.forbion.f7cloud.mobile.ROOM_TOKEN" + const val EXTRA_MESSAGE_ID = "ru.forbion.f7cloud.mobile.MESSAGE_ID" + const val EXTRA_AUTO_ACCEPT = "ru.forbion.f7cloud.mobile.AUTO_ACCEPT" + const val EXTRA_CALL_TITLE = "ru.forbion.f7cloud.mobile.CALL_TITLE" + const val EXTRA_CALL_BODY = "ru.forbion.f7cloud.mobile.CALL_BODY" + const val EXTRA_ROOM_DISPLAY_NAME = "ru.forbion.f7cloud.mobile.ROOM_DISPLAY_NAME" +} diff --git a/core/push/src/main/java/ru/forbion/f7cloud/core/push/TalkCallPushLabels.kt b/core/push/src/main/java/ru/forbion/f7cloud/core/push/TalkCallPushLabels.kt new file mode 100644 index 0000000..f385d36 --- /dev/null +++ b/core/push/src/main/java/ru/forbion/f7cloud/core/push/TalkCallPushLabels.kt @@ -0,0 +1,32 @@ +package ru.forbion.f7cloud.core.push + +object TalkCallPushLabels { + private val ROOM_IN_TITLE = Regex( + """(?i)(?:incoming call in|group call (?:has )?started in|входящий звонок в|групповой звонок.*?в)\s+(.+)$""", + ) + + fun resolveRoomDisplayName( + title: String, + body: String, + roomDisplayName: String?, + ): String { + roomDisplayName?.trim()?.takeIf { it.isNotBlank() }?.let { return it } + + val trimmedTitle = title.trim() + ROOM_IN_TITLE.find(trimmedTitle)?.groupValues?.getOrNull(1) + ?.trim() + ?.takeIf { it.isNotBlank() } + ?.let { return it } + + if (trimmedTitle.isNotBlank() && !trimmedTitle.equals("call", ignoreCase = true)) { + return trimmedTitle + } + + val trimmedBody = body.trim() + if (trimmedBody.isNotBlank() && !trimmedBody.equals("call", ignoreCase = true)) { + return trimmedBody + } + + return "Звонок" + } +} diff --git a/core/push/src/main/res/values/strings.xml b/core/push/src/main/res/values/strings.xml new file mode 100644 index 0000000..9332134 --- /dev/null +++ b/core/push/src/main/res/values/strings.xml @@ -0,0 +1,14 @@ + + + F7cloud сообщения + F7cloud звонки + Принять + Отклонить + F7cloud звонок + + Ещё %d звонок в очереди + Ещё %d звонка в очереди + Ещё %d звонков в очереди + Ещё %d звонков в очереди + + diff --git a/core/ui/build.gradle b/core/ui/build.gradle new file mode 100644 index 0000000..59a20ef --- /dev/null +++ b/core/ui/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'java-library' +} diff --git a/design/README.md b/design/README.md new file mode 100644 index 0000000..046f7ea --- /dev/null +++ b/design/README.md @@ -0,0 +1,66 @@ +# Дизайн мобильного приложения (F7cloud) + +Папка для макетов из Figma и материалов для вёрстки APK. +Файлы лежат в репозитории — не нужно прикладывать их в чат. + +**Figma:** [Forbion — облачное рабочее место](https://www.figma.com/design/ocVUCYCrfFUoqYYvlcLPBF/Forbion-%D0%BE%D0%B1%D0%BB%D0%B0%D1%87%D0%BD%D0%BE%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%87%D0%B5%D0%B5-%D0%BC%D0%B5%D1%81%D1%82%D0%BE?node-id=1-90) + +## Структура + +| Папка | Что класть | Формат | +|-------|------------|--------| +| `screens/` | Целые экраны (фреймы Mobile) | PNG @2x | +| `icons/` | Иконки, которые нет на сервере | SVG (лучше) или PNG @2x/@3x | +| `tokens/` | Цвета, шрифты, радиусы, отступы | `.txt`, `.json` или скрин | +| `references/` | Ссылки на фреймы, PDF, заметки | `.md`, `.pdf` | + +## Именование файлов + +Используйте латиницу и дефисы, например: + +``` +screens/menu.png +screens/mail-list.png +screens/mail-detail.png +screens/files-list.png +icons/bottom-bar-chats.svg +tokens/colors.txt +tokens/typography.txt +references/figma-links.md +``` + +## Экспорт из Figma (кратко) + +1. Выделить **Frame** мобильного экрана (не группу внутри). +2. Справа **Export** → **+** → **PNG** → **2x** → **Export**. +3. Сохранить в нужную подпапку. + +Иконки: выделить слой → Export → **SVG**. + +## Токены (пример `tokens/colors.txt`) + +``` +Primary: #70B62B +Background: #FBFBFB +Surface: #FFFFFF +Text primary: #151515 +Text secondary:#808080 +Border: #E6E6E6 +``` + +## Ссылки на фреймы + +Добавляйте в `references/figma-links.md` — **Copy link to selection** в Figma. + +## Приоритет экранов (редактируйте по мере работы) + +- [ ] Меню приложений +- [ ] Почта — список +- [ ] Почта — просмотр письма +- [ ] Файлы +- [ ] Нижняя панель (bottom bar) +- [ ] Вход / логин + +## Код + +Реализация в коде: `core/designsystem/`, экраны — `feature/*/`. diff --git a/design/icons/.gitkeep b/design/icons/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/design/icons/.gitkeep @@ -0,0 +1 @@ + diff --git a/design/references/figma-links.md b/design/references/figma-links.md new file mode 100644 index 0000000..dc0dbba --- /dev/null +++ b/design/references/figma-links.md @@ -0,0 +1,10 @@ +# Ссылки на фреймы Figma (mobile) + +Файл: [Forbion — облачное рабочее место](https://www.figma.com/design/ocVUCYCrfFUoqYYvlcLPBF/Forbion-%D0%BE%D0%B1%D0%BB%D0%B0%D1%87%D0%BD%D0%BE%D0%B5-%D1%80%D0%B0%D0%B1%D0%BE%D1%87%D0%B5%D0%B5-%D0%BC%D0%B5%D1%81%D1%82%D0%BE?node-id=1-90) + +Добавляйте ссылки: выделить фрейм → правый клик → **Copy link to selection**. + +| Экран | Ссылка | Экспорт в `screens/` | +|-------|--------|----------------------| +| (пример) Меню | | `menu.png` | +| | | | diff --git a/design/screens/.gitkeep b/design/screens/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/design/screens/.gitkeep @@ -0,0 +1 @@ + diff --git a/design/screens/ico/Ellipse 14.svg b/design/screens/ico/Ellipse 14.svg new file mode 100644 index 0000000..43d1b60 --- /dev/null +++ b/design/screens/ico/Ellipse 14.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/Size=45, Name=Карточки.svg b/design/screens/ico/Size=45, Name=Карточки.svg new file mode 100644 index 0000000..68af341 --- /dev/null +++ b/design/screens/ico/Size=45, Name=Карточки.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/Vector 181.svg b/design/screens/ico/Vector 181.svg new file mode 100644 index 0000000..7c55131 --- /dev/null +++ b/design/screens/ico/Vector 181.svg @@ -0,0 +1,3 @@ + + + diff --git a/design/screens/ico/icon/35/Archive Zip rar.svg b/design/screens/ico/icon/35/Archive Zip rar.svg new file mode 100644 index 0000000..7def58b --- /dev/null +++ b/design/screens/ico/icon/35/Archive Zip rar.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Audio.svg b/design/screens/ico/icon/35/Audio.svg new file mode 100644 index 0000000..36dc462 --- /dev/null +++ b/design/screens/ico/icon/35/Audio.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Calendar.svg b/design/screens/ico/icon/35/Calendar.svg new file mode 100644 index 0000000..5f88296 --- /dev/null +++ b/design/screens/ico/icon/35/Calendar.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Certificate.svg b/design/screens/ico/icon/35/Certificate.svg new file mode 100644 index 0000000..55bb02b --- /dev/null +++ b/design/screens/ico/icon/35/Certificate.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Code.svg b/design/screens/ico/icon/35/Code.svg new file mode 100644 index 0000000..3c7b627 --- /dev/null +++ b/design/screens/ico/icon/35/Code.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Eml.svg b/design/screens/ico/icon/35/Eml.svg new file mode 100644 index 0000000..3cfeaec --- /dev/null +++ b/design/screens/ico/icon/35/Eml.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Image.svg b/design/screens/ico/icon/35/Image.svg new file mode 100644 index 0000000..a40848c --- /dev/null +++ b/design/screens/ico/icon/35/Image.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/No name.svg b/design/screens/ico/icon/35/No name.svg new file mode 100644 index 0000000..1eca373 --- /dev/null +++ b/design/screens/ico/icon/35/No name.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/PDF.svg b/design/screens/ico/icon/35/PDF.svg new file mode 100644 index 0000000..a46f9a9 --- /dev/null +++ b/design/screens/ico/icon/35/PDF.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Presentation.svg b/design/screens/ico/icon/35/Presentation.svg new file mode 100644 index 0000000..5a52f52 --- /dev/null +++ b/design/screens/ico/icon/35/Presentation.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Spreadsheet.svg b/design/screens/ico/icon/35/Spreadsheet.svg new file mode 100644 index 0000000..05562b3 --- /dev/null +++ b/design/screens/ico/icon/35/Spreadsheet.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Text.svg b/design/screens/ico/icon/35/Text.svg new file mode 100644 index 0000000..e09264f --- /dev/null +++ b/design/screens/ico/icon/35/Text.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Video.svg b/design/screens/ico/icon/35/Video.svg new file mode 100644 index 0000000..fd94385 --- /dev/null +++ b/design/screens/ico/icon/35/Video.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Word.svg b/design/screens/ico/icon/35/Word.svg new file mode 100644 index 0000000..0681f5c --- /dev/null +++ b/design/screens/ico/icon/35/Word.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/Колокол c оповещениями.svg b/design/screens/ico/icon/35/Колокол c оповещениями.svg new file mode 100644 index 0000000..c19b69a --- /dev/null +++ b/design/screens/ico/icon/35/Колокол c оповещениями.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/icon/35/колокол.svg b/design/screens/ico/icon/35/колокол.svg new file mode 100644 index 0000000..5ab54c3 --- /dev/null +++ b/design/screens/ico/icon/35/колокол.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/Вайд борд.svg b/design/screens/ico/Вайд борд.svg new file mode 100644 index 0000000..fd73254 --- /dev/null +++ b/design/screens/ico/Вайд борд.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/design/screens/ico/Карточки.svg b/design/screens/ico/Карточки.svg new file mode 100644 index 0000000..56d85e1 --- /dev/null +++ b/design/screens/ico/Карточки.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/design/screens/mail/Заполненное.png b/design/screens/mail/Заполненное.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0a305fb96f900b1f0111fe2fe6fb2ccb1f1804 GIT binary patch literal 31544 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 s))ESvC{|0=Lyd(Pf)&u;uA z7)TDw#4eAh>7{TCCoP-HvBFrw@8IzXMV-aLwsrbr6d6Ez9eSf!?|!tFmE}VwxdtB3 z&XZ&U;~Pta&C?pjl3dtK6tOzMBP?qc`S{^mQw~ws$5bR##i^_}^J&~>O%#d!a?iDnouccT6A8Uynhp=q1}UApyf;R1 zHhxGdC-VIiCwL<^3dfogt(2_ypf=B{dQY&iNQ0;#L+4aERgfAW;W_bit%3y`Fpv4& zhtPji%Dq<8sY0FR=-tODE7wOt=>&hqysJg_3+(&e{I(nWI4J_Eqveb|?ip0ULi@dk zW1vla->K{c>;oxn57C#++RdIOpFBz}0lPa4^P>wD#d*L~VqlHB!Py<5jcaHVF!Oul zK1DxcG+;Dr5A#48oWw~jMv~wR!8#()+cBiKUs^4oGkz4;9;lLLqtJu)Uh*+AfGzECR28> z$PeP5&M&%zHIBRs7)1gLo&x<9SC6W$wAXC_@A@3{O8>6^bG;Rjmtme?JzH(EgHD6K zv*|azsd}Ed#2oXCml2*i8*P>SAz&^;DJDi^#d%k4Gv?36fu$?YHkO3YeUd7F=ovfr z8jW-ht(G7#4;sLtQ{5k113KEKli+9!&t>VOG~UH%M@)3c+(&mmv?rBQaNBBRc6s3T z*%lP7=EArdx$~Q924MJfg7qhQo-bbb*?>{IWc%_x`Xjx4zsYz}ClmE*m>SLjgUmo-yT%Rv^o5GY=n%l)(#f6WQ3ZtuezS7zpC#YtYwW6xf z|A0cifrW+fqDNq9ej03#h8Lc%+LitWA#Xlo2i>Y$V8c;zd50GK$L)Is-D+d|5os+O zT^~U&>Hg@#PDBN$urCO6SQj!#_O>^cmIchTR~8VjCs2HP;r?li`jx+O7m<+|YEhe{ z#Buy;l3!tTPlB`*q^4t7mwWv0f}x>oWBWY^ItwBz3L`s9X;nwEHMH}e_QgLzb+(_0 z!9a?MD`3{IWXh$2xy&QPEtT}a=j3ww%!}2iu!$Jqb+Vj4az&qQz^joYq1qxcj4?Ri zk~cFljOAW0(ktRrDfT2^8SJ~!rx{wWlTJ07<-k6S{49&}_6?Fr(-ksP+Ln6fG|<$v zN%DcnA{bdz%A>-e=B~;i@nG*U@PNi$R|p8edNCH2_XFuVqAR`mx^y92^cP- z>CE-!x#|Q0=s$@ux7e>2A_Xh{KD;49g=uyQ2Vfu=DJK=lyjS}4uUEK#MoI0I+Yjmx z>G^lf4BI;)cPPg2@TvY>p)FlDVX0^27cT2nEPcbh8Ss$q542akEJwT`5iY4IN16hd1+;-^7o$t{twi0 BLsW&_k&YlGG$~2w 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

-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 R!S+cWyBiLFG+g&h{vVsG^ydHo literal 0 HcmV?d00001 diff --git a/design/screens/mail/Параметры учётной записи.png b/design/screens/mail/Параметры учётной записи.png new file mode 100644 index 0000000000000000000000000000000000000000..f67796eb9d9b3e2c0fb88eaf871950be0481b1ac GIT binary patch literal 204274 zcmdpcRZv_}*CiUaCbuEuEE_QxVyVMjnj=Yo$s%j znyH$HssCXf=AlpDbNkAX-FvUK_6}82kjB9z$3#Ftz>$^tqJn^cXbC?gLVpE6gLy~P z4*$Zim(lu(fPh8#?}Lbtl12(YiTG1RS{$K#jPelPL9q~%7ehd(ipF|0LWTEnog_7# zRPD^2Kt_&c2vSxSK%IO$CPAbI&~;;9tL5m{n#(U~@L$YirgW|0li z27Cj(qMPx;;{KBS?{;UkBD$&DYl(3r`HEzG@k?dkiFBUFYfA_nI$gj{EPI?oLF?G!Xsg ziUherdOf}{|1E%*R*Os7is#j+m&;qSiW_n&y3ySGjIh77pNi`h{=cbu)WeX6F^|2Z(x{q^Lf5g zXdJxGUhQUSLXvmL(En@lyzldD(RB2uB;Xrm=JR#oF8j+R`=PQTLs*}TG-^tAr+o9DL{UU}V`stq;!hpx~?l=2kzFxjwehVVW)H_zT z;b`(_Zug?&O-mE;8TviqRIEs=#|)vSj=o7(4{I>tu%ErYGB3CNBIe)R$q^iaWOM)> z0z9G2$tfE_w7pIDhBQV7vBio`uYt#6(;gYrw6zYmo55JgfXDm!4)Y=ta(ws6R1k!`-9`;sDHd(Pm;T**H^f|#z}s;*>bPJOJm|6hpbvXupt%bXq;*GJ zJ~r!-B+;9xrbZiFw8%`)Kdejp;|H>i8I=7FTg`kv%xu2;u?%eZ{cq{1fc{q}B?eD_ z1i@8Q!UGalo$HF;m+_ZvXI_fUM%_U;j>D`CjT}1^ytWD6V$`nc8)zc8zQZ1^O7a<2 zK5952SN!{F+wGaob6VvZPfPRd@7G_RVY{7ZGzkx99qY$dRb1=P`i5Qi1$N0 z#zvPI$LyCyKmW*Y3V-f5!iaVi#;DTfNenz4t|@EpME_oN-g#~Yk~BwUQN3KyywG_- z>cA)M52v=vIh+EB+P(@qk-Td$f@iI&3Id03$?&oU8;vxre4iipMb4g$gT=EDzYu3| z<6^RCu#*ZRZ-u>jT0QfgcMJ`niteWlkMWyoNYIMK(0V9jHm);e!T;*7>`Z$K^@&RS()bbs>3+e@`$lai# zqXfm7+qlOLv%y^$;YIPsi4e26!ND(Qf@#t2l2~YH)Ii=UL}LMvAWfaOG^ zr78MP{afT^(N+w)bb<^p7)AotK`&`>N_^VK_R8Zz`jyqaVyMf@BU$@}$9r_ODC8 zt5#D!rQ3x{w6P~!X~zh(Rq3%!f(hemWa!{i{2N*rS| zH?WjIySqSSiSX@)|L&wT4H4(v-#1$R2>X#4iuRU$-Lai+5ssN2r%fmA(Wv|HTCLL> zR{2b~d#OE6=(an*74sd)cT->-cp-|DyO5n;AMN7fa>@r&^UV>^srlhad3_^^?W1&E ze}*;$eiN=ddxbbg(U$4|^H2Pyjak-yp@2T0qC>pm_BbDV3nGVc#CPg1X#M~KA1Sg2 z`1Jp7kAKYBuo838R*qGzV%EQYHb?9gVqBaZ3~%xBJ6FvyLYy1+T-a-_WediALEh zkiCPJF9qhu^7=w)yi(&5zwjFlJA~mFG!$W;9ovt{4#H2@)BLcFx5&}1inA20d^GT3 zWXk{LUzF1{*-r;0u0QVaD&!H6vzjzg)uKR+umxJLE?R@PjVDx$;G2AnPcuDCm$m&{ z;ty%bA9^3Cg^!ePhN&U_qL?qm`MIud5Dstv&m`J+ZM{k((`^}qHRiAq(F1*onB#lC z-Cmsza5dbGk-&`wwQf^Q;kknQypmkiepX_V6n+20&kVN-jG+GNt} z2~{dq+Vx#+zEKe(-J(6k{VX-~X+;@l=4SyPq5DJ+2I8rw&;4{JF=rJ#fEbUxu|PTy zBgAu^et8^!87ai+Cs@Jz%V*&f^TymbTQvT|@myKF&kM{4G|gi49uJ*2Q;C^2?UFq_ zoDEQcRwk93JgSsa}%F9r@QrZ6fn zuP^#(&dT~7(fJZ-Kr0R^#BVI&;01wbO(_rU-Po^xPoa7p#!Z^Qhm6Th7vLl|5>Fk# zhrIUoZ9oj0>@@d%n+<%S#brnql4_n`ZANx;W{JYP!8@z?lnFAbS#ZFEeA&Zq=Oj(0 z^sj>h37XQ1%@72YQ}F7&`u8#`5Q? zBoLR8%>MV(|JlY{bv8R6oA!ngE!uhZbBg~Nsio+3fG%2iF#ezh>pF%~x^DQ27rf$K z_pC|#ImYj}9mzWc|Ch5#Q#mK3f!5qkRf*cK($5C;K&$UG^xg6wyx_rgU{=EbV)K4F z-imR84^h2bcaevxt)#ejt2f;2a4H}EDuY_fSTzhMN_;B>kICXR&&xsa0`_U!B&t_2 z5?LIqI0_-HH|N?>!uOVRrhv}b)z9;~+mr#wxO}2xfU9qG(9XE42tB!d>hk5bZmp!r}z?ocWncdoHg{vvRAMhT=IQzK7XblOiPc6q#H8uNR$I^bs zg`nyUD{YF}wi)OryE>|4qmIOExBcwhoka^E7A&4xaDm1iGbVbK7-Dwpc+pD&Qp>Ew z&XXW(uIPqNbG!8;TY|nFc(eYoTjMZ{2C+z|pR^yp8)w1;92{QrpHy~F!3~e&Uu@TC ze2x-4weQGu+e^Ndpt+CH2^wGXI7|0>>Gye*w$ovGI1d&%Nwg+^YJGy(f!wULQ~UPF z3LXl5?h9E)ODfuzj4MX_*+#sxA|RLx=;l;M&z?>tR7^^|jkRMD5A`jWorCPVRnxWNJT+&x+TlpX`9_ zVfK#J-s3Ji-JC8gaZ*XUubqN_alWEP`)^&|K$qduZa?qBIt}`sq~MDK)^{&%_{JVA zv5~LqG$}d8An{yDVn*xJ!}rl53yK#h=>Og5|@b}dWUO(=UYL6LMZ*KDGb)FcRJIkR%UjM5oWY0?7=+Bgd=Z3LT z+iS!N#m@bV#JJdlf-Vk3zbI-KGAqT#u@a(zY^~>AU4Y4`X`&#$r7U`j&Oro+Uf)2u zy>mzG!<)<3Xgs)mgbI9}>81DrdC`&7e>qp`q?_?~g5xoa5UKS12uab}T<9?q{V8l4 z>1vRzVnl|5KNV4h=?9r;Wgsj)8lp|*=nvr08z~yI=(Kw_$yH=3h%M*fT4Dhi+nSck z_>SLwuCKY!)zy~BQxv+HDV3;uz#g73Urj8`+V(rAQ(U%P01c4%1q$?u8*Kb3DIco0 z<2{m*_F8DBv!lQi)ngqX0X`HfdJREJDl^dEEj(FCIJj8``$259i41G2PLcD(S^&@m zlR%jJWz@wX5^6KDz2QbcXD3PpR!&*XhaTJ%rHGm1ZrNx;jX(m%SHkW{OQa?rT+ff} zE4xyEZJ1D`{pB09zbvBCEazy~{PtZ@+gh5j=L>NM-75jWNX8Dn#&FYq2J?QVPrDP+ zQ5d95v;BYQczJSJax{NU}TyIC(FzZ~U`AL8`gcvIJ?OKV^ zb-_~6ri98?@H$DnN5%ZCK0F2U5B9_mZF%aOu zqLd|z#domz4(UeUA7((DNN{9(y6_~;v=Qf0eJx3LLT{j?Y|TtdIOGKrB?+w)^1Qq-8~Esk z*L>npF`X#zRl7SQDg(XjQ6;i2Q9kWW7Td!YJ`~Ym&b2}^_^$VtGzv$bS#e*l1fo&} z`Yywq#vGMh+I5wC@uy(Co1)-?T;i^hV3z|Pa%sub0AS$yL1j!upSw{okpfG%orjy= zs}IZi9EO?nx;Y2le=k3!5A$ymyET9%dnd?40<2oB(@+=#VId(BvvfzLM}G5-4a`~!!A z=t}2YRRiAzw=Guo7hx6+M9cl{YPbec z3oUn%oPHY%dG4$e4`7n1NJPQVh9-*Y^i3^EIY0??BC+ttc{0_$>SEz3XN?Amc$9Tv z+D2Bwd&shM;ZoyMDYA*WTs2;gP02_a>3_c!HalMM~!?qQo0_(+dXv4 z#zlD!>JQu-MC<)90qpF|=QXg;K}@?oUvdgj|1g2C6w>UDt%+7ONvJ4fxTqkt&PGF;RBgr;`dDL?!k&kmX}b z%wKel?(s^&zK7^Ir4%#%cyQA!dk_=zFibKo72^If$%M~KX~&mnY=+<@dM;xWJV$e^ zOzbVe=Uk-U;53z;1%X^xMrSTuEC3ll|K5!FNRcuH3qu?7$6@Dkr z#=a1@Cbemgy^}8rt(5f?VI^FyJ&~eGC5RM{apb7L7%<82vEobd5z~+C_862lONfpyYU5yDU z>bq_RCgLR$!jW&33gE!I5e~@GU^wiaaMZ_!;@45-6fJyT^w2X^rq`lw+q9dQ2q9+I zXF;QOHI&Pc2?rVy+2&9J^c&GJ5b3|CT^6rY8J2VUg~fsO$4|vsOLK*79vk2&T*b@_3bdNUIX!7JN8Y zro*_O_EVvj(&lG34zDW`s1ucBVCXkm(DmY1~T?luXfa@avu&zM7*>K_@oQkt@h^L~{&6;#c zIf&BIHRC5z*tII3w!!q9;84R9wh98#=dV>3`1e2FZbu8ocA<5JIN>v3^-Kn7jPY$_ zGgjkQ;k$xAP|$<`(Z3k<-aVc9bjX1oAPp@sk(j*CiHMiV4r4la9Jt`#BT4jR@^2w% zI7Ur-Db_2XlPYY_(>n8on-H=;l~DZcp(Dm@M!weuHJWGXmm*qoIl6`&7LOT{3tY~x46 zt4F`Vru*x5VTMrk-B)UjM-5>U%kJJ;yS*TM)pD2+w6G$-fGm!c9ehCSOxjreO9C*rsnx$2@Zx=UHh85UQTOnP6-ju*)+@kx*@EQI@jMS*VGCA&hng{eax7j%7n4+8N&a-0A_+7Jq|@(hKSn_|0je0d05 z@g40Az3Rd|K&Q1K1xJ30kfc#REcArCiUbUw849P5u7s=+*@lGT1GL2fXhIpZo`~6_ zEi=;SDEa~>bpbJ<=1UlG;{1)6FERj#KiSSG>NVcE;~DIVN2|fr87%NL}cNM7w|AJ zFq|SkrGBy0aGa6HM<`zKZbF!^$X+cw)NBGQDv>tZ7ObO)PB%>zQo9y>3~ontpDvJR+xs>S z&$k?9T=Oj3Y=3E9_kEr3I$?hZAM8vgEk;jH3zZ|~RE_BIsF>$Jk!A{|8=^+@kZt!* zgBdW~5H%A=C&RZlesC~l`j3VK*N^^1ynjEx`qH6D2>tx%XOf9Qr}|rty-f|SHgage zY5qTzpxWtB<&Zd14EE~J8 zAU^QM5{9$;-4KST^F*P$op{HyHW=o=^cK3cXquuRgc}}lbarM`6@SAyk{B-FTy$R^ zzROVbjWqtBrh{?s);IywWYun0=8P){Yd7#2#FpvQ{rC;Wn=&Sw+F9kgn}YRR9K>7U3i={w z-D`FCRU@Q+d1pcbZxn^x&!e9T)QFGqyk+)Iy|&Y#pK9Ox~_4jxUK%+MP)9^jb? zG57>T#2sFtQ8~rvIu5>5$aC;NkKh`MxhSY+pVX`|k8G*sJ1WXeEAp$eo)_p0(xmZu zya-(OIWeL6=|kgwK*u;o1J4lEI1ivjMtWYuNZQX)`FCO@4rB>AM?*rne$9KrBO#wd z5b+IXSgyfGL0ocuHh>|K#V@6v&0w0-FY^V*#5?|^0+*d=>4=G9MHqC`Xhar0X%Y^? zaF(o_mu29PQRy(@kCIbNU5Twaor2C>Nj2uh$$X~Lk3n7eb?+3 z#~^U&R)lnuUF(Gu|NTL3KDNI1of!#gl8{IJ^-x|?2_}*NIsvQBIR@SAK3sNl@u3?+ zK#IgOo-_-sG5h)-@lXtbAc)pFg3Jh)MG&rc<^A{;hK~lf86NH)4(qwnP`A|&aNO1@ z_8(x{MFRcj9S`NQ_;-ou0^UqVD?q8XL^pGDbN`8%V*>*r*f==+UMGxG6AfrWCVklL zmLd4!*y>q~J^oVJpA7d#l24gL`f}lj*W1n(o=iK%=<@FV>*Y3qZ%OLg0ncBMh@&T; zil)(x*z0FUK23nI$?0$bL6I;s(Y!-hxT|8A5C&w2#ISP{EG<-^tbAD1- zUkCU+d(L}oNTAcHl3~aF`oJ)QCEsHmO`!FQ2P(IY`KP?qyMKG#{(^4dx&ZEGsM-k7 zsRC*+9r|FLL3H4)t)o%#N689bYBL*~5ijxBIU`2NZpB*TO`R-mFHMKk=v5xwL~vmp zQ=(mIcK4%+GsYEAW4-n9YA9rp!g}2{anVztj-kGMwUdmQVWeds=u`Bk%pA^>=A3)y z7GRR}NPTN9k57xdzMh2O<#Q19O?q@&B4GiO@t^dUk7E-;o>~580X&?`9$s21)Sq;F zwR|iB>lS^}Pc{~K>Q8b!Jw`>&ew~>uFWf8CAHHRuI22nCHGIQ*Y}%qQ4Xrk4&W<;E zTQA?@a;kPBxClv;@sfZ#SbOcJ{ki-PIcIY zsitc6Gjkh~FQ*1zw%EPY`jzVYuch`r7oTsu=cgMbt)>PTf#oF@rZ2b42h~+?DvBJ< zS}v#GF6UUuYd0w3OgbNGCaR_^hI^*CMI4r3)!dtZM<0@FyWgzvc*-tTOfmm#{g`N@ z1FW|3SRJy)t7&7(O*SBBQPibU)#;b=t5pU)@~S_u*VHIyax*Jl;Xx~^vTa-JQWIxa znypG6QZ1i8=bG!KLg+_b>f9_K$@!KGG;v`l!-P!F>1JuJ=CW&o6H^1#Jv#H2(|Mo4 z=5mZ>$wA>OCEOG`pQEO~z)DyPV|ywz6c!^rQv^9|EevHU1*}HbPp^4ye(c4W_ZP2b zd9U?NF>-qJ0ki-hX)S;SoZ6KBSl%24%v3=Aw@BQDB9p1~F6%E229L|)e znSdX)-YSeZ*_e379+!vN;Noh2O>#y@@-*kspHna8T`@er8JERt25{?xNO@7aLh2Z4 zvz6`{TP=Qef>JXr95rcbSU4EHQk?NeFUv@Es&E7wdKOZpfZv2}&U-nmmd+NfVZTp1 zSkTyo1lX97o}b5g2-y3xgi1r7UHE|%rE;nrRFsf6e18TazlUn*8GPININ8jW*wHXz zdIF?*qiJZd?3i*yA)EP%2;$eu*_+5rRVzj^91bQe*CJ|QK9+UhIp*P z(+y8_0iWgtM!;yfT`3gsE%iNpeJDZpd0R`nEBPizPOiT3kARtSyS-iTsi!!*%RH4ioam%CYOV8^Iujiud5Pz^a0GrQ0!9R0?2chJnM zE5oKEMpL0YmRQFd_V;LtTS8QHRK{LZF3pF|Ia z(+6?-IQC{OjU`Q~uQ?=R-l6ib)7jW98NL(mVXU(lMy%SD+B2x-x=0 zWiE+6V`G1TDNf1;+5r<(m1UpKxsemunv>%v>~)>3X`^C0P$oQDze{o#SLbtF?3zrc^h544{Nww_?LOv^dK53! zmFtX?cj>$bL`PsJ-qMM7OGl7`=Rrtl2IEAihI*nj1w{mL7%24YP>Rx3DLKnYze9gXg3{qmkSJiy3_Mfn6+} zvI~#OusLhdT?V@745vGq{(?w;Eq>MkSe@niMRjt2Cyr?uL}FlTzyoFs<7%7}0@ z)zedH6)Z!$Q;c$#0#S|6=vk9dY_MeWg2m}hjB}L#7V`N zdefyDNfE*od_?axllrU_r2}xdJ6KVH~T8vc`^lprkO>9~EKMCMBI1jU+7 z1F?EJIU`!onQ+xTl-KL zckz$~3RSGwE@e;GZj+gu@yb^mcGtGMY`T^dI(+OsNFjGzuwTpGG zOZ5|}2)){~@%)*-F(pFZ3PEXc8*~4-6gOwUuB<%#kg;^Fp5#v`BG16%x}2gNOn-_Y zqZiO;LxtpEgSnQ(I+c*hgF1B#&=y3a2pbF=IpW`I2%e9SVnJTkUe2Q{N`@@H3tPwC zIy0y^N!%^I^;>gyTy&9-1gm?e;@fjCIZ%vkO5Wy5IL;59 z4R{N-mejgBSw*{7P`2psM6|Im99DYxl}>hW2Z*-iaSLYmPr2(Zu?-vlNlscM6#4%7 z)7_tbE0iAexKZAR@lqPBX-$rx4+ZiLR^_nc?b))}{iM0!JgORc7J0?RrDP1lIb4@E z0~mLmPpVaIxt30zRE1M&mHF}HfnQuejq|zGe(0{r(ewO6L`SLary@^QJAZZk%g0YU^J#$~= zR_kL*x)|*NeHqoDrs}817qyMjfu+Z4sdFGtdU%fwCyy!cop<^Z=OZpF&Jv@w^~Li0 z8p&__w6SAGHX}8KYt-Ia^{oAV0)bYl42?sY<|aqZx?1g8s!^!vRb@VQ*Y4uW&CaR{ zjJr1~nf9r+N3+pIIMpVV{R;YSMr|#?7W#+f-QSC7B1@syl`F8Vj={vqNR?Ol0etFn zTVt-`_O<4^KLB5pDnz$kG}OtgFtwnoX)(?8qlrJv*JR5WYYVQV%nv%OS^)-+#!#6( z{vWoZ*%sM2aiK*NC4jjVD{sd-i*KG{5zDi+oh1pb5DG$#2et1%uD&u1`?=u1WZ5J_ zGC!~a87|@nmxKA&Q^iwFx2WR2n!cDGYESPIU=d!^2ek!IFqn*s-9b)}qX>|0&ApAFl?$>}$?XE<$%}y%$S$_1uTvmK zYElY{JvMJ~0gqOB4nf}ny|-EY(i4R;jDFind?h5fBy-lk4td<`P0h!?hi1*^Gn;KM zSl>|i^Tk$wmXcW!c@71$e(mGLc{47j;$Xcqs|yTJwy_$$$=M=JupUaBaWB!rC@58H z?XI>;a4jzDT58tv=rYrHYq#9W6xyd@tFah?waQzCEZ5kr=wLAcZSr_;5@ytAOA6~q zMI4Z~%a+>}q57T)E6tBr)waVwd{Swnxp8cOJD(F96nnjCh6fo$435eAr+GTS&fBF2 zwq7Toh-yivR!M%AmiT%qMT!>I5|(8Fp}rX{i6WEjb8WZHNJi6!zz128Yt{+tX`&l2 zO=RR}A%2T8A=!7;rLkk!LNcnMm}Rn5=%8D@lrFO~s0US`OgK84nQ2aH2xEa!QRkIr zeiMsF-@7R>x7|HYpM3=%mYU$b;kij1t#GF9n-gURJIml6aK>8hze}1lTJ3i|3 zWo$>IsgKU?l~ZtjdArxJX9km8eeXqKcBS`rl&9v-VzxL&^qSrta&WUNDhciR@O7EZ zlVkBqvq5S%knlm_HqA-)JcebYy(OKhYsx>H^cff9bh1I&DbZqX7+m3zFDzzOer^m z9$rZkVMDIZK0Gh{p?DGP0qA4H3X!{<3M$-uzJ_3xUT zkfzS6c7XEPyvOQgFJ-N24vAIP@pW+`^l=3Ay+_kx}XT#675ct>?Q9$AN|fU7jleH}|V!iA`L@ z1J#nj1MwB>?_QwG!z)R<-5_{z^c|h&64U13AH35muw(zFPg(D-w~o()M(%3j%$L5f z-kJ)bjh;tfORLDoiK=+h@pr*P!LWxC;z?iHr|ZQEGrthPdI!v61w_PRznbe~@bFao z@SGteLU*>dO_;2dQ47m#8K0*H@D9_M3F#2>JMmSTf>G@p+`J&2KXrvG@j66aFPK7< z30?-CU%)2-pEH)#2WzvZ>!ymq@gIjy6gyXU^ECEIWhX699Oc3v3mE6>JvMrE+Qtsj zTQarBE0hcNP?wc6E6bGF6E0lQs7yNak4#-R)eeL}+WKu=)FpMhuMYny*l$-?ih7cI zwxeSC?AAc3Y}ewFZ+R7#8eO7*+xtYWz+(1V*5h8xJoYTBqr2OjwIWTA8ct8a*0Vi? z^P$VB5D;pP3uVJ`rhwgpj$*n7;eo{pXHRmp&$N#NUBvnfifeF_oy#&+NC`?hw5&YH$W{n3#uCtYpUUvYDmKP`c-Dl8AFp1AXM>+)S(6`PizW!)|t)Pt)bA!R~tHIPQuA8?W`Y{!G43oMl34L1FwKs8obY z-7ZLFW{HepRN;DP`qs+Ln%-3qlWT1aq2PwZPsGhlP<%lgTfBp%OLkNc7K9^uV# zPcNKdnV%j^&6@NS;L6{ChVeDldk?P%tZK=&H_TOs+ztXQD+fD2iG&A#*9@?HrtWck++vGD}{ zMR|aRotJ#k3<(dnX6gLLW;UFu19s+sNRl?Wjm^25uc;ys*hofgatE6#V%(f&HTC}7 ztIwXL%AtErF=1z+ycex)rShe1#o#e-1MU{KqOommpy{;MrdMxh4f_VZ4f=6TN(gg@ z-j&=qLx1SQ0JDgr5f)3ZhS!Mgix%$MX23}J(AMk}rAn};h|*Qk=UlUJ+~3O?Pd+nz zirDx=qVDJ`*)3@YXa2aqK%oVyRqZ#2>;jV*gH(`|rB;^L~&a#TWzM$p7$bjN?;duGJ;$_ zO&92GZBcq;An8D6Q4wOyY6`2O&E=ek!e$?-?^FZ={n8euS0uW=&@2i3Obx;gzj! zeBmpQ@x)j6`_xT~jv=7zsO$3VdN2V%zF=LlRqphj$AmQ-kwPJc1(>pE z1yrNE0H~UrX`auA0j<3#fE>g#jGq~;C3dTDb2&2B&x@>5M|M~^5*bkZTt89sT?8~h zpZ-F86xHoK`_d=eCGZ%yQh?vbO%8MXkGu4?S(n>Yy`Q#VrdRe)aimaNGCjMa@8i^F z^l$u9e~p)U{dKbMpfz)eqMY@`D-SIS1=0fR)0 zuLIUbYG@Vp>i-Zg{e@XrI}Z!jMWGo-L=#PcfA9(d$z8|MV`XyNHuOl`CKOv$U}<=f zu8q=dhidG?rH9I|gwZ8Sm(HE!^cu?QTGrmwn)Rpj&z8)+Kdb2N^jT`8TMXB~xv$k{ zR5Vu)Jk8L5!#L)u$gMB5#O{T4y+tm!n`2JM8GF<@!QSGottya=0g3?sfy_0a zHW75L=jTPia>wDnu#8(q#;vn*x44f>w~^fBHIeD1DPZ@*#=Br1QO0^{2A8&Aj9^+t zCnxmJf2{-eBO#TP`mDC4OC`bXol^yqJ#J&9zD5$PlMwRZ4ar=>+3Pk-AgTVLSxe~q zv#RIwAY+T05|JojwQ$xGzO&K)*e~&4f0sqYzjG~Y;GnYy1KQj=kH=SU8q)2 zRzkCj_Wq!bS@8Vu*OWC2IcdWoxyRiUz1N9U3t79fH9Th@2A2x8_VlsvKu9=I%Qx|H z{b;a9YgpwVaNMiih3g!RjV5A%&mH`-GuO?~XBkmAzY@RbHh;D5MDKB#IvyLpO9{r^ zjP&u?<8<5ErQvV+#EHBa@p4sJ(FEA=UA>;kckD`i>2T~Rrzz|GdggdYOYP%v0!bFa zf0wosJr4ks;nnvZ1bhFAF)|H6atO-mnV2p(;3RX|s(xAZc$R%XVAS5I6&y2ih^9|} zwzy4r%FFgbP&k_!o+7d}bGzXANf(d4B;z{RpN~`Y8!6PgLj8TvG-BTTrq95B30~Ut zkr&!**mtg_Q>(YYk6K>9fg+tz8<^|km+1?JB{6c3S-m7hXaZR4?dW31dTmihA-bNo z**CYFaCwcP=FRWb&Niw~l23hD-)%l*6_>St_=De4)oEgNHCV&_W?`>>(dC{YG*7V% z=XI!Fq5e|AFCLmtmEsxqQWTr=sag~2Yn~><4Qy@|lucKMm$NTV7M)F&OI6U_ z8L#I~j1L*F-T+IM4BF_5=)zfEYTdR8*Busr{}32|-gCF{y;++@p*EtDYcr{yj{h0M zrGJgoI@?r-Ykjrwie!rEo9dMl@T4JK?>uo5QTMS1W;T4{;*QLDVspNM?UFz>sf_x5 zc{*SdNAA};q7S9AiSwC(RrC%LlEQeN3t z0ZJpVko`Z$1knnwuTZjW!S(2QVa7SnCz=PNL2YS$&XK>QdfS^y>!`h{U!Qgmb11gm zFACINuf^`Vp@r0xU0gnWvnRahBA|y38MW~r+{Eo;t~qbM-?klikvHvYrgFADrojNi zqtLd89RED*uNPStYzLWkjk-M86;|$(QV80?$)8^)->HA-^^6R}?ShMZrO8%Y@;_?1 z76`1kvcY|rc{hM3Paw5=rTFrQQA)wW^ru+MWy>_?fp3c6}-FF^m?@j%bJS6pf! zrD|E%dSCxKZ<5C9Ke6wESE@gwthV(>WW+N);+I z6RseSdICz7Hb2uOFO8jTdZ7Q?%KGR-tOB^9j zVL*f2uBr5pCGc3CP}fBLCJCa6*_>oO&7alU;ku&sGAe(m8vYV761tCS@ztDy)#c}S z9&dyj{puUHWm!vI0Yc7)zmWuhvzEI45TCus0(sxDZ=ZLIfyO82m)J+kX|(EZ_xSr0 zc?D58pxl?hT5Iydl@pkLYtBcHuV$`pPdfzb9lgu)*F;}Mx>n_vYyr3WOQ!gc0Eh8L zrjUs~=rYUiZqP$af}|A^4!e8B;#usA(7gm16?O6FuD!kmbAzO|j>WKotcW_-*2o*H zr8pkKw4@ER-N?XUdMJ0@HwiX-`qxanqc$b$ zqBp}gt((NL&?`rbYKN`@+|F0&X-Q_(=il+6oI_`yqxCD4-iLAaHl;oa$WrJSxCk1z zatU);XK+#DcgGB(zH=MT;`V)ImvZB>$PIO8ow=w<;fo&9REZC%QpTVMOQ9ck9BrAl zNnEt)R%QHoStdNd?bvt!WHo{eBu%(I?oXjGotk@N$y$@~qck74xGanT1F%?yL{Z0r zQ|5a2-leIExe38 zKl)?Mhq>?ovk@bpGbZ}p3IYyD$C+YJ%zDW$P#tr*4bZZ3;k@@bISYER`#oGcxSQ(xc8irk&e% zaGp80Z^#?>!S<|Iyo1~#k5tnj7t8EX6)*O=q&S|)YXKDYN80BRI<3`51u;K`Y<+uc z3!`IWq0QREjNzoZqWm?eXjzG;pz^`>_h`4}`}*khL8_W}dy@?_?6P@9;Ey$Igztt{ zk0&Qt)Jx(9pHs;}<%3J|@t()HI(iiwXCW4~)ELv$mpL0ZvHB>RxLBu>R8t=3 znsuH)0YX+Pp-l|+t*M9jyfF5uO_*px_s!O>8LD9D9z|Ft(Mb|tuu=E~1Jw8^lr7$U zfd1ynCNY-1vK^$WxW3Z2-uskh(-y^f@OGS2sN8#6AyL6FW;0QL4$n_4Kuds1StZl1 zhI)+D?-OH<>0Ct9sT90A+9`~(cKX3I23t3)bFa$za%4}?w6|cr5lyQeSE495^(R>h zOifd)YR%+*#%q%CFI~g#>)kvA*aWF^KP0HjcKZPPHjSx+pW^!yD}(Ch*+_nV#}8{_ zn@0^bMU2SevR7z^m|qIK*E0;lJCY#~H13HDfKcVhBe63^md-yV%9M_@#ywrWmD#nM zecb&`Ro7jiT6*n5To)i`;4p-XQVVuZ4Ix+gV*XGr=Uoeei^cREa_q|BewpK3on0+AyY`QXqo&G z3~{Wc_!>;%?{BV)qP+;Hp9=)&Q$44bQfRR<CdqvnQtA@O@cra{51sFWHqdp0$ zZqH+Aj_Tn#;OpV?kmdnl)!;|R~#%>s4`ZAW?xYO`i?rptn~S z+0aq$y!=J+NfyJ^fj*2(w=Su&nU)jo9Ad|mj~=U(uDS-e>N zRQl>-lXvdr=-qh=x~y)0I4p{kJ>W_DZR*;0uMMpl1@M}7J?J(Ju#&KS`M>OFo)D$;iOuKE^PP>ufLXUUSn4`jqh-o9Dn+qsX~ zQU6a!-T(7{$Le)NsUbq6ylGFo0RYt3fG~JMSJab!K#TCqIulxWtp)_&T)!?aFTa2N z2>@YT`koj4hXtU4@Zx_2K?smowf;u7Qn_*i;DaWPt+yUfz~=B5Abyj9_^G_dqMv8O z%~Ai_c1Z;l5WIqEzYbpo7zEc9Ux1qU{ax2MmFFIK%>X!x`y?!A1O#*YihzYGGWeZn zC$9rEY7#(FbgQ}Ev$L~x_OAWP-VXN1$jkNgwW=Nl*H%)4KqG-#-)SPl1Rbzqkt-lH zQ6>FhXq@^Zs*a0KCOEL&o?1jhrYCsk*PhBlW>9ygSA0<)x>RUvM#7#TLw zCTFufx<_YS6q_oyjAIxNhPOMx^h;apt*~dpC%0H%#WnlyBbT->Hd@<@R~NO;5ndtkP82wH)dkh*%!% z+yL=l)TnXV`M&>olZ^yRz;*Mc*E74g%1oPdnSaMJafLOfojry2Qw&v_1AEf~l)xP# zt`#W)zcva8SQpH)eK~X}=O<6+X3~9DGuU4~<$F-oF&&59bVkn}8UF$S28<+dJkdgf|A?BQLkgBCdjd$F=ireWecxE^ zecn`8dXz;n$Q>Xm;Kz?@OVxNAI>9*mBeM^*HiC%6duQS*iKGEtNLByFyR57CwG3%Q zjN_Q#@bsU|aLKwhmwQs>9)aEtcN&#CpIeo#Y#xXw+x}9LPcj|t5v&q=mFF-WC~hYK z$2>)Vy}N0wYx5gUM%C7?&=sEG7?;Xc5^;s=?96S#JgNBdv9n(S_UBlAq4PPOF{_U( za~yojo6ig)>JkW#nT@<|mLW9R^V(UGS{iz~4glQkTf`3j$~N=zvq*;uD#zyE8Vu67 zZ{8!l73fcC-2Bk11?GquM~b>R|97|8ymruC_aqF*z8T{bfCpryq5vW}z@@dySFFcX zHf;s zRe3G2Uys-Ps@Vk(9Z{_iw|95FKU^*;4vy0^+{WoK->H9m9P_>46uR%TnC^3PJGgkG zZaQCA%0f(g8Zz}$7e|1Y7VW->ZbX937@IjK&p2lTs*VYJe7%%L=zHSHU%U;H#zi_ zPeoxLE%ltfe->ZrTl$d~8(G*U5X(h3j760qAG)wmWk!V zC9kM#D5-WnHdAoRdwMTCtoUN$=0uT$da^b%6zceEO_W!ZnTb=8Gg`ojWs{Jy4hw99 z(m?RosWsb%R6D&`H$Cn;pSE;lsKj&+`jstMmplmf-|gGS;Q_%-%-6F0>Q;OEiCKt7 zLIFaDlmM&8BN#?fBe*XX#4{f(#gsoCKr)|eem-p;=YIY8njnBQb2PmtN0#+X;2D0L z$y-9;TP!pG^ly?9y;2GgF%elO+$kGv6PS{XZu?W_wH@)0Soq}2M9qYx^OqHi&Le-M zgj8F?KB4H`QrQ@$%p>_Q@;86PUhGV*d5=;-Sqz?xQyvbn2+25L4wsNixWnqWxEZgB zu1TExHLywzYYF9vr4*GA>1UsD9M9<_XYV1KUERSBxDlydoQERA@?nv#rzrzBghq7P{P?CY$+M{y!qIlT0E^I!^T>X|l4)?`Zm zRo5g#Q!K3AiFzvrIOGx>ynRdt_Pu(T56v(1XZre@avaLeryvFg2>{ioPShOpFc9g)JXNG;3h!lvt}H3eh`nTT zgV$6E*kqeU`z|#sFTq#ak7e&jH1m6Kz}P+`<-O#m;W6Qx6!gn)ErPsl4Kic(Ms8;# zil&GRHEXN7cic+_6lqQs#XCJo9pwzT73gxC>tZ_2aLq?JyQhh+F?vYPu=*-t@%Y4} zzb-ET)@kwV0&V5s{P=HR$(Z910XPWh_d^#%>!Tu7*L=cBe*MBqbUW%MK}5%-7VH%l z;ihT3zw&F1C3NPO;V+H4=9+H)(-(SSYPJTa{FP5Z`W4A<#I%!m4A+UoPT^V{!R?V) zL~L%)w%2SOC~dXP|?f6uN!4i{r3Z_6x0kE?HYX9YCAjEpYt3!nX@gc(!u$H3@xaWOW&Y zx|_B6-E5PX{7G@Oh9m7y6|zwLE1uRd$tG2lI)g!l<4O%|&Snr8()8~o>l2UUQm+Ln zGCWRq5K>HUsM$%Q$hk;_aml+Mgt1I_6A2qNDFkA+-UTtZk|zFfP`_cr2IjKejozO<7~Xt0j9a&1Bze}-(D0+ zI8h>-1<8M=l3XWcN_pJkXZN9W;B}K|^DN<`JnnPM?raHJ#<1=blLeCPr+(DGrMII^ z?dOpr^yZnTa`=8vX|6Fpm4g3_C3)39x+XODIb~O>#9H+?4bo`CrV~h-N+MOrdeup& z82xY(M~Z*0{0AmtjeL|4lg>(|Q1puId3HzLiIOsjJn~(`yx}mD_tlvQSH_hSZm@`E z_NkKQgSc0ywP^+*V$pxXoP!LL(8`o%GiNjp-P{=LqDj(xCCc9^_gbY(JBxbaN!x0O z)K$GZ$lPH$RsQ0L;Wn;0OCds?e*|xu_lyY7FSr?3!ZzqOm~WIN|K01;?A?z}RSkz` zTaoM0V=qxBe*I#_9Z&+)pnmv`a|F%MY2l_MIBh6b5Vna|V%fD`h8FsVynLt~+Y+RJ z4s)q`3J%$)PP9jHLL8-{>OdJ1{31B{LxE51i4C)m4HR`S*^5m3>6j7OotQ9Y+Dx1C zGZ9=nhoM$ulkxnTgkZ}v&Wqp^C4I;pV`qkQiu1}U<3BI8Ob@Cs4_B(~#~jOVC@(g5 zD3;%Vp0ygam^O^fs@5LPx^&wSx$`1YKN`J=*bH-+_u|zNaeH@?yCt zOY=E15saXG=jEy!{8Ksz`N~V>>gQVt-5hWGD}O`Z1F9y;rGhTAFzEWcnJh=| z=)_Zx`S||nL6=c|X0G(@RJFy%p*`!bqIrUP(nWFDkZ04}bXCw@@zXc%GE5L8|7#PM z@hvpyl;cwq0%3c*Q^Mo!LDKvMjqMOb^7yFQU3b4>p5U{V$~TD2Zn+cg^L&#Kgz?AC z-6c;M*Y347nq!xP-{}u&vPSaWYrbywI&C*|EwgPAf08wnZoT2q-*2+PF>sviuHy)+ zD4#DfqK{gqj~;BJ9(rio+*=vrEIhV_^yuXiSrv3>03ak6#F&1ex$At_tN}_BU1*u> z*M3R3>mLCfxv-B@l4xq0MDzy5`ZcEZd}Z`+*R-wi4s*81-cPC9avQ22>6bOQj#QbK zPAbwMohb3l<gq-s8*K((QXcL|SG(vY4nSpB0twO9QbuhJ$+yjt#oBA-?P zWFLWq*Ou>N`qOyeJXKc6VjUQ3%lHw$I3pi*yP{RCO@M9bo6lD&nQStcL3lk3h(?#G z75p!jA`5KTlqE(uY(OxqR~5YCRXEpL)_1&V4>RI5wyrsH7P9R{tutcD!J^h5K^0;S zx;hdh41Z>xAMwthzUL%Xck`m0%~%66GL{`ck(B3p)YxCbJt@&_g(N<;rhf?kP%BwGF=Rb@s#xxN55kDf$%Hx zD*6%^Pto%`@x>M@Xp+2mKEs)lNbIw@Lc)nT@qwfO{s#39wpZ{rUN?MdiUXd0rZN>) zp+Bx)iHdkU+1Au~Mp8187rc}`$gfC{nc6+u1XB?3pfvwuiSyJ+wqN{IV|fehgwPnd zT^AM& z=S0y_l>I$}xSD$=u8j?A28!Pbv-1T7=3F%Ty~T(}{bS{(;AMj52I}>!jf5vTnRa6D zAH$-(BdX$Ko9BA2G(yN1WE7=5+;h)RVeczTQ6tJWMWNb#X}>W~CvUDOedWCizUenF z&n!DiDPm(h9ij;flFU#bHjaZS5C?;vz`In5;+|mSK)XjhB4fJ-6*OOm(`-MYn=n+i zQ7kHumlhcQX>?b00ykO`u;0i#G^qU`_5}lGTJ$AiS9mf`Uw&sUF#A=on~^9iXGk?n z;|aLX%%MYk))sKhy>TiSDWPU*t={;BK6^+$F3cx6a;H(U(QEI@8}N-tL$i;ge4g#T5y7R|n%prjO(MH{!o#9_{ABFgo!; zHIZ<5(a>qAH@Xt3fww{Q7*!3cbVp5IW#YS)!rx(u&;0P-@fOCQ^M*xLbDjuBi8Bkl z4$yx~1N#`{cY2RJH_+hiQJ@-QB?eS^VOjKL%8-z4yd#OY-yag62v_Go)z;_Dr>9 z)IhqZ=KB8wL#}aNRR)a^P;oo47=>yjvy1>_V714tL8`F5j@45DD+H0qeNHqOdoQZ` z;_0}5T_q$?XP72b77(&ph#z;;LBy&;8P4dGHtp@HAMVpgb>Cbb1M4S+5+qi0K|#Fh z^BFteTCixHpLAx>Oal1ul?~Axf9GwzKY%2XE_}v``6UL>isIC44~ZKW6C9)ngpk&R z&i_3};Dyf1Wqbhn6ztz$u6Qx>b-v^%7`<-D9dB_ ze52SLOc(8U9hSOZ(@IT^e>htydk$bJ$_3c3iaX+x?v8-5UXxin`dNon;B5)CqK3NQ9yabkh z1n$|>mnS0%60e)A25I%HEh64LBIf`UD~4OEu@XbVw8n<`BhS2&`~VA~;|!H?btFGL zus+MVn`Ve$7?a@)Sg+Y?;WLB}a2Xye$O1N(ly$%piUv2?P5exXRY0I>ZQofTur7bx z!hN};Ci;^;eA8{Z`T?%QL+t{7vzaTsI~&m^sYzBC`_9SH5n`9DaLTe*X6~Oyz(yTn z7W-&6F5W{{kVxjn>GHbupHIWm7XtjTyX1dICV%fWs7PQP>jmk+4;rt86Wq+NZK@Ny z={pPnMC|D@OHKlMCQktgxJJ!40v1i9%z!)S45ane0DkWodj>$+x=BQtf}`z;$_o$7 zvOis(x139zCp|~fo)*d67Lz~ZVZ2-pLCM@K6VIEY&ldw)YXA?#L-~b!P8xYYaHQxx z{V+!n6j(V3^IX_c{2TJb*vWDiSX0{jd;zSy?H|d%e8#vE>dtIHHOVUD8!wuamuUd3 zCEbFj&TJ5djtyNrDt=lO5I?k`qeM6pJV;$H>}vJ={ww2IYSLjI<8ALuZbj7Xo@Xn% zPf@B?V|HQbUIXDSYbXV<+vR1Ij(}Z`R>_>hab1zpj84)3_BM0okyz7#8TC zHK1b~KsVi8pAM6)?Av>Oe&njQ{e>7-$j5jolai@?{6M5{%1BCE=!C4z7nY{@n~E%a1bzk zeVfXx+$cYKfS6Lm>>8^Ein$ z98=>ih*(;TTr?cJ6G#35bIiPK@Uvwy#xJ={QjbXbm$X?S!F)_f_>%l?_?#mo>Rh~_ z45u&0S34pPT9@bj060C-zPv$sHc))Cpm~sB1t(!&h^R1Ix^h0Uc-N-#4lo&>^o`bT z>N!X~kaVogsl)6)3MRSC6RcfkBh*|D@_1Cmum0HWnYXZIhhim7P9nf}_w0J^20Ls< z#QT3fkiOojNd=X$7*RT7-w(hEEvIGGWfwYzXVbvFVC@``R?bHd@KJOsic8vlD6ORL z#0J3~Abdtk@MZ~B1dzaadW>+ zP_%oM29|r3v;DWlA(T>6cH$QVu`_X7i!vyD=y4CWID?y4@VBny)*H)nT_xIB*$2JkjX)W#j57xD)U|s(wl{Z)GMD7V802T!k={vHZK}i-1exyPv3lXKUJ@4E z=w^$a7zJFe&PTa{YCc}y@%!2}Dg_xnrDSH_^b#=8b+#p4_Oiygu@601;0W&SMkUCs zv{WT9!v2O`0Zu5s7JI;(_M?Q*`IA)p3+U!|Z0Ttn5{2kDfBf=n9~`OBf;GXA0j59d z7Y|W+yt{iZvn6->jeB~?NAbi0mIPKMizCH?@Q$;czZm=p4qvvY&14Lg<(oJ*8+k=c zDu<+A_!MXcT21!#5td=GPRQrO01y!h-%Q*mgATeD7@6y}VY4`tV4=u>GixoCef z2MMP?+GFnw1UuCb8?(3b{OAD2d-?>LwX38iBV1OJ|#9o;=|yK%t3|o@l6rg8~V+pHJ#sh#byA}r%EvfiCwt5 z@ePF;#xQ^M^2!k%%Y&TXYVWWuH|BX;J$6Yk+6D=hWk;$cpVH2#-vKiyzX$CGM`)f# zqp3$wHtay|)og?+$kw}H2Z>sn0;_yJfr_4y@ZwLYkB@x-d?#0a>GU9SHkz|;6WmZr zGWo{5#dA5$;{Tpmu!6;$7OeoIwiJQzA`ajfr3|?@jZzj^2kwbp06*oYWMVZgE{OsY zrr8ydv+NHQ6_xw_404(YL-?ClfgWg^#3OP%S6r;78!)1N0KSz{x{;^0%+D70LH&6 ztGN7I3*%`hDX#10O|ZBMb1)qvFsJr?ihra?lVgngVnILX0K2xz%Vq(1|zXBVi>R(gr%u)&%9!@81|25wS|3t_IcHg zS3)+U^-G_R2>%PRt7-&1*j-&3Np7p@u<=x=aF? z>@B5XUu|CU?Sks1lI>L;BWm?y20n{P*RjdJ?G)?VZ%SKoX3h3AO+GXtPT^%5(iZ_qP)^&0U?$X$L z>l0YiJJ>lGTP+p)iOCR23#0fm)wK!I4Sq^`D!%IUy1@O~0pX3R6RZMmS~T{TE0X!n8BvG;qjdIlb^Fl^hHrWO?H#$7 zWyXi=rdi>Bs)kY_tpn7XXS#wNoxX(U+V!opwsaenQo87W*B&6%6ivI>@5m{?Nl#-q z@1fm%E&R-Sa^z{Mgt^>qjn?|`oCekK0zj^W{3vT+v zDs5*%-K@ZZs^c-`cVQK0YBz$55{q9uac$9!-f-Kb^0n{rWHzp!f(C1$*=*{DgK+qO zL+W!wgCoLi%5ng%Cwh2#k|spC|G1hyWD;fgr0U(kZwGX;kc8rXU3~Xltg)$WpC?Es zckxe{zJz)h?Tn`!>jjHdTtcsO+-zRVrybI!IM*{ZwRBZi8DW(A&24yNf%`*zrFRC# z1^UCqsn#p@8JktlG7mbxy{D%;bmz3zcZKQ{z6>S%&|lbh37@ev_9*kPbboe5FUoJ2 z%rSUnIY@d!IOxibb~F(GK2E=q=kE6tZ+vq)d>~W6Bxzvw!-CNMr_^`X(#FwIvT^wx z)h-=DM>nB87H*Gnqa%xA5~aRB&2nS<+f3k*yV;X@_@mzouA6GPwl19AQTh%QwNN!@ z`*LBwyVaISM4NQjaNRnowKV(PD+e>u-##+cMw#c*P7oB^K!dHO8Vt;kD*C~WeMu#67 zvj-9tH~K-N!0Y{J{Nwl8 zSw;a_r62!=M>~`e9P5d5l6P59w#We}u*?-0O|{RzeTdbcCNm33r;D|T`2+v^x`q zz?LhprsE7hTPrw~f5f8C_UTzM@lG}R1+jR&X#Co@&ap5!Md%9$;~2MPf9_J?GugUAvnZVb<&|!qzKjfX;yBn(s;~HDTauHBGpz%*j=2|Ezk6rI)>WihbZ& zQqvTsSDk$&@s_UCVOxQj&D^i?GxexK7i%0u-=*UpPWNuRYvl|{KwyFELHth*7C~< z6;#LUOMKioN!BY4Kf2o#kJt3UCl&`QRE>faU+_sC$J78}TwxJTk$s0Iw!_X5V(_bV z_OJ!#C^1lrm^CW(-#E59dXo5ZWe2Z@6xa_gi(*@7QLPr|Xgf^nL(UvqzPtKaI_=f^ zO}%(E+hpM;nyy$o?&U_9aNmhu_pNe{H?~m{PGkq&#GzvkD(R531YcJ-hw${LiXwOC z0t(1P40AgadL8BhW_#20-m`3ogA#{<2k>4?$^iJh-gQrJmF9T z-~|v&v0>i!=yMM+-%6_$7-}*~Go}tcf61V5-ffQJG&TxJUhJkRPYf+i{Bcg}?U`DS z%3tv4M!j#dr8Ps^p%ZE4z*Gy{mmFo_^xF3W+=x1Yqv{3E5qutcHM8xV5C#KD3ot?J zQ+uEF1`vFx(Kt=_ahvpyp16`fI$-TDkKx(nsr9+{*%0t&x$VI`4gk|(O zK;G(`*ChVg^LN;@LUF>?qhy2o$++H*viL81(%HR|lq1H{K;HPa;aTdhh|msxxFzhs zjKOGT^!jMZ_P)7rl)=NX6k}a@*4+cSCg< z3esZP&fOR30e);5l#(X(r4Je}JYBV|f|_4$Dp`MNv|RLSw!a)*iNI-{&te91jd^$& zzWdkdCO&A#u5a{JS+BE9BmLCwFs&mNq?!xU9(nRRBh}UNbP}X?oU2Bwb zD6qrp%a6-vT^*v!9Yhgcxs!y0>oThT0o&M5Z1`1cw)JhWX!{q74zC!;o>tQ*Pri_5=|;#c?!qCqx&89RYS2W;lE# z9T8D!`>rA;F~fUGJaI+Wpd{ahN^lV#NipO6m zAu=s1dh2-;Fi_HK5;}83jx(_V3qc*7)y`pmgB(>~%_^ml#PHipEi5x~{2EeFg>O~v z0_R8QM#}CRq8>ZFBCcKH;JmZYbDbM_Ii=KhpcBE8uk@Wg9tBO)+@wI$v?&5Jg@@3bh&>NM2a{(9v*-10-nA*~Db`h<7HM`aqbg?Oq`{wzsj=R3ZO(ZZR-R-S{=Xo z;zy=#18_PV0+30I?HSAC0XW^)QU+UlRpXvSqsRGHzR>z%If zzPlYqe@i^w|JueqY1kbLVe%j=+P~rC02$#mX@xZKT6~?EOyk9S+U9NURb>=z|5aJ3 zpFB5-+RfaQBVK_=9F#NCv&}#%Y2W&!(MEek$I@|&npJ*Z>J*9m9S{r*VMng+{xiMe(hq3Y8ndiy;+@RAUnq=A`<=8EgJS&>QeDP(nC{h4QdlH+ZXZjBp( z{n(y+ni(VTO-l;vdf%qe9X`vzSM(&J}{ElF;bNKd7uO*qaPq&#HS zc=5)ppAu(u2kvB&nmXVCquHt5(L+DhW_0_?TR}sx7PG7io7YcE1J{IF`FPl;m(JY0 z^+Q2@#*h4m>dd9|-`3a%9)C5l<<>R*tgdFYZ_sM+bEd9Cq~GH9z<$s7EoqxLcYynt z%eg-t4{GhD&l9NoF+NQ~*Vj`?^ih4eGZIZmrWzYQI}$_KX2HtOwvbaB z>iMRdr2)v$Z*puvxQ8A74W+QtAxabcpQ~hZ@eaT`1A55otd}$BGd@XQ9cfBA>kK;_ z_j*HfsMhu17fWxlJxfA_GyQL+XUgI8vBz;9Ac0Y-V{btUj4JU@Vdvv}gmZr%sRfRh zHQ);=$~QaXJ~7U#hYZ@AXde$`dF?v#@rBPifu&-t@_S6fH84CBkRD}t*_6__5=YAR z3Y$zV8k=-bGYLwwk9g4zbKBx2>U>usPXdV^=rS(F@KpSs!y>R)G=OFPF#3ShD`B05 zZslTHR%GHqOotjgN$c!ss3qe2B8F`2EqLkZ^xdm z!bugLRrCJL(7Fs`a)4(dBoXh-NJO6g$xC^Pabfr5(7srTn6Uv6yU=X_y zgN7i9I68|T$>)wi-pHzp0i944kCr~D_ zXGoa0AfbOqtIci|_9h4_&C#3K&_<5Q3b20a+W9(GSpVKJaYC|)w7y}Byzye==!DPK z7X^#3myjeJ<7>IVBI@uW{XHe;YIgr{`F}rE%5p*`MF&$mXNg|68}St`K-pHp-sM96 z92@(jDT-4s${-eM7>}rr;C})V97}_%Mhc`6E=rtFIwvo1sizk&t6tq|TUJw{l1G>Iyu^@Dwy75#5hrJ?is;p{ec z4g|{xj79mO@-TH0E#IZojljxBeO@aQCf>S?nv;_MaCGMD)Qnv>$}UULNN4p|=rDYCDoCa2kFpJX1bR?KgKEBkK{y=rv+XrzNc z!%B*A-IgtAfW*{LZ`A2l%cRuDZqR6^FoH5<*7_g&elfkEp^)bu;4!o}b7|4VK~bw0uFyfO{AN1p>{CtJ8U z*_$F19_yATiD(ry)Jk^%{hd$w;Nt-M+Ih`IzxiGQFvD2)mZs5nRB>VTFzrneZxaQ0 z(y2}962et*($!zdw}y!ff*&`b-Zwp6u+o`Vi-MMsFbA`|KY0j9GH-Sp8)A@?Dvtc+ z#dwtR&rt&g-*|!$yYf$2cr~Ib71ztsJwC^fOl3`p6aGzDq(1DbFYS5V=|d`_55Hh~ zVuh4m%JTA*0HQH&)HBp{bNU{#J!bI@Fa zXVG)#Li=1}1;^x86f$2rJ2A<7d|m?dGaRD+jO02PM91Y5mR1z*gc9%tU4bf~gj6o1fohD9JCC}Aeru{kgG#X0(; zYGbD5W^m@^LA#gVuKr62r$KF{(xEfc+4Z$~9SMb(f4%Ax41tmg2tHph#WMcwFF_q4 zJ~tv}TtQ^j>G!ncI$?=dCM6LZM;$m{&W}Pj(imJ=2^FvF3}{GZ;Q6~1u$e4 zTA06Dyo)(Th9^du;K;GL=5cY*5U%YHu`uW+H|N({Qhn_>L!_46rf?YCGWmA949&V? z1x-4S|IH;ZZ&GvaFf$oSm6qu|h8^taAl}Lwp_{yuBD7F7uW9#=44lk%+&5PB-ir8C zrr2Q-BgRx>uX#n)C&AHEp6Kh(79l**w53#r(?XeVeh8WF7z$b6(_gddB6A1c>p-TQ zVQI|Xf7Psn#66s}oi+SY{=JFsYD8>*s2FQSK@^b(%HH^TQjv;*Yo#K#mv=13vtuiX zn=r{#jAo_j_5s~N8~b&&5{|gUge&5gYgkc?hrEgaLiGoNab&>}!D%nU3!76w{gcvdP$CFir zq;e!ra(@l}x`j&(5hi#3h|vF?k(O5j+xgJcfFs~%+JpNw_C64Y2Jy#FSer7+8 z{?$v6EUCvu40ifFgY9e^O)W>SVn>g=?XpC)@1FPZb&ALiucxk5ov1Yc%vyID`xLzdir2G(d*Fs<~*}Rv0G|3L& zhNwM-p(y2xN46d_Rx+YorzM72;7Nfaf3ihG$8VOBZx%z@kR*pXP5jCn`GE%@Q~yyB z?9AXTT8VsKrL*OC}=L zE^-Hw?pJD%c~!O<&}YrPA)kh&5b;oSJ-yjYCob?3QM!)q& z#}Q?k*LBYQ*!q&Lp3j4Ty!3wcV9N`0<-uADWuzQPBu(p;&AwubkgDRWvDJ5d9lme2 zi`ll_wCSReoh>`colU-oeNm#-xQG<;KR1J;+ZTF+f&wV&LkK(zMEUgzrem3!J$;8z z&Z|0Jf}_gzB*i|p&c}}`MOSaA9gY#tdv7Z-p7EeAL@r@Tv&r8#{AhoF?Hp!S9gx;A zNM~>uejw+VE6ys~p|;tHo3M&blNG6@P`~Ni_y& zxk}t6in${63uTg~R{E(utdCVOsv^{xr)Z-H9bVnEf3+$w0IT01gC4ak&AO%5(4jcI zUMAv!#*=#(BNNyn!s}|gk6mr>l{Y(;RGzl|vn883k9Zl&MmMp&An}%bb9tGk z+G4$W)-M+f0PPWSn2&v1|4lIVcB|9bIk%V=w;}`h&EAEI5xxHOyHkrI>%?EJL<=7N zJ~KX5a<|{dB}DjO((vfKd_8942TYbpYj-=PN&0Q;0c9aQB1(9|ga#q7xoL*#RFvMg z%So)%eAcI)!#iDQ`w3PnoHgk;yR*qW6fOsudBN>7=%;IoVKfVncwg{_4~NsF6s#T( zI-ERLuB11aCJZD+(ZeDMZl^j4F~tVhqIn11|^@ya$_C%Aoa=7lSiAu`buT8d^} z(5GgwoeLo+q!U7@rF*<0D^t55wcQOyjwo9xmoTA(LY67b&B-Q3=elbZ$Z##2LyJK} z%V#jaPlR49OzlUlT4AR7c-pW7i z8*)8&7S+>&wr`|p?FW8#;>y{mxi+n13uqe3H#Jk*`Zhd*mw?H#NG9roW=zmsXv#oB zRWI;2SJzV8fPC1S`S$ck&iG6w9O%|v=noy+?D&JTW$I} z$MD(#hOL9>Zu_8|g8Qad`qc`&(_ge%m-Kf-X+>5v2Wm-iLUJs0nqAv9jU^@6J~4$K z#3T2MpMlFZ&8K1iAC*k!CoGOh0k*rvIj&+^r#$+E=lxdmUtb8&Tj((!{(L%~C&zhr z7lrFEIb^Hl?S*_quWYAmXK}5+(?TqsR?9nZLA)YqNY%$%LmXfIoCg~$CwX;PCzDW@ zt~;gZ{a(38dHdFNhV(yp<}gvPCPWvZ`6k>~z?FF=}j;pbpeY zf_TYhn*6g-&+oCzJPG#+w~QAh?zedBNt+nmo?MXH!@yz}Bt&knYW8W+JkUCO_N}@8rC78?b!-$Bfv@vZ&?Yn9Gw_bIL z2+7Gd#pBUc`7avN_F-QdZLYkt%m~P?8I410O^>l>{MU^!4>M}aaGsAWP4EmiirRyx zkvhsM%;R~fqPw*G-&L8XEpB?HOwn9HmVwh0P~Ab#t0Vcy+;++pF3 zf4zF-XipyzNI`7(wO@Zq_bkqObeZpOVEbAU9fq1VjDbcksRN5&cJO!e-kc-!A#!8{UN2|6(Zn#S)O zJY1l37X4|aiQ_08GR^XIRDtTJykPOAiI==ygCgM(X;aWgXR|`(exr&8)wl{G#`BV^ zxdLeF2AJZ{LoXQ-^fW`_K8a7&zP+m1yM{T0Z_Rk_VS#G+z^F2X8`eUDE( zwv5%#(#s;sLDU=&J5IJ>;@JiRd%0Yk<6h4nFN~#6@{;qj)<;iVZ%O7*9d?QD^Myxb z!*V$|K0~3wYg_<4^-c5Hk|~XC{+MlK*k5Vhawz2lJH?4Fr~+yig6g>o^?UCd0qfa*7QeCE7HYH9xQ6n}ueQB{b@(n0*y}CmeOAgZ+VWaox(V z2EtB99?XOe1bKWRWXEV#3!dC~0366`=58nQTeuyw) zT>mj)J3U>$As{Z!$!gxgoAGcM8m8|v(Rn$z$}*6uzxsS6Ni@{NBP)irqA3TO!rtEe z4`HgFc5CnXT|X6+8<8dSweR2Tidnaa@LeW~W6>NAUu~#klj^qPz2bNFNAV_QhXbBu6+Bkhf+$2 zjRK5*Wl(h}^2gX9>gjTQd zd^aQ(6M)XRa&Y6Ari_sWP}#!_6cJ^EN_ zphYblbx#YoEIM@%>c7Iwx3rd4v46`3$gqpOnOH7kN zBsPBu4iy(j#z+X&e-OexgFi_~T7?VWnW2zgFPVcofpWUgPja11owy)9A>^kHM%rQe z&UfLxbnOv(UXQ(oXw8YhT_deE!_uf*9{CDt>M)LAw~pY>Y-aE9)0M)f@&rKOJB1vK zORuaX+go10f}ebrm~~@8H5`&M>pZlb(2f~eG`mHpNFa_G{p;D$kSSN+uNd{|FR>U4 zt+QCDT`wE1=?fwWQ#v57HA+Y>GC=eNtAdi@8N=f?9NA5#A{ZZ6Ku>Vhn?f;wKVZZOzg6=hJSTufabeySH0uJ1?@Y}Dc z);o9o7GJ2_JWvt7c5ecB^MR?4So$Jc5~%U2wwvIb0Yba?f&BPld_@{}C0HU`0zmM( zzn)5tkI1J8#8zQ|=0A1rBwcus(R;q&Qvv+_Tg0M&(+)5^T{d&V`uwkVL9Xiq3B|bL zxxg?s)~PVwJv;4@J`=zfWX3EM3Jm4v(Ff{aL_GKAlHA1pFar%>?p|Lj^lOwS%Z<=H z3gUlbz{>@p*%?4K{iPw}I$i}a%g+^k3xyOB;_1r{#=8-`2_UMEs%E(SF%O0R(wR2H z13V73INSAO8WNV5U2w`V9p?F@|Ha#TN5l2~|Nap~??iM`^iK2=J))=S1aB>7j5^vN z7`;V^5}hCty^L;jqPH-NE_&~E_#N-hy?5O|e&4n3cdh&T{d3kh&YW{*?{oHk?N@m` zt3gx3klXAhfUGsiO0||=LsxI?P60Wf-yMsIjvbJfdC+dX6C-P^?a9~~6WO>-fvQ57 z?vw{w;j=w14qZ*EDc+4oN#1w!?;KS58)+?c)h-sp*XMAS%$J^~(?f-3D{b^GSTT&) zjH$9nJ$=nlEe)Nc`J)abF*v6<10VsDr@n`P{8$|!JS1CBm(J5<0mv)=a+ixO20|@x zyWV2X8VK)_?x)1a1I;m;`i{nMt%ZO+fZR}mb(aZWw-~}OBW4gf)J`VPJ0ySG$mr6; zw!0_Zd_W?3bG}@8y<59X%JDsv37YHxLVXhLQ3AKb1fDhcVZ1L6laOh7eD^QfN-mDp z`hb??x=X`NlP#k{=V&tGAhZ^oZ-K(zp%T&NtJyuNtLl;-+tQ}fUeX5%0mpzM=&^Kf z?Hv^(#WuqkG4FdeYnZxz`MK2ZhSbmdmj{)8CejImWc=w(?@;Fbx z`sBq8YTkQ0Yp3}ZvnTBn*RA7!`DPELfEji~>~d0Z@PO=WGoQ)CxXCm69*>yS1EYB7 zRCafENZtMwpp)*_O?9Y{y8I7-{U}%g7!l!A_T$*yV%sg{zfPMkH-EXbVBtxin@@@% z)>k+i!>47m7Z!E9Y6;=i-ewl*s|01l;47fIVOF}tYE7ed`!0_k37$jDIye6u-tg;$ z@ZACvMvjLj52{AOF^+WJS!S7=+P(U8>AW&)!0$Mhr4Cv_{|V7mPK_u;@JyR-!L2sX z^Ec4<9OGEs;S*dkdu7Z}JG^_*!-u@XV&kT*ABXPkNtl!6iHdt;JSt?c}!kiYeOMX;N6S8#%U=5jWd5&p`dx5`n z6L6$0XggI2X*1%Um;*C$8c-NxXb66tN!Nu~3vHGPCYCc@kH%4T|w8Ot>PzCp+ma#8#({=r%rOE|DX35yr)7&IMDrm#< zt5!0B3No_sQ&QbP{Eg&zuUy+v2;6QWhFT%VVmg%R6M$)|ta?+;X2YFsC2QG9f( zd54;&bU&>L=sHs~@0hmANpGtup!R1K5pDXrvqh|o794~aC4IbVcaOJbr=VM%xawDv z@R-#GP|MIis4`9f#)GB(fhVpsOagkf1yCk%SPj?s_9O-KG7$vet?$zgF zK@abQ_uzf6RiBkV0pe>^8Y6v)!w(p#PZv6|0%NeGaY-`qv~|-MQO+nm3A?iR1@{GU z(x=-_)p#5qP+O~iXu$UsG{(lkkz~zJh90LLa!PsXKAi4AV3EE81@VwxcjE29shHf` z)q}xKg4m!2`!V*Uq}fc=+;oS5Xh zSGC5@V;XkbO4W2MC}Q+J(?Z%OS*NE?*FQM320168%yvfx5(7D;LEhCyWLtWG&Q2v8 z!*y5m!agj3Nz8v-VJp;%stwdh$0XaRk){KcCW_&cFap$n!6{AmeVkxfOf<5IMZh}A z-q^~V5w_pDYrrM7_kksbgb#1N?>OzN^GTLfM(TB@cIP)aHpzpb-qm2L+W5wI zWpQR?$;rvAV%Fu(f@MQ;SGCwU(1n(k-_~e=edPr)z$4=pSe@gO2#@F`JnDeJilQyh z*(Khe+ukUcp0vbv#@W36VMZwVv&|a9jH$1{ZzOwoA(ASa~1_-RZx zQg;71B(Td#Ntgeyyve^b3sz-smaZqB*0V^$yEA;;LUhJ7+TvIBeA8ZuoV8K7Vv!LP z^otr43)c0Udsdt{#UEvLgtw2X;zflzDR8c#X>FEV^GlmY=_52KCV^z@ZvkbLm=v4c<%wwyZZ*)q7E6a=pF=mhx$Y3hrRqrLCZ1siS2jS6rBCr`4^pNAL zBQ_Z^dLdVz{6{EQ9F&_A<7;z9F@68K{wK{D+kGy{1MI2+oLJ)z=S2Oa!|trktC(&2@4=r1C*%)QEpYJ&t9?fK&3(I#C7g#XRY@zA!*hAhxWZ3i|5wniXEW!uQ^QkI+Bf& zsFIS!KZ^2rFXw`I?r}JJ#v@D(cc#I^c&_qS#r?i>e3&W?0rXNuHufs_^n#XJg%rRJu&tIA3+^+52WRPz!$Z5gfk-!tynnDi<& zkblP^37XFaGGYRIIrjTHNDR{W^5xD)@imhXL{@wSK?-kzFo%W2Uh<$-{@!KvdS8$m z^Ye6n(xdndBHv>Yh-Wp92!FGnS?bMR}{3@U<^O;oU2i_*r5UNZ6 z>)6}HIhE)=gHW$Cx0tHNI&ycj3WFQKoQRe6iCDGjFi*Ihb||eoEGIqrb7*x`G$kCl zYB`Rf9Gt>q_&|mubs8dC)GbzC$8cc0wiE*%b9&L=$V&ESnsP|8%TB3cr@rbe}d^K zubcTa$S}!6PKdHH&mi;JZ=<7WLYahl?L8*l`JEc8x0b9l=UH8Fa_rXJWM)?L;|+#7 z;M!_$yLzj=jscu%XS|>lR3;5G&PXpH&50R&0gfCH2-B8^Z86UwY-8gaFa93C%eti3 zF&2YM!t!|7;)6%6hRJPxTfOBCEELVi3Guzo?|Y_)w+_lCtIf?g+kO88r6$3?^ohD?DoXob2 zI}}PXE+B?vwOMJ=n2792)ggsWgTYfq%xv*-uVwAhDR4Pl1gKIUW-ErA)fnwJTY2X1 z%uVCA{!aDL5;z+vUq9AJA2ffIQyJnRf@JJ%=M^B=Ot&OjeCQcC(Is=mH?6SRX&P5E zXcSeZ8|Czq2Nx-wKE)2nkRnOxSf%Zc4Ce9L!Ebn9WH5pNDY7%<5mad-P&+eVFL*}9 zoI%x|fNJQyAzJ3I>4TiAk8(cQ=2iN<7++YN^6K$E$cST6X0O7t?q0Qet1E{n*C)vi zWz>ES+0h^7dVKRu{0bY?CU(bzGeKGW9hiMIsG<)~FVHq`BFt8v>nTWDRxagkgDTtF zaO{(;^)vuHG}Ea@!jmC%RWc&xHF0v|nrAfzc99Ny6e&i$Sj^%3xs>qaH?b zFH&i$@f6w92|=J;RTO%|F3c%IiUHc{r(_#^B86lvF`J$>n7H^`wgZ@_iBrK0MToib z3c6L+__$ZiWb__;&W|^hOPU5(Cis^1-jB%GEgMd1)BQDZi+A@^Q0$5%NQp0F=sLn- zjID@RRrr;IB6i`g{|%g&Z5fy4g#8Ygz*P!(9&?6+?*35xS6lf1i>>fyuF}ye4CB4z zeyWW&WcskWQ7XIU{6;-=rEAnOWz^oc?OHTehT#a&XKZ`)u?AdV?OutL;wweVSh@3j zymdSU>!r;8mFAq@nbbx=CU=91Cf~~3?v(341R_#VOw7!Ka#mJWfbZ~4${i=6KSgAg z5tv)@b(4fwXy9}#{S}SwTklh(JxWBNc3~9MfOfUbKmRDJs;Q;l419a8fta#k;25>W zcjvlKvV6CI_KpSg-bp(C09*;~Ty1U~pPTCoZL+I82raEe6hI=7re#sp1850j6u{K} zR+%&_+`41$iqh^8ka;KjV8;7SJ-J0s%V0t`44=r}i?@rNcp8+Mx<-3-wk zDFI+4$nopkbr_byopL+3rabd8JSz6;auUhkmn0BdV%+Fi4m+*P1fWeRgvZMYI;eZA zfUER%jKmT?WC{QjaNRjr07>|_tgv9G8qMSv%j&7mG!i}g1Z$;nhN_fmu^P8zPf_j0 z$U6i=1GKn?c;mA;!nFG1JBJX`GAixZ$7){s~^t( zojU>oTV_bPS7O#=bUN!{ey0v!Aqwco7Z4@AkZ@1E)8!@*RX({ZTF0TWjH$ZQH&2&% za*M>EkpmO+fRH->&=6p=mT3OJ?m!jNHc!m9L%an94miw&da3u3_sb-K=>;3kX>`>;z(JsX&v-h(@YkUEt&ZdtQ zMgDgolGjpTaa;Bz2MfjpM6=QZ)r+zR|{S%Y?zrhAI- z`r&2ji6-0dIf{aw&~bt-!z5p~3k2XmWXybao*R~Z2uR)VQDlBgS889fP!}Rje86xp z_sGDkE4m#j2Aq-t^YQQZ{Vd=YR$!5NFSZ3czG^WGt}ji6r*S3%)DJv!@mIh@Z`n&) z`2_y?_h5prE>QH$E`5CWmH%qE!fMrH1pK2a+5Z8ElvzMA4}n+bO*#RQ^S&(buh+yZ zZ-Ex!`frxwKEN?gRKBas)}f?S?4kaz?6&{re(XTV-EWI%`yV3T|0(`v2I3`}djE0B zdOuwEGxY$5w$5YTVax+0P*6-grXLn$1{^~i(~R@&-w&k!ipc-Jv`O0?Kt-69ecP0g zu@x9@I`>WgSM$95w~_vC4uWcJKG(9N1Gl1@?r<(O5p#`uEJ`yfZm<%(Gu{4L@3^kTKWHz zCI^gY{~^oKkvHB2!)SuV3GVtBNK!v?hA86O=MjT>RkFJO<>9==T zW&e(W0{~tMMWm!Qt0*4JTI>a>E{fRnJKZ19kEK+6iRoHc9Z0nXe2G-j5!m;ORY5bg zdca-PR|4*mGulB1q(uxshb6azg@lHtzZ{DPiq_S#d>O<*PDc1z@E2!WfUJ{T07a$E zfQvX`jpOWQR4Oo$7?VB$?vNXMM=6<>1z)%da=JaW3qd}8uCUX$0?5~s?HVbj9q1=f z03+;!z#=L;2W6}!6V+?F1da@o2L(|~+>pUF%-IV`=Q zMQ)to5w-ezA0Wque<+opy))(jn2`e(Z;u6B&k#+kAkNaK? za(w}qLJB{9G*4+ON}zxGUMZl-hi*$f(tAqVdqLZK+le7H-*j(oaBF?sH9^chVkK^k zqGKDskNZ{XTC2xqxZ9F5pqervvge_fveO&=mFbE(f53Q7Yq~5=`*6FesByW^QGfis z*Tr9^%AJ^4)coW8%M0^_X7kIKf3ZKr|6w})pF^7xM$N@T#itj8#HF3Nd4aZ7n@0-y z-(0_*`(Vqpqpm1(8Rn5~$sT}9^zaUs^rpTXc;=oT^JPF94?=w6nc($BYDf(rws!RG zxkH+BAslHssOUz3j{Wk(9|n2I>P$9hbF89mcd zY&-*KNNvGH|I(10-coF;tmm2ogw~F9wn1VCU{J%n>kCt|%2J;9QqOD&>biS{6gT@* z#fMZLUgkjpx@I-BNr6{G%WV_smt8>_tDvo)|0bu?=HNpLZ{?)0eyJIs^iEa0rpozK zw%;uTdGVMS{TtqR>r-PJx{QzSvR}kU9e5v(CAJG2+90j9tvQFETIrhU=t=&2%<9{a z`&vDswm_V9WCd7-QVEv>)TP35fctMjM;%S4E+;$Up8jppHJkP)_0LsIvg)E zGec{BvqpnNepBuwQ>dYaA-OUJE@tX?vEp((qNb5@7YcSp7_d%rZheo}rtjgQX{+zt zl;(Wk-fzI#?|(q+zbF^4{+;7(mi%E{Z0({@`H=M70cpysg@06iIndTmwr|D@5?t}8%h-A&S zBFzX60t)&Tg$QhFz}C8)o@`!Krk-beNv?|j94dHob0mLT2?L->?)QU|sr-PTQh7>N zCJ-h`8OF@cW73a8?vUzdR|`R8P_JAQ&vO*>g;H4D!wba^Z1tJv9ULa!sE`wcNtR_{ zQjz)PXp)Jc#6?5h>rb*k2qj1+ZsL)#G=%`eIFpHUCymQeIENI4G{8T~V{tN!g~|YS z=SrIEU>p$h?g*A7=Liv(3=_tJ(*_0zv$c4C{Z!#DpTsn+d;CaM4ZbJw{?2d*zMK)nWA3Mhu8R`aN_%U zFW^oud{2IvyCeTNs6N?*h%UU-H(h}fwq4`-@8cQnMV*8>Td8d**yExrU>7b!RKcv7 z?h}S3yr^R!^!&6Bo8#X|0BIEvc^cE!bS8fc3UcQ>@|nLfvta?&elMScGhP}y^J`>T z@W3lfdz6E5?XhH9{d5qK0?nxExDe>@p!l4p)x^c(VePhXfLY$gO3eh5Wg&~_ly&Zb z?Kpw|$Z1(S^Obc_Jy6H2pI{HB6Xm4R=lsDU)mCw8PTZva!;O2?sd<5M3DzkY3vKmi z{Om6?=P%Et>ihw(%~<70J40u9gjv5OF2PoLF5B=Wg9R>=O%OIqUxexd&i$-*7Z4|| zwE9u-OZ%5NAEqwWGUqFv=!qqsxro!PEH4DU{G}VD5GKMIp|GX4cb;o@4i+%H!n)|3 zCha@EyJak?cVT!ke*wA^M^^aF1m6tg%y1St#vK{xvN3= zL&NY$52V&T(v1P;=@$&Z~Lg=_IX?!9wY#R0zLySbncyhzmm+NimQa|vBv zB0v53rK{Mpy+Q>qnxrypqQl1lDfD2^N#fjxF0#Ulzp)DdlG=C_*y2*32t^O+;1WUF zmcw?&aBS9p=mCbI@x0Wq#(P<>K7Oih+@(1cHe%k;maIW?M1>4jaeP~nE*JLfFO@cvoDyko5TsMWiFwkzk|_ip1fg%ww zPF}wwGYY%R5-`Mj$F69LZ_yIjk8RzW8j{Q^Yq@NFk8G5ghZ8RyOX@!3P`u%H=Vn%! zJk~DKQtCw-6|`9>WzI5>NEdqOB4BwN2=kR+$z{B`dS{k3@`&7==~=*Dwgh%Zu>9@C zkgfQhlZZB?%|aT#U>5|6y_O2EWaER9c2HYCN%+K6?5xZCMwegv=}A@`srVx|pH$Ke z48XAHA>>cq{#~7N0?_nNwxM> z1>!nEaF~y?8ttmyfzIP}k9rwQ2ion>awXWZ^dr9F_Y_G6qTR&bkDQ+meqOX5z-P;hm%nb8ccT(p$_ldmC4GNuSh}4dbohfL4vEkvv@Hb2nlD97 zw)D#aetSB9liIL7@|g%uX}vL^&d2h&lmm;oO@ZlVv-IXCb*#s5?sE{a6oPc2gD^BT z9Xf5VtvoV^VMa+<=!L{oDEI|&QY{x*Ws~egDT$6_#qH{MxQ#1s|9sVC*VL`Y{-{e| z)DoNQbJiH=(JM~k6;1$>zODf8@@`U>7&(^xb=D_<aI_nTD+9y{<2p1N z0-C&NUsv%z=%CK!cRIB1ub+gu|HW5zd+RR4W7AD1;PxSCU%TY)9Z1Y}zhRXe! zXbF!u?AvMv*D}7g`^rqhIUJ~opjk`zov5{|^Wp7zORHy3&>IuYD{@69% z>G5KMKK!$@wXXJC>GP+HIG>WsfR4=XhdD2h^lAhC5_l=YGrDqyfFS-*>xzEAzO-K5 zEcFNZ5iFt-<)Ht~_>gh3g^|yN%ROY4E;nHB+b-xY6mdp; z>1X)m{=a^mC}Ut%dQ@}(T(ywcjJz6H0u=bWt_`{`nM??_kK!27F)+A>w5=b&-p~P8 z#=*B{?T^%%(zf5Y19E+51dOu(i*(WdhS{smH4GR*5!(RxY|0i$?nnX>po{^BERa|y z{4TkQ`54Hh_}8Oz1zX`UkE?c=l#07E?b|d{zVjMYz5I77X7UGy(|caPSjT;rUdQO# zFI3?;D^+)AeO%^gB-L9#{2tWZ2(QR0v#ES6f_Y;B4MybwelG9*)Za{BfOpI{kvSV6zXH;ey z@D2?;nP^_D@Y|%P+?_8g5%K}igJON@0k$Cx!J6b>G@ zuQ!m^vi(=pg`E!H`GZ;};69pjflHM%9=@s>ThzKUIvg(q{0@jb1Wf>R4zvCsQ4hfVSiN}YoAZYfL4)mp-jkyBXzS@Nd)-od%=AKzLpzt`P? zPWE}zOJ8zvGuX+s?XdzCesMk>RwPiY#m9fu_AKD3Px=Xq57M>CwMb~vy0rQ%Lp?(t zsWR~m=(9PY)ki~~Ytm~ORwtV%uRumT=PrwQ2Ds39-s#?44`kgT zBO?RaKUsbjFs%4Keu@eyenDUI!A@lQo^ccT2NC;1qKnG;>EXdnpylXG;mLNtA%H99 z8G{{F!>e!d{(f-?s%BqTbXndTmW}t5)T0@|XxVwe?!RdPPOa=dLR zdzFmjYs)TxjIh3G#Rh)U`l>3D>{s9{CYQMt*5Qft%dnBclAtorgQZbO>Lbk_7(+gW zOehaoFnsHO=X^z`h)NWU$BV6)c*ZhYJa26TmL$s_4rG^=k~C1_GB&Aa@XgZ8|I!gRpwp4%v%aOt~EF_c*j!Fqm2mzts59s3iqL-Uo|akmDVDk5NJJ zV#Akv@UF%*MjUm;g4%sV+55*QiH-%c9IJTR{)vZcRTPqlu^IZnHs54&pL&%($JIOY z?eJ-@dN-|hZorbF$w{R%c~)qaO{#D1>n_s`wYG)uSBA)BQdr)FI%Cf(FK9u~;73hAp$u#`<9o6MT&oItq$h$~9 zN?WTxrOhl8&x3DbV-2Q-n1pQkSBRzH?!pgRfSfmS9Wk`zL0t;nqQwg%*!Yr#$!SF_ zS<j=`QjAD-3L)MU3HtNkd7r<;RW#};ripuchkJ66y!dzc6y*g4^A zhJwVu;b=asF6~_2U+BSO7(3@ieYf%qK#+emRUc6sC5W4E|KaeBW99LycV{?K3i7SL z_8u-_v5?gq1WZN;YBV*9HX?4HQzmMr?-PF!BblkG);ZHu=+oOahUfxy<4e3nKx zBby70&fn|%)2m8}ozJJs-*luZB=Y#05fdtRC# z*Yse&+%=BMj(uPB0eDyyziIEu%>xeiof;A!HgTa7!nt3jLVr7CNw5v+r8DtG0)HQj z56BpUvYC7~hW1$B5hM3z`qV@uMpkc~)$Ft6#;W>A_{Mj3Vkn37$&BU;7^)*HXiR~EKBzT1%cr%x zajarnyIMBDqU|5CL#9*?N{_rb`<{H-ZEh?IL7#H0p%Blf2qDyUURmDO+J)<8hqbG> zYY&Lk-`|g%&Jro9u&L579d}B>&XR0rI(C$rU*jqg=R|Q*Q}&WZf_+ZgZ%kh+%ibK0 zQl4J8e(f=z$ra1swegi>8Ga0185yu)51i3@*A5c4RZmDc?cSa%Kbl)4n>(^yys>RI zo^Ezjx)rA*X=Inm_R4a*-;kDLHOjXCZ37020Rjj`;%3hut$+6@(LYw9DaSH1=dR_8@5mNSzPL-&!V61$YXc3JQXCMV$7lwpVG&=7aQ6 zzg~{cnasY;8=7kIT44NkjvA0U^@vdL$oUz|`cboacJmum`Y{ZBa0tB!Ah2G&E5 zoXY3V9Eg0q?06LEZtQ8cjmj-mWF{^vy{hWe2phBn|5}NixyV0la-rr6IZU2qiuHd| zV1Q|*ZQ&y18E1dH?AaR5@3GlZjn? zKP0;kbarv1a$k{~r3H@v(vB_Gkf$Ew9qvY6=`0~@Zm&z*Cc-d!Evqm7ms**Zkd~}B=%#FnBiN>4Br#m#reiH z`QUl4?zqJg4&<{vLwq*xe?}pcb0>dK4oYzdy!JU}S?~7Ni%^r*qZ?8W5|M{N%kAY? z{_I8QviJX9yhRts`!p)Z=apJmuKv&W?>DNTss6X%KhqyKjOFfohUq?FDQd1q19#7tnmzmUI`_={p`)j#v*&qdtJ%zu z#-)yQ)uk`qDL;;}&Jc3z6S$E-PM_nl`j2OHfw?gWh(yk3zOuNlYl~t>$8suUcv|C% zt%jfVqAa>ob3kdeI)0;<{j~l~Wi)|;Lm2_vPhbM23cbl~7ho_ZS((HjTQZjkzPcHy zKL0N0HH4ZW?NEq=F=nhtzv_9Km88$U^@D#W?X3a zpA%kML7lC4v6P|YAoYAlhhGOa0yv|Q0!WU_Zz_!oZYmFv`@dEkH118&gTf@(sM+8> zLOVP^iK(a-9ZNks&@1^&2R1~ZPN4d8>r&R1ziZ}8j?6L_-jIw6@cogyZq?RAqqo_y zW!}ozA&aQzxP{h5Cp3(fTKx>Y;fcecc`G4Sj;07|8HU{)z8>Rxr7xt8HY20uftBA{@sEpY3DB z|1aC#s^U$|$K{m$%brLJ@bbpKx2F&YR78~8mYPj*%TO?KDL0Dm{B^gS@5#XxzIxXi zQ6oH>`Q_#Zg{n#i)k27FVIX6$lj4br4M~!-Rgr;hJQ%{afwHq+2GLb|eK$N`KaZi1 zcKnCe{#q&n^5l2X2)Ab=DM`|gcYeGa>`ayO=;!bA4k}Wi)Zm#%e20$IDlsd|XoN|P z3%d3vVo=4-;LTSMaY821Z*d2=;y+1=OPaQwc*ej{Yu^(*a(kMtWh*;b#OLHyRc9o3k`Pe4 zsPu+jjPGCRMAHkOZ`Ot7U((Ziwa@a_KEh;nYX|r(R<#>K>7;k)PCd~#7MXN=BtA&Y zXF(>-jhu3Z)ce*+=!Sk$)uomBa(X2|x9wL=NN`pp!gh%+}q4BnVt zw_`7>sB+0GmKW1;3lXURqij;a?T*qzq^>rM^nMlCAiHY^2f@n#TE*XyMA2>WpraBhvY(h*UC$N4Zxrb9 zMDkuJO`aI+X7GXj`)?3?%8ySG9FIpO1*GM);sqv?^eF!kpPsI{YDIAp*&GL|#m9X$ z`;&l7Iuu~Y%v7FcpBYz8^2g5}9V@l#e*5PY?UR%MGs;6%p6FY%S6k_aai?x_$d5+) z4DVK|(JLh~uk8CyjxT7qq(HxNe)4gnJEx|5k=Di^mEK(h*NPurxq{6GCv6_!c$<7* zwrwcGh@nI4d~UX!#^;C%lz(uTW|`yPGG>sTiOQ~4YdQP?&opxbDOV|&EGn~gk28NJyq2LrEx@jhQ`lFxvfX55TQT8*``s(e@b78y#5&a zUbboBDOLQRn&SCjO5#z~Klt+zy3$eAttfvq99%QS50b7>^6W;RlCn&n&4-*dZY2w* zX#RXrN-B>(B(_V&pcXCw;f2?YYH){trVT6STdB%^TK}*+Xr#gjKCx(hz(BAQudwk& zhK4NlD;h_PLdD#y;Cl8f?Q>P6U5^g+Z@(mKyQ9ZM7;YWqx%?2wQ~g^+1+2OCkHw7a zZvsa&0wGoogOwC}zss|)lszEyts4vgQ)M~^R!I`RN4kHDk(#J89YB=xeC8apXaGa; z(U1nEEba(4RQpE61XEW#;5{FKNit zuvRHQ>h!udDrygc7P3G**mE70I+d36EKiF<>^z%a*AiD^_8dct2Y*Wq%k&<)rG(C$ zf-TlhHA7yMe!SK)81wweH3*66PF0H!5T;xnl2l;4im_hCmO8;FV)L-?e)E>lbw6+| z*nVd3)Slj2$T5M4%je6(%Y8+Wl4QP-6Ehz}RHI!;f4Oz3&r^!qjyY%SS76+kcjPNLPamWGzrYB$kdq~-BB_@tN*$#ouN>c zrftUV&p^rhE=|;-%v52~*y^ZXds*eYOs!Wf_-J)82EEI;x^q-$Q@eaDs2Os}c&rhv z_DyJwB|5y)Yf$X`%PU%;*>kIHe=$zAF|gSvr&!q%Y1ZO zsk?OzyeDZnIQLj5_bbHs#;@TI2S;;u6QDFJR0{zE zgVXJ{M|%|08Gh)Vm&v1tN>uCO?bEATtv+qW%S(((kE~u(x|qGco_oC{7F+lCck~Ya zE=x_*b<M7xwJG2S7V6^lI>L%_3A?UhoQ0e1B>EC>sXq@#-3c`n&5<4!`Xm z+lzLo%UvOi(J>fItTH2^I{n@_GV+?lWv-|uH(6YIyM`F1DM35Ic^3KJmtEsU2%Gj8 z+v5!Fr2TjC^JTreUoEunQw{u@T;?6}@Ju%iYlr zkqpaAV|G(QW}d{UsjO0GNb4Yh29r=w-SS74nrK7}9R&Wk>5qIA+7N|$bfxjq+%Hx4 zxzUc~^!r`AK12?`y>!FTGP+qpC)-Xs^%H$FGkDFTKSs}^M9ow(??`$x=E#eB&AVzg zgN=AQF76r|@rF%1e!z_oLOMTDCjt4E|2U~vcBF9K8|ERkA|wVVu+5G{FP@0|&mMnA zQiXKt;#>}NP4Bm@2Wer?6Q-()S3dwfp&QO#38%q!bE|r)Xojx|Z}g;D67qYYzWt`P ztX1Y)m>stm-wD}H8zhIqh)T7}UsMF^Yu_u5rokCh7G$+Sk*@NG?Bd&B!Uzo?ZV%NcH-BwoPE&i7)#ft-45V(aPbwHQT zYOJnUv?H%fff$>8RU@Jt$4@u3qv3dIrK9~p6K%jS zsv`@&F5dD@iB9v^o2|Q^`jj&Wj8BbSio;LUTXZzDi?!5ppfVP9PvG^9C1|A zXi=&o6Agn`u~SKlM^8iv-}rVgjY&=DII-zF;!n*}b;9kFGu#H>q-kn8{c0R_OO?-T z=k#&SH@_;Lb(+TCb3`4#_uLOgw+jMpnNm96pOUWo95c(=(O=4{9=LgPNpIqMx>Y@U z#751$m`wZr;hzPSN(#lPN}eQ|w6gE>Y8p9oz4xbk!fI$U1$U#rdB}epr6C+4Dk*A< z7a;J^fE$_jJ~pkVcS>j+OZ>Rn*<97s$XAOX{f#sHaqLjCT9`qlNy*1Amk)~{(NL9} zTL`wIdTDs>EB>+e$cS&W{R7I&BXUnWBF^JbgUPL|B5zY>VfDEWId`?CL zuXgZ46&@L6O^RkP`+u|=tBs3p{2YAP0uEQiH#|7a(Z$!)Mjer$@zaBcdylLQHl}3W z#8nW_R5nGwZ#%G3LnESBL15A8Oi<7GNxJk7i#F=&I$vUs*=%;-5@nHU`pqNKgFvUK zNq*+&+TGdM0&S<^q;cPFzF2m;*QL^Ge`n^Wn%BQdUOzH& z=tY!z@$BfIQ9y0$il_0dU4H5~RVFAkM3^f&YBp2xyZ=eon=yf5V1yc`Uf1e;_A~A% zib&596%$v%D!FI>&ovi;!0EDDtPdzWEavHoQO4kV$XK#I^K>t#4xx1b!vEFWn%z{% zv5(!0=P%{wqVa|rc5%E&R=xmE`By-;i`T%cM>47)~VYwU1J8yH>R0rzEIQ* znDkxfzgXPRXCZX>hUQfku?m%KYi?*3xbEXQ3r_!Le`@b%elnVFu^QtOGM{qNa8Mg+ zR-fzDAKB_N1e#w4chE|(pp^~g~682uBY>d}~WWgs4 z<|N4T0r~Fv&^>oW&z~0<@hyKk8Rsh=EBn*blbg?q8C&9w5B*L@We@1aPX?ggE;7Cx zKhFF_$jB<8(|zI|ace_ zZOU*yj;N*xYljBNKx@j6^==^v;d}?AH>OaK6PxI`zU!N=cSd4#;fq*^NN+|W*r85u zmBL4Fu*r*mpkch6zPV`W$CpP}jni#hzt3h?yzCO%=~aluoyi!~nVNiyEoL~;VBF}a zU@?4$>-ixwJ{BTn1fBJJ`r z4WcrKhx2NBFo-Jy8sfbz5b=AT3h!pbXco=9~4;C$Da=oX*DP2|bE$-dAk^ z^<&(O(rY4mS$u!7j%;pI&zS;N=XIEmS=v4PPct>{W8yHkrsw;9xBS<$xwmy(X0f5M z+hREomg{u6>tkO2|^OW{k#HW^FUT=(eG zF3F~W=|>Fd5(03)>4&TG(P_!_ieZuR!$uD8G2DECUOTZ!l?A2TA3d`beU(zvEM^iQ z89+i~$)d=K9%JuX&QAJF@GhaFUN1x9l@~mbgnvFw5PdTRsFs{zEO&Z!NuN}2{_||W zE`oFEdNqHteO|`f@j6M0sd^Gg(miltdF*$PmLz{ty`ORh__9>aze!res-BUq4Vgq88toh8fA4G2q z7l~nM6T0$aFM{pfMrD9s4l2A$4I&d~8Kus+@X0i}R)ses4#y6z7PTxeK|!~?H~eI) z!?fQy%;6I+SdkL9NE$D;rLZHijK&hKoO#~S>xOm#l1vaGSNA1P&5ArS$Fo0TS)%#J z{5kSH*>WWEYJM8*0X_iwoin0x-mh&BCP#SlZ+z_I07|)Hk{>TbhxyRfV#t&XL5?7Gp-=+$=MTT0wLHZ+W`u7iu%Nc9O0T(~>9%C`#Uv zCh*ECRyDgwsL2P%VVt?C_xfE5#vzA^McVbgVVdR{@oue5ZKI~}_07cT!sf#@5{Smj zj=B-M)EBSN8avbxh{L5BK_AMi556*sPfC1)`fRr=Jw({Gek@IxU*8frvyU_(uc6nN zIge|<8CARGJ--`dNbIf;H2G?9o=k1%CbO++2vbvLgCXja3`S?v@_Jh)-pcBjv%D|G z*h{#S`cv_lO;RriIg_@o7JUVdKR8RH3#Ac@!Jxf)%e+6tU?T4^`!B4edhro89m`_} ztQo*5Acr1jh6aQd-_HrMH}!bf2^w9gY+JBz8q{tzhy}JY;ikP_A#-+bAxg<>dzeCl z3~;wdcZt8BpBLL8>J}z)d^mY~UZpqZ0`wYC_}w0i&=7d8rn~} zHWSA2&E~V(=4f~U-`=`mbdp=rJ{S|N>vB!ck0<_%7O6J#1iFlVWtow% zytP5uQ3?UmH>Ay0)2$kyk3YG_;u)FkeGFj_lYG)*Pbcrcq9){KabgIV*tZA4NFt7H zf5-FRNAuAKtEw*j^&~*?G9vu6@VQpNO|g8~#dhs1zr`E`le)V0MyOw5+Z$86_DOBd zNo4r8X5;JSl;ir`;dv3qs)^-jZJ(~!XQ_4i#L^2ZP$HkVB#tQh(A z*es`wxdF7s)^8p7cEc(VaRyxQk<515Sz|ZJM-k*E%7X>jyy(^CfilN-hrG*#UZQt2 zzkSevc{lJCel}j*pI$Tn+zlIYxo6^YJr(L`?>$PC3O>$6kCJlxwSVso`JKiYa^Ui8 zj%r|!PI{a9f%O7;H~$kKv1)7Mv7upRsYmT(I(m^0dml}F#LP+SLcL+TM_U75$nVtRPJ@1)wc6aul3^M{I zB=`OMmh1Xl1w$2T`xX(0P3qqyn69UkC7(AumvKl?)8kueyS^Md?ZC}@y!JN4hAtX; zytmn|*~(d@qG}b~ZW+i~JSa@o3J(T7hj4Wv#dR&4&w6OB;7`*rD!$himjSaX=5{`< zO`-GISm{z%mzk8$k~9DQB_?XYtb4!HmZx$GSX&W2D2_hBysxhBIs3qYdu~Fnn;3ZB z{Fq(mU~ndWzsoi+Y>mlUuwwoVy^${SQm<*p(nDG*0Ct(wV>uwwtgxzq?IJMh%`tBp zuf?WIo}GYuQowtLOVi2^}mHZYC$NX6A8YGLLt*W*jrUfNllQ%DR16|R-AKFRWTrTbM zUP-sc7UnYD%OMvE5>&_&(ql#Zu9|HgiX#SbO?qCQxqM7!SQcYZ%RE~PY0yhkW$qrD z;*h_tUyLZ^!*2u&N9$T|&(eKh|Bjno9cl|{!?uOmnwj1QU&-T9DnolzPdn+&$@l!% zUUZ_x=jLe`Embwmk{Va5m-j6ec;8Va{9b@{~`Q;)Qr8J+2k+&-HuJ zSM`aXOP5(7b@nO}C<&n~*e7rR^AG~fU&ninW%gax&e8b}~F_h}=n|RVM_|*tvvZtH@%V056Css>=713(y zq(zzre2>+*=iNA8Inmm`IhW}qpCcamcXX9?2@_<*-SyO?m!!PLw>3UyZMEI%S=K?< zqcHVezJYS9#ZRwIrU}RKWBIHGx+#gVY`gj2$TB@Lf2$eY^-KSK`;5J5o8i9?cLk4c z*K@jqToo%TbrHqp`uEGkQEI-BH$LKRNKg@gToDy!kq z<#=R0{YD!OTNxTF4!)u>miS%mg%%NxJkyi+OE|m0gUwMl^4A3Jf(*Nm@-3Z@);lASLKw zFWE3|22Q)Z(aTV(wU4E+MUg;B*SF~ zNNsa4(n9Tp=E`o>5R$ANa#9yxSD*S3UEj@ee=D8qo1`W?C@*(rGT`bnhHC8!ytt(( zE&o-9{b+bdv={smu_y6WabT|eq1N*9U7MnVUtvmYmbui~ZBDRm0dP_XcK#`5rt2#t zN&2pC+Ka=and3^na>|+>k)oO}3KSD7e%cRsMt$cbTFU|vtNy773B>sia+~Mh{bA`0 zX7j)099jLJ)MkO4q;9eC9r&?08K3+5WYF63#R-XcUH=OjBvtFTska<1j$YX@ut@6|FA@irmL@B5Q#|}$-w>=U zvvGz|>z9yFMlaLNKqu7&QY>WTe_ABZYMO0mYg1)Cox`fGzfIoo+q9J78wwcMU5Paz z0(mweWK){hhdM<(c6rx+xt!0ot}=A$2&b&OCnKERkt$xc!jM} zM$+mhzdn(T|K*?afVlvJhil*NrhrwOybLt4gkQ+L{F32R^9$3K_Z?EZIg;kyFL}+Z zL%b_SB6VEX~Ow_>oitHS~Q)hu8%?u|f+uGV_@n(lFXNN39DZeVSv+ZQ7 zr77l$e^g3+ck&3?8;K;>=9xmP!IaDo|&nVB8L3&OLPpW8Lmy4FVT1GO8ICXexA0jp7oS`RjF{Uq2!>vwi*wl%43m;QtW{h?>ng+1blEP^W<`ZM4Z$- zkSJa_w_>qbabtJptYZR!*aKO$eUuQYLKG?Nhv+Mr6-{v-tevXW0(-uKXr$9}J@$-vhRcWsJ&X=(?68-ipa}^zfZyR_l@*U052hW3c&Myw{ zRkOPU4jHByJ^qrJhc@@72p(E|_*v&fd-?f=$H!N?6JVBQ@1L$l7ehrHuJCjzaQ#q< z6vu%vUr6vgQd2bJ9} zS4uU9Hf;#WL}>B%u=!n>#9>bGn@fG&*+8%7_rJ*VR$-{(yk#4`cUClh(2zzl2ONr7 zP_}CeXt1yNwG2gv`d^|fD|Ss&NX3}cn8qLa;S-I$TtfSfRQa~foX*L|6nm~13my(@ zBT^0dx3MRu(7aQ5A@cMbGI7>MY*9zg=<%ZAV#L|6L(z+m{2go|M&Ie`hH8WgNFoX^ zS|Z}=Awd!Qbk%ce3i*rr$tr>vI4ne_nIif%B=230RxEfvt4YwYjhivLV&4d*I-}C7 z!~4LP)>kk~BK6449tCcVTa`EMkhGhr(>Xdebl3l5eXXP=vJ$&r1VKA8z~F9kyP(B- zTYt_B=LLoiYtcl-H^ocllh^Z$3|qUD;O67^$Pv12Z5NB_QN}CAQ;o=4(7|e)PXfmG z^a=}w0WC2Do2dvf3wGb(2I{qsMi}#_oy-Y~(hMs)h0i*%;Brz$^XuUK z{&Yl$q-4wJQQ17RIk$uOocdAnYJ6zIuIihXe_&U|$e3r-Rx~-YvLNgvOF2h@U&~1H z*qL(#1QB6J6xb~allSk)TkZ?B{`M&!Er@vaiD3Y)c-PY9BUrOEwZCZQx)!50gFY_l z2%Q~Yv5fnBo`3E6NMNWYA+u##F5n~c70H)4{LX+@ThU2ktS+`3HUutxgjib}_xy!e z%SONLq4*(u61}1iD`LqU_7X0ye>z3v3W?nVIh>l|yc1W>JR1wAX6V*-)L^j|(WYMB zFZ_5Ga(vyduz00Z_n^?@Jcmx&tvyQJ%4_)kWTD4mdGuCC;b=9Vyqe0E29?N{Vm@S} zh7o;FQXFh7^wond8$?a~?4)ptP!1(iJNYn9x7kE?xH(LX*uWxV?7r$`sG6ml{Yk{U z+UxWk--n8l+dYAFlIBk`YZE1`$9`k_JEhOX?x7|Z9R7vZgLDTRma(5|BjakkiL&E2~b9gjl6QL zS6Ta8^;yIYlC4O(jrxv4ZI*Pih|QV zmep5Tawchqdr9RF;z<-JXZSsK%kZt2wd_|ZV}swSpBR2D(m~np8!XBO2*>IK^CZ9E zYf=sq&k3tFSn>E(negmQL^6JOdSc6^L4xA`#>IoWa{ZR3Itv4oNlOWDg&E>SJ(jK! z89$)-FAN&r;V{SRGmMr9f#9mJo=?&{{7k&(v#xz!LK~_+KDvv-rc(f8AxFQGhZAk& zV8;s&Z!3&|g^HDF6Ed1CI-%o(ESXpoh1rSOz_oaPI~xYqADBr~{vI<3_scS2`FqAFsmXNhP_NO)a)a3yjjQo2dk?5YU5LgT?=!26$IzM9 ztVk!nA9_&s=3iTn4TAT-AJB!=u03AzaX8ONbgVNMb7{KQgXh7(yM}nIDn%K$zErFZ zgM_yoMQVBxhAnUOuAB5K0`q1bt!RIoQuliloE)`t1;cmDfffI4#)5F6^Qhxl3mHI* zNDoL2Q*)XlRfxH|_T!(Caj9zmzx{Dqm^=tT2aC-B$l+=KqD;^CQh>KKm|8jf3fPz_ z;*Z7`Z=~?MR=CZ-rJaCXf&*|j9}T}!VFhp?X5Ii2_ABD+eSwZBrY9XYc7k01K*|ZF z&h-jiQZf_+n5_ILfR(KDd!sPDWAp`w>9#RIYbKAB18^G_00)%f1)Ikk`)k0N-Ep`w zfH?&SA!4NRoJZc<`72Tjl4#rE3??0^Mdb&jSSH|ob-`s{pJy|m)jMHr=jm+^Vg3tuIKt8Y`Oc6ZA%!PK zs2d&$$lmQl@t}*gTdV<}3FxTm56yfw3VQey4kB{3uFrd4D7-ESG?2j=y=#z=Knv{v zZfpa`w&O`-79w`<55@r*WHDSrcc|oEO~~TUJYkQeBtWz^^Zl&=XQXDw4t;*P#L&hM zyY9=r)PP-@yt`Phc@V&he@Kb_ayo6BeI{at4q-53Y^efx)IA79z)8)zy<5!z;HP~U z({gz@fN=p}+vVi(CVmIqqhwufa=7gp+0@thu#@R zG+COVDyt$nKlYoZusvF*ZLx$*mY+fP+z^oX=8)E!cA$u=mE7CA#tAV)lJh1ekDjd4 zkU_(O>@B0>xYV72j~guF_6p5BZ#F=nDa!*bYrKbwhMB(gt>z5m4KqPnQCBpqrWu(J zFyKTQ*K^NidBv#`sB}A!@G!;_qh@cH3?oNN@v?wKL>RuduWrhW+Lg0Vq~VhDHJ)z^og8VOhV~|lVFwW{ovCz8Z_sF%=MNRhY+ z`_F1eRcHGUS3iCHCP)W-bgOMV2=Qz%B7c6bx_y&l1v_8bYalVJLQ){b^p-RWa@XxNi3&M*@YT>9PjT~BH=|#%T;pn%h6suBH ztbapaLqaCBal7OXuW>MJQEo&y41fiXR9Zrjtc)ekcqB5L*=XMrvWRt?5oS_YbG{w; z@tk+y33^+ouI;I_Q=nBnumb5P)TksjGP?%6?aSQ z4>mnYQIAhob%fyC#cTT9Zm$YbYE&&detEvn33WTZpxj>adPeFbh4YDq1w*d(dYBt@ zR-%31KbMwqEzznp>mgCoEv`&_qF}$2KjGZ}G~`85=#yeKWYCplJG6rOdAjoLid0w zbPbNbTm0GqQ0^k+cMbuqzxdn7Pg7pL(rb43z4TR}qbHiB^R)G}rE1m_9Ri$6oIXhL z5|1jt_AGD%g`fbwaPY<-Pj%klvXGn#;6tuG0M;$+*##gvL|6girpvrnD>ic2zYYKz>lZQIR=KO|9HXJJdqY+ieu*f$A1^^aGX6WUOGyxl4hB3=XW(z& z71OR@1@KYCs7li-8E{$tC(}~v`mVT37(k!@_X>tx&XH&OT&uVu51h{heys=5;4Zf~ z*(AB@1Z*c{O%`pJ4OBIRQ*5ZCa8S*gFU;|Q2PLu11vX;2Ca>uI1OXbPEA5i zHCW~OMHA$?_V_!+mpSHF>n{}hVJ&-n8Bb2ed68By;9X@~1pE_G9^4fEp9A7)iTW?l z0R9ZgyWHe=e)xN~=O3=;sEB4M4gl5$o`I)u;XS5I8Djkbcg9lnc8#mdF;~wcxFv^G zjLWmYY*{ZSK>;?Fg?bk=DUMc(VlvDuYCgbN)>#hiW(jY2i6+LKfvi%+f};Ru_ zPVtl6=aEZVMDF{g6^)N12syC*>UUUGiuRiUEQx@}x5_~LR<{=+VYHcz3ZI~^;}5K$ z$?qyD`;W<$Yb6GyUmvgknXGQR_*>cYyFBy57`HOV)qYr{D228; z?E^zq15tiEL)mO{PSr0;s%X7EzyO}SIduNP71I>*#&s>sO@pP-(n0QQAvlC@Lk!-I zYI~F!7PO7dQcCZ1w0>OV|4+3F-9`=X`Zl5+`n<*OedMv#ot6rAzx7z(Oqx zduYK|%7Wt`h}1CP$dx;+@~ckA*Xlam-X-+Z2UDGj#z?QGaJRY79Nobarz;*r=+a@L z#4tEgH2zFUb3LIULW~I1eo#N>~4=ZNEY<0iJ*P{BDbAs|8lj{ zi_pIQ)&!ZmRR0+guJHC(5bXzvs>~o!es?-mJ__veGf{r*>|TJE9$0}mmZP^}Bsy#u z@wub)hsyb|?$yMo!iJ4-TWL)BqsTt-mc6)+2QUing-bV$f%C2ylNRaufDdi~RaEU5 z^O!~1JLUbD2OJg3DXRKaK{6pe0w;QVsb4Aw{ENe7AM}#N z=x5)UaY}G3gDt9{MEBQh|AI6aWMZq1bFZ8?=lk8bo2IlA$ zv;vCZQJv4)Y&*&u&D8?ibAAK1U#o1yadDqzzx+B~df)c1uS#(86ic>AOKsYAor=8~ z`?(A`Lcz>P_lDn=lGId$Ot&4(-teu5&Q)dwe-*>t%9HH#K`1IrMs!~)wq*jnR2D8VFO;O2c4WfrS)7U1HJi8v?zNn2 zK(>S(WeVFfof*Jhne#qwHtF9bIDgY!z%_M!4g%SaC}`z+``TZWD5&}<{}WEL6ZB7E z^;=ZX)#6Uy-*j<+r{|4U=!)?_V%dE6V4n~#B{^4KVQ>5nk|c6{arJx_f1g9b)kz(G z&eb*p`6x(xvM^tQm1ELscvi$WLnuY@qI-ieQ<=g&&MCNZ zAX=kiVhhSh{lF`1_TD*Te*tZlYyU$wB0kVmvD+C7JGuK_$m8`(S_Z9W4?P7lsa+~> zy9`sbvNqgOmuLLx=~wS#O#G#*z3Doc`ixxLo7u+o{35`9L2LHjuyA+iS)k&&lM=!b17X&tQ`Wt+^zRiD2nRC9gTNc?tZB6 zT4_|bze=XV6d~wnzl&Esv?ASMx7(E;ukPsYl~g-|mUbR2cM@1wwfB&7WIWpZMr((n zMsGwOl@^C9b|!{NQB%+=Hj)2&7h&`-TZj3lk%d7M&rWF1Q>tD$-GNdDJ8PY91(Ga& z>vxUMhKkbR314<*EvFx@wnM-yP1KxQ&f8mSJp}M$W?M}qbyu&yL2mGc^{0gJe~zk+ zP+4w$A4F*^(k)zcOY1YS6D+H;!BPJ9{6q&>-L&N&lo{q1CVY$C>~bK>o&1^rTin@x zdVuMDG9uJxY&@wBse~AzpZP*l^sWAVtMEe_s$qt6Zq6&C!^eB5U8WI)+wqUUbCU0F zBe8Cl?wfkN3^YLmb0FB;;&pM-`RG9$i?M$bl4k42ckuI8HI5{ z3K%83?LGp>J@=YJ^Q#qepS0h7u>w-c;zur9moChV3{l+y!_u(To@alpW%UG4=IjO0E%!T}a+wPs(5q=yHjcSXZ4@3` zi{3QNYAM|7;%~lEK8G(cbv_b7F!$~8#UX6;WT>}`znT%q$j1!N4}8da)L1vL3JuX? zq@LY0nDR+COk##H==)uY`i)01uhS)c0sH=E>8Z;@| zcGtJ#7R!ZX=(Ki}PntsC2}%es758^|RO`S8RuE~##<%oODR6pg6PuYbB( z)qU~~S7ehgIeC{(c_JaFMX;}JO`=}shsB=xiHNPzhj+F^m9*i#$jIZSa$}-q=S)LU zl*40?O`MtepI}qP^FG~2r|9=CSEk%=b+7y1^p;B#Bf+^5E#ZP-nml&D)5^YDhVpUV z<`H(sOxbI-$G&Y9=6RH|J4OQ{h9|0%skF*kZ2IiM!$Kj!`^Yqh(DFNzTa6yD*TJU4 zJp1@&YSx^cqkBHa0>fc%w?nWk70Kai4kx&}rQY-qIf#7zPLcn|!4$pb^m@|GzUo%_ zVj}MC*kc>4JOvjC*Csr%)rn4*#${pWqb@*Evp4@<tjb+*unadjq78I}-ZS7+sK{^WL-mxdHGSb$85=^9UJ-@#ju0T^6hI zqji5_6CTr0u6ve`lei0hkMl%rL4y`0ISCA4to7J*3+K zo|I<@sJUtY6rVeD>?Z-Z_QjT_Kw!TFf6*!HnZ?FSCd4cNrH(O|>^=((V+i9*>maX5 zw;Z&s&+LIR<^=5ieSsm0IV;zN-X*#^$S1D5v9|WKTeV^$z|i>BQ>znPr}JQjVida@ zB{c0w5we?f#uCqq7yWO#n;^@6t!6Yzw|2)%mOI09{ac3>p)#xYq^NICyM-+uiuicG zf*JceR(2sa?-dmpNiDTyDUt4368x&(xocY&I=(6#ffgi;4s$%Py>p-z9_v^rNgNq> zLQ8ZF&w-5Hv*YS|OObV8qbMUZcZS38B=vw05}1MO<7@e{ zx&@qu=5*yBr_8?X0HXHT*aOZ0)){}z(m{2~6AOxGRc)hmD5oXz{D$U-yPlo<^D%2K zR^#dHgeo-a00LTiFiTz*mkK~$kQryd#L$R%8ff?G8TFc$ziD;=eQ+>!?p@2v1oOFj zDlGJFY8g|Koh&WN{L77n^+RpT2fjo5gt4nY%zNyk&{d^upp#m>!AklI1H-ne1|@mn z-wR)=fZkgai0l#troWs}r1kS1TeASW#@;Y`R)U5x|)6%L!(18a#0aE@clZ0_SYgQh6J2AC6cra;Z z-}uN_nqI0^-`{W6zqRyjIl$lYpp^L=4dWG2v?zoa&-z_8T>UMl@*a~hIF|1{zTX!8 zxalvKP;eve$N)cjSiDKZjVLkqZ##;5vKSL_h$-Y7j#kOqKP&&3&Y0%wz>xdQMb-4OC z`xlcSYZJgRbq1K#^e6EM0F7;s=mGSa-97~#JeLOm{MKSa zd?y>*WuWptYx)zUDpS0cP1*B&B{>-t)A)*y3hvsP4FLb_?iliB$kGZbNN{#w0DjXND1|zQqJTG4TmD)!WKLG{-{tt*g;~n$-w@uM**T(hov6PpoN`_w+D_*?orcnbCClEkvInm49h`D%ooD-uZ)~Ve zHrxiy(`MEv{WxhW6fvA7XLinyqvL=pr7D0G@vz z5>wx)G;Woy`b$^_v43_Rz{zDtOy^N6W5IWOZA;yk^9O)7Osn6*iaCBr2&IA*g1$0( zyR6iM$qq%S5S&y5gnJBjD$Tl75NCGn<{|wZqL>1<@ls}UNrA}ua3*K+FUgagsE$9u z_1GTIrrci`{%k57jcXv!bcOJ?6)0X=hSwBanMua`SRflS?$$1LL_0s+0HaP<90$Te zwvHy5+`jZmL>3(SbBjsD40W6J39zX`8B>U(R8m9@t*03|iUC*5(9sPxH^tF8_b~5nL!K&lfp+R&2gwHU}nf)@Ki*`kP7@H7i1`!!FTb3a6MqF zU7a@iZOxqmQrM0URLGT5}S)p<6hg=PL1j1yD#PwKi z6DCl&_(J)jUszGCi5{0UX%n!k_Ez}0=C9GR>_{Fj*0;H+`w;x)P+{x=j zrIc=~DW&vs-0O3NOG087(vFuhJwe&lgP~4%LP6_Lf205}VXh-W6dU%ytO^%`(N4_v z-x*adBeLjMVeJaqaUEL9_dFl`WA)Es@jtm1l3{{`>P4%JwB#~Uk~)nLea}?8XUrfHpWZ}!=b zozxYcnQW)ifiHJ@=Gxn9{$4)ilH?$=>6f>Q%$}xYxT=u6b9b-ZiFNed!S4zn6VS2> zGwn+9^+PHge$cQV5{5q!|0j5|U#I2%;o%o~8bA4;0=LB-Cd<}`Ry&>m4V#c-XHyq; z*{J!6CgLPOS@z`Uw#RXxAoLj*5N5An`ko!Ma+f|f)+er~gYT-@yM%ylQ7vP8CbjpK zgqdS~5taJ9(Bw;&@g!s~k?}U;CP>2-ue0I)qB>;Pi<_ve7lmo+HoGt_^iMURSM`V3ue}lq63tv~=C}j3L^%qdyv0crgPW z%HKn9dPXgr9RA`N+yC{i@0(aj)PY$nCiJLZuSHOUxZ1#~l5$1l+KG|D9)>^P!=J9- zU4y3K!}lAsE74Abb07AgPEMzL-`ELSoZb*~rBwl{(9NOfPJLR7)fEi{FR%{^h!E_W zcA}@e0~B=1QJnyjhJ#2F@BPHo;Af}VIzo(o@=RU`0_0yL5FwOmF29#QMS@0=Gxy$g zD&H1@QZrF68Ho5PwjS&z@4mB#GFD#v@nRiy(VMp5{BM1dTOlJz zH?VK+1U4!da90Wf$W+0Ap%=i~IGjUjyQ;H849@!Gp|a4;(|37WVZyWvEXqY6KfVXR z_8Ant2c@Y$$!!DK7@~zQ@--B-ZVLU;<%*`=uS?DI0l1I^9hu_&l%}9p7#CVnrFL;&KLHK>`5?o5Wed79?3+ z>rYo_NDeuhmEeFg5|ja?STBxg ziU>iI{k_K!a#*b>`#T*2;4$Vm7eJH@8U8cHGKTNYp;$HW(Q16W!7hH=|7O*{gLPS7 z8Ayf)(qP1w<0AP^gNH1GS9zewL&l_{bmgqBTq5AV@!6ee&~vT?_Wm)|X3EUrPXdEf zdV}_Oe|nFZ4f0ubiXPG^J3{uqI%aa4S2eU z3&Y%@Y{VYaNeib3a1M?ZFj=fKd2Cfa-17_54Nh{}Z_tfF*)el};U7zxDBC28ta7y@ z2;0UFtqXltZ^R6B2GCa><QRrUam-{(dvNK!7>(S>~`e z;t`t4+|?-M>{QdH;%+0JU=Mj{Klw%t(?{=kMU(~HT#l-Q z(6p)e!yef###komPhE@_yR|>J|GQFEwMX??|L-0q{EtTs|G)ezj7((#h#)4HoN-o} za{oW7rgq7n|3}1k1{zimZ7(1a0mw_CZV{WHh6DW|Ll$uRg;Ak_EQurdE4lTEo7EH} zGjRFYF74&T$UMq$?jR`;zghhqjg+PU+dZkH5tYvWO&-+=+;5E!Cw9Cw;a;$UjnA0A zwJus+av=GnH)%>JF@fE|!w&%3Tcu7^kAH_wYch}dzD5ttnY_Qb`{+5n=RJ4+8|+_8 z;kk0SK5+#t$_m5+ zIm`sze3)lWfE?l+YfO3l-23J8n^dA-6`772u`R%MnfX7NQ`$}XQ-RDy?DT1bu3s)F zyY4RR5O=c&wt3$+KlR;JBfAD)323WOhd*Bq@Cm`E@HffCFV`@D_^f1bi-+S}y;xpw z7En)p2eFuEPtcdBi-tAM_I z{oKU0?*VAz;FECM<>8VWpkMMD@^_ zV-R+92;?eEv!}Hqyc_(Nu!%&1^TR`vvB%!qoi+}9)Fy-+kisuX9ne1?RONiT(H(sE z%Yk#PCy++MkrUiSOv4G%d2@><4^#z@q_;1og5<|#XHPhO)7(;FziGrBw}41--qny- z`dJa~PObzuPtB13iToO|!t(IB>Ici*9a-((4?7w%n>xm$^hlMako)PK9IAD1JP zc%H3gxak~O4+B#R0tV z!^YjTyygCap!*VH9$$IfoO&Zm@AekdfMVqi)u}CIQeo-PaQ@pN;V6piN9~(LgpDiM zxzpBqtM`OQH!?+{f0bnfMTWZyU+!yDj-Yl;$LAJyT=jwQ?aaex2Q2sL?*|kh|gtfUyESTBkX>?SSs&326!Q$9? z$OGDHIDd&VTmR0mwRoJyekxo^y zGR{ty26tD6vlSK7MZ{b=#&YH}fcwjItqF-9JJ(m8oqmPG2O`ZoCS@p?Msv6O6Co~2 zEbCB$c<4&IYeXbN_dlJb{Ul>I(>5Z@`djjPg1eb>e)%zP5hileA95`el`X4BbgJDo zbTVbjjcMnnuu@Wo2HFge{#OXBTY%BJ@}wD)T@;1a$P)AK)9NTIF|-53#f z^%;gMXQ5gM=|u)Ij23~TZe@>*1t>_q_AdT2DEx_kFv-VX7opTGkA-f7EQp&dtkD%M zCnza9nm8pVI%e|6he`z0tim7)5w(OM)0aH|gx8WJ$Uhy4^a>S4(eiF^Sibo_t$k!q z>$}+rx3s^$Q616|a?Ms%h;D}ptz5VT06G+S#E(ZaBLd6gVD*k+#au^_61(G+dD~YR z(T>g$3+8I24GxllZjhwyb`Q%DmY>7y!NEH@S!JTm9{Bt5ldLkg1+a3Vq4+pt*bVj@UuJC>SF(h0PG%&G=<0)%IAISGu~lhQvwMQ$jp-TSEbqR{lmb6IErv6%BT zXm5{N+0lPJ1pgGu;&~D#(e;)O^N^NH6`y*-2sAI@a)=lrlk zoY0>{=n$^`aH#9&*Nhl3 zSK{1FK*9rrQSg!Qb0NjottHXTI(Ocp9^C{oJfIz-pugaE_M=?)jPiEW@9TL1O zDNk&5;yJiqn7;mLylVuT_LQ9)TRYr)L*yVb&u-wk`Ww*Pb^<}~>^Djgm_PFQ&rWn2 z>YJ?j+r3BWJFN0RQ24v_OKH(Dw*=JU_`5dCjstYl_Z4)sfWmwsOtD;GgTJk$+||=X z=Q3sejZ+0!FI2Jhlc2%h)W<&(S~3r{LBrEKIYa7u8t9f1Q;?$JszPihrL3T%wqp~( z9VhGje0fx)7#*FK#m}6b5bZ@lPny$yGmF0|I=ZbqXFaCQSVn(X#f4I_EyllKkARO` zR02ba^^JDmT)Yp6vp7`ab9jKSJuLQGPK6`Z%&(8l;r<3}z5nUFZV|Ck$F8_u1L37k zf(cfJK&yAP3clj?{B&s2>Iabvm8;&nQC!s?1C>C`@lC1Tu~pf|PARwl=Rf(K%t5-9 zh9(|KB=EK@96m+~7k??O*nO<{DXlX;Q z;XV~Ac{&9k7z%n5(-UhbJrVL)I;;67f=KbKeTmTl0Vsmt;u*<+@W^)&kYLAnCd>oc zJbFrnvxR-#>m%LjiU3ir{#qXH=X0Lq{_w+_8VU(S0llllNGfj@EQb^+1T+C zEJQvOyc+_fnso))7}**Dy4mVz#-HsA1qnqX4bm}4800Ry4nJG*ywRh~FMibte&<8~ z$O0h_Un#Yx!wECPK`?x&IsTK}FhRT(jWNMc^BY1G5Mp#6D`8Q9(X%Zj%8bKMrBq(?ufB%tk*n6Y0s2Lk>`d9=0;TDR zPL9|Q`g{Rs3E9w-ow}@>HA<%8;g8`P{(tojFhvjds6Ej{kR6LtxixsJW4hRbPJ~Te%Qm6i6oN?eF$I{^EYn&F}(OEP}@8YiDjqW+<|#Waujd zXc<7J{ut#cj>Y-~T7StCY#k@^0TK0Zt#$Lhp5GlQHccg0Q&S^FS2rc>7(dc~G!kCZ z=9f!55_EBk>hrKSum!Q{W?KL0e#MvV_xOl3Gmf&ug|~54-Wwb&v(M5b3t62=pj=fU z2C(?;1kABxQ^7l)Jy3Vo2l~Mz8xw$ov$sg^-At2+Uyy@&lf&1Ko)B_ zlCs6eVS?hIV6K+rOXuzU;?RRB5iyw0^cxOIzw>Cas=Go#L-gf614# zB!v7OAV`xq8v+N=&iQPWzeaQJXA)A=l9+MB+$w02bzBfmoc-Yn=V{N39bI!JB})ki zXpRrev7Dtp6az0Y9I+>&T&^MAe=}FK)42mKSNnsT?Qyk^uybz#YEeEhY$x&EO1_c2)SiL+C&LUA?CNkLK8KXA zpYV>e>&1QBV9m#ed7Zxd!VOx3kQR5x<`kU~8b-QsMNjT$CP_ZB=ff+X>Ickao@A1< z?2OT}FkYJZZS>CZ{3~y>CQ~sxt-EC_`LZQ5|G`{l`aj$D|75ef{P6da3fm(l#Wgcx zS@!ytj_4n^JMG$InlG(ojSyj-O>f zBM7b!1R0IU&1f~Dm7BY@BrgGfiO4{5x~98YfLlZCGbD%Go9;IGd==*g>5l4fc~9J{ zTl3Sy+G?5!tGX-)IkPDl>l3X*gX!GS-SkYvo;6Rp$8bJ+!hm-^a6h2m|q8Ub@2EZuQm3uEB?co+J<0;V zS{Ut&ffZ)Qp5$<|N)#h!&)Uu++w3$Q78wHH4MQ!w4*6IdRm%7tGiiNnt1a!xFijY( z3~lEGX|zcY35G-ji56V(mq->KJ)~TK>cX?{?X_KB-T5vXKHI`7TjseTnXR+YK&}m@ zRQ?|JaV|sY(q|++7%$rUBYQAl`r&-vt|6^W9PB92@tgAehCAj}VyY|E``YzW>4jnf z1Orv{EA_V911nMohFvXF&T-VaY&S#k3A+D==l@@j!u$UOZe|*@RAxWLYzvuR-Cb@t zo*wgV%Yg2>m9{KWLS${Ao1whpuiY+>2=g)_KXER*BV&7UlNK+Y0Nb)$V3c9>>cm@Vi z2gf$)17?-YnyvSW>paNLL0hPE53)tzXLJM;>Td63{&nAW0#DY!F!y5{j!ztS8r(sO zrLV z-j?F8IW`dd9J|GTAt8Awf%-f5`{UVve+q?{*EiusFFoCMX-afNCN2G+1Aic^ZK*&r z+48;@*^3@|lQ3jz1((J(W~OF-a@lvPY0e-@0F~5S+GBt!!oy~KVmDwV$D;lUiJG{U z)0RDd6_*&W1Hyn07>uhJvJ>ucJ8)!s{{Bx*_cBc|K zpn-~&aJBb(rM=e9pi3sGAGHa#XcKJuT%LyRK2BXa=P1iH821&)lhdrY9*jYew&D6_cr6&pZL+wp0RRabli6N1J=(DG~V* zW*n${g!B^n+l~Af&6q-i*}(8cyi_WSx}|%hSN}vb?v`U|mS21cuzHI z;*_Je&yQga{ZoOU@#IAW_6XU$(d?-1Yat1#R^S0(pjH$$3(zI_hDp> zWPVgoK3wNnl&@=?-lR1uv(ulNG3IRy*CeY4=_jub~~vkZ0*lZp2BmBzn=gj+s#n`H!DBsDw6$W zZj3thp5s>=tHbQI(&H|tfowrVYi6ifK!x5C=K=LJGx5!u-4Ey9MgtS?ik*l!(S^E? zR3+HTQyZ-g1fQ(GMRKW|BOdB5+WaO_Ombj|8SkzSj<99qyBrJ|;hVwepoSELRG%bM z=9dqf+?(0O(j;*&5K9AI}x3qc#YY2@m9PZ%tn}Zks37@O%<=BC(&V7j*5t<9f-Pf_De*w;la8tHg8_0a{=)yiwJgvT%{hG(OM&X#cRNHPxXgvF5@oJ3qz^ zOkG{{yFTwWRvl7!RNOt**&&cz=2yK^male}Rnbv2I2^D^o5WaM*x#kL@BJ%3XhquV zMC81!Nm5jF{lPtL9?_Z5i-ZBHgQXFP(k?!}(7XZSS8dM)`|r-;6A3gr8jtNiPCfhD z>BBYhNrb;BJg#+eq@;|48m6C_diOZczSQO3si&9)QEN6wPjrFun94)CvQqUWrqpE` z`&!389R=E27g1Fk`V}Q>auww~3CjcENdM6x_VMRv)%gID{9JG$wC#hlqto zR=DQoPfh$cT&YhBuz$W3r+yXn1X}X}k7f0T-MtUFJO9bsc*^gTNibf>tL5~o|2=jj}}c6wdQ09n16WR^4E-o-7vS2f)2@Q~2% zi`q@i#y*^%Z=~hwyNW~ zCSJX(WmsE#S)O8;d-s%mfQs11yEQlau#~zi&hx`d(}h$iLHzwYB59m;5kEYfQb*Nv;pqs-fsP zX8Hml^{vVY?`3^h#ph!uylz}Gqp7V{XX~=^D=S6Oak`Sdwq5zB@itxg(|C0kp1GJG zdaK)`KIfyw$uFt;qDoiL(-+P)Jl*GkOp` z>*+?H%e}-8tYsg@sf+7*v0rikUn#?7UKk7p0bc#O4B~O?x|%ew5{r- zV|IsMr9_3RddS~V;MBJz4U7g@K4?)Nb$4XmGmWucI4>_16Lz^mZX?5A35bsp`>E+TM*r7%>Q99`%Kabe#FYhXLY<%a~-5PDP)+NYf%|;0i zPW5;xvu|w3M4g3MK$r{>*s~#QLcYUSxCoD-6P}i8#h$Sz*=^xcs=JQG~?kdQw z2V9n6oqmsXD8XDL73HH@UvponJ)PXN;YNpIFChmr2wh{4tAyttkayEpN2siQ$0v#( z6q@5vXi=Y00PhI)U=u7l)yTX9o%`AOZJ{g2w{y4A^QaJg3w?8y z1sBxKU6GSV$v@h z2&yDT1ze~}E}n>~Uz^%@tYvrpvy|2yTGnIA?7MgT;F6e`M4qNTqnLMFv0bU=9Q6hX zH!Lh>s|UZ*GWr|86puya5E$8(*pu-SH{|P>{Jcj?h1ajt$aQhoI_A`Qvaj8GQf;kf z(zVFj7mjSXzLc#g(^E}#IP^AIa7^#(~BkWqu+d9l$M#VrDmyN__KGyUJr5Z$P`8C?O zC*%)B94rEv1e6nd{-o0P57k%qXFXBxka>AQ;t}0@e5WIa%LmlQh3-kZA8q@e|!-xhY?L<1!QsJdUcv z*K+&EC7y~nSKK|qeJNWQ?vzT3YuS85(trXnD&N!b{Ku$xjH6YT%|2#9kNE9ILSG++ z>@mV}iOJML1-_4JT$}ndIr4|L#hdq1xJ>|U)OVKxuh_J&WbHx43Gq)xT*Rh`bwzfv z-;KXn7@lQEStFJEo3p?q`;t*HPVoPo=mYV1pq|DA2)d7Zf!@5WPSsme7>Lp_Dw11> z11ig0yTiY-YPcX-axN_5n<8lP07@R9kl7QUL@@(?BT0qLdx*i7>o5k2h=O%bz&yUs^GoW-jiH!}>%POoVVr3!)s+xs_8+ga#XeglSxdI%_lshDO!+-95u zFqsg>^?5(9u^GhHK8x(C_5Q3*wY$8X>_KtF&C{Z&63hCeb5)x4(h`hbWJI}v78?4R z`=plP5DcV4MGB-AGCt`!bl+`70&lVE2ny6G^{dIRkEvUuYwqnF!1*$o&Bsej(;2t8 z$h&WHzqoPC`>O2D2ga#fx3u8#^TTNa*T`VX{grH~@K#X;1&EGR942&UP~m>G>1pwd z^ro8z6st!SJm;x*thOaWP3|zrqL1Fh!re!JdV2b{?OQnmMH=BGbI$s z_`{z^&QeqAEyoH=3g!FxmGzhBq1&$f@3%$#B#hK!CQ-o}iuhMFMsZFYQcv|(t~2&G z5$&5AN6bj8BO^Y3jK=BnPdG`Cn=5uNj1`eE%8~}0i?U~KMIiaPyfSwU-SW`;%;i(r}FGtU^ww{Oc&>3wD~v=$@(ew82A zOaF_=NU`kPmMGt~<}h`3Zanbtf?OP%ytmbs+<<>8xP$;=MwK>Mq*LLD-n8)EO|O#~ z*~F+}D$a+RD|}lg0$`f$(F7tXoPGd6#LtgpepCf}z=3b|NAUJ9y>J#seCexzxo=(A zNlSK9Ug1pDQ4PO11R*o@85>JD;<_rG#FP?hsnI)B-eCeVwp#m$?nZr}Qm>iSi*NM* z@)p1S`8ed&1@e2XsMs5ekWET$O^_&-GCtbeWjmAifIE+y%Hs>(RUKDT@c)&e$Jll_C{p95gX^R^|;>X@pDq3H`2t7Fr(kX|7EG!{oZ~e ziDQM|c2S$*wjK~{?slUoB{ZHpli^gw<2DcI=CkDe~V z@fc{1Lre)%P)xb;M@7PnXFpnx6{VBsz*;``zLvTsuwIk5lPK-sd_$+jzE6mwRN9@F zHgZI`TVW`I)9V8^yC!j9vJ3w)$*V=j51IZigWWUZ*q~=*!VWA5JTj*~;r+*|(exQZ z>0E@QKg`(bJyjY>VmhHnQw?YfZ;j~M28d023V#d_2T!lD&*RQ$L^Jr0YU%)4(Yo1u zV-<`zf&_Nm07fKJz+@SsvLMGFklz4nDZ2rGWNs-;YznM!tM_6aYBn_VeGtDL?G{Pe zhWWWx5H-6BGKk5795MJ;`Ppa#ACd9&1@A)caII+zSj>tvg9E6@oss34w5R^QCa}e+ zO%Of>0b!&w%&f*@qn)Hv?rPX!jm_jwYKNyf0P@zBvIw=fG9Qthq_s4F_x+|<1WnUPbWhd6#V?Z3i?UO zF+<5|<<}@q?stJTU539`QMaFOH>&Saj__HC(QeWP(2S!(knPxj z`HZM3F#9k2fqZq*QkmbqkA4%ZKh9IH42b7x7luzS{Z60&ztURky7k^(t{_c3dkAfQ z^|n3*9i%6nL4bi^GHz=*;F$`dxJ4lK8~}wZs>9}vMj8E*YlzU+MJBE!+&%|YAWacH zkn6;%|Dj@hGzN2usWAA)x32N6WVDkdB588OyN;L{c>}h@5-xt*^SH}^G?a>eBmMw{ zR0%64-l`l87kb~!@k1oy!l~KueL8>r**H{lmOWq5$kfTY`cB~Ns9lzHcdHzxadN~r29bSiSo|FT|3%4z6T-i2^J>HK zNe+y9yZGzr5DN|<8~^b1j>$r2j1hRS2h@^DZOK`4b2EA{fD&S5Z#YMNQmxq<$PQ4V zKfL|5S=3C*y?%U9QBNNs3sNP1FkKpPK7abUotVOwX^3c2x&m9W_1;aKfpQ4kgO2a1 zj)X7pUYeSsq%3M0_Xe=Yx0!}Gk{zFIpMsN^WEyynv(ElOUhL0;Wf%{z;5k(B5MRZ; z43FON$;3v$b;0|rwU73(DMBieZ_zYD9{o&!CVR09&VDrtTXgd#Of~U}xHqU@2HeR#{;d7VndbJltMYTM z22|{XI8oZgJKOv6HHhmgH`!@d73eV)!+Bi5JwgF+5(~2H{WYQz%R7D{3-Ko5Ar$E_ zT_OBUaIJaiI>0{QL~c&~C=HLmo8nN7Ki%u=Re(aHtm)FzyEPWhbh`mg+|dkAOT;qr%mQKis=QP;;D(#ve^B^UVcuR@AOjBJVd&|Ph+ZCym@<#Rv|7@ebil+`c zBFKhmV~9TS8`ZS5ziV)RsqJlwcd$h6Z;y6QOHo1SvPTKjVfHe@2%K5zEROM5#X}J+CvNxM)4IXZR^#I-H~(Qk_AIH?~+|l{YCx9 zXyl`}gQd*S~|4#9Ox>)mi&P>rR zJ?>cB$?GZ(G4{`+uhHE8)TC09VTzUK2WVUGi1B^GrV+IX_S>&&=Ou{)Ilo>vXGZe< zZIufuTgURNTnAMMtiK(ayJoMZ%yMtmf-;QcV9EUO>x;+_;L_^`o|I2@aSzgtUBGM# zJgQr$L6(RZZC%>EC(|lFQ?n*=SmFu}l2?MhftFRukJ70dR6w#=DnJUHJv?V!v-D@z z(nI!?ZY^67P8$W$&(?#i*DG*z<4Nj*b)TG!c$NiosyyX~ed5;EyOC|l57QE!9>vS4d<_5(4)%uS6lnop0Wy^& zBMU+NM0o*6M@JExwf4|O*HqE`G|U=u^0H^49l2M1DOS!ACu(l8F{VfFup(J5UocgR zN*t-Cx>s)U>H+_O<4KB2Vrec~LJhP0IttSj)1Uvtd-r<@OB^4Y3!lS64sz*4r(je2 zT)j(q?a46XTPOA1^_E4ci*7%p$J^%D%ksvFYH}&1Fk_Y6H=pToqui-%g-EEt>Tde~ zU3d5YY-4oilNZk=j_0GAy$&biCM%#e4PaFM)i#1!hjb@yeF|tnE zOYOEQ=$mJv)*Lt#Ho8y*$eaQFyj*H z@gk$<1{GV1*))?>mnpYw4Ad5=+#65{h2gE}Jc=a^@9Q6jYAXuADf#qtXqd8$p4dzI znO~e8&wvhg=qX>_(X8E|npgl7cU**0<^I|RUgf_M&p-`4_9pqxJs?|*k2z9YjgMx? ze5f%cHAUDj3gPr!4_W_Ygz^z~#qpDA>pN)`cMo_iD>4$s={vvtu?tiaJQxQ%!K7|4 zn?C?N5M^_6t&vYfkvqvX7{b>F>*F(koEL_S|9Zq7U6y~xrzc6G-`k3|Ko8OmM~QPC zy`3CBs6|LBtp2H3=*gXShMG#BVq=yPfOg|q0t06(js>Q%2#{(8EcAh5q3anR3r=>L~2IOxkIY&R*T7X1i@{ zwC1aW3^>Lo>_F4JU6hq<5uj(LELBXu?C1r@2Z z8@CnoFs?X+{fDRDtls3tbhnfnw|>ZwzC%`Awv&6+KX&)ceh$f3MfD+)9wV*>2^ide zz@s>+elJNV5;aV`VyP*+Vn-ZxYvDaX`KEALe!bBA(ca^y;ER2H4P|g3{Ei$}6YDMa zj#|ex3I6GLV|TInUAKI~qQouYn!}nU>3-}kx5@K&Om1XE^6jThd8Ul@n!4ol>*bBT zGN+Jj&CXo`rE-CQCO^wTRbDP?O3<|((j zny@!0oma2*$QrL3RldbS|b{=}f# zb8~(HeW0H1FXF?5yRO`frCPu_6hy`x{XN%7TwC?a*zc?;nUz5@eBOomRWoh#D&+>H z_=|qbA_E1P(`^xxLoEMzzMOS3Eoy4#L&l?U^Sk8h&te;GnLaFXK7EkeN6^$PSFv~2 zMUrDg`lyDlD^DJT;Xgidcz_W^-GgGt_aH5TjEk31C@4eQe|HR?crA9qO zWE*$zfKFmsOT%jKD&q0^+ofQKhsl`l#MNJgO^sY?KQAUb3eO z^Ka*|QLnaBEubIYENmNa&yCwtz3UPcU}kYJUrHpiQ^v3{q|k4 zphizxa+p7EWN8VpQL(PR;(+Mm)oYbEEZW0DpV76Br0As0sc8H5W<^4435E-1^~qHfU-Y2bscMQtXiWtXSHHHr~z z|D_FlLUun5LRwBE-q{1p=2}+ODYzMF+dVh%Ip3$g|EEwZh?jHX(pU<}X%V#)E7ZT4qt5sm5>2UGt=l9#Rd z|BvMT(D?sG@`}e99CvEZZj$*NHIF+6?~2tQcW>nagFD9ZUL(=jtxLZjB|-@P{svlA zetH-=nS$4VGRMt&MsOGV+tIdp2#C(N1D1D<82^~M`&O-f&&zn|(I=1Bih55KBC;xpvl=3EA-1NG~!-iUO8^gFlZp$!5QVG_Y%kxeCaK+#_K7ATYx$-<{ z0~ma(YuRy_0Cki8K$Zw8q3TrRFSlI(+j6V&}}N1%l1Enn$OI3G4}u*MV9g;^c(IY<^oHiWU{Xfw-*? z#2YB=&DO23m62&(N#SgI?~)M8jg2N(!Wj!?c5{oA|IKR{;nK+#v|v@NPv(ZodJ;f@ z0)u?GJJ+?uahqZXjS4A;Ph!Ujqh0d@{4d(S=i#7y`+^Q<1I7lbPFC~g>e&ZA<{N$3 zO*>q9bDHvmhVZEb6l+32INTfRWbcE%G6}@#y;Y6}9p#DeiVt=)!P2u4cj^H?H`}v2 z^Wcx^3AG!IPy@yNK6QzO=%&p548__mD_%IJUkR%*If=fFJ=VYAE+ zdh0?|uP9g-WZmxGgn;r!)T(PlryLZs`IJ3ZcB4u74$1Y=(^ij~wvOLs{xA^7mG7F| zWAShF=69S}R;1&2UmjpIH}@2D81 z4H(mAvv5rZeaVl^loZ<4-^Tg%n4j?P7-t(=;Yk^?e;cCMz};uTX?|@F)hiKWi-nNb zUOD(RsYET(A_&0^36B3D4SD>4FmWM^x_0%kb=6?EK((d#x@Qm;vRLNjMn_o4{N3>b zU?yPqs?Wh7P zD1s172;0Ug?M=qa5)nCIQ4isger{DatozI4Ov(Diq7J&O(eheieoChW{kPkxVH~~ROomN zgSM%y7QMT&?y%@oxZadR_0Mv(FFCsB_ZAWurg_y+8_B3j-4pm~+-dSiX(z5h3V-J4 z+4t4B%sA)GC8_N8c~seV(u;~*-4h$@@VV)W@<&%s#C~y2Axw#z{X~B}WAE8XYkeL? zSPF{@ArQQZ5W@*#>k$}YD!$c5JkUGY1(%BYKK|1{gPE5lyK_)^cS8i7d+ek#+O5(x zoR^qv`Gv05y<5x8X_x1G(`Mm?n|w0LG0X38ygLu$O#1U&ci5~pWm7~g_r&QWB{u4r zsfSiV)!EPe4leg(9hI7P*w}Sh|G&5ZU$%ZAvb{H`5tJZoPFepC!lFqy z`lc3?h=rx1M^)=;dht!z&1kYQ5fyjSbLK?lIaHgq`gG zBAb$#bfEYo-z}Ut2dXiXKF1vgHlzynClTUT;pTQwRaWY7!ohyJmCAt51|Yj2j(GbS zgaF$D?0-tPsOb{ZE|k(LuoO8DZpDf%*hyIy{9OHhNBo_Iy_4MeFAvaWHUf%RkoUBx zfBjt?xqw(ISbJ4)8Y7(gN5>51Gl0i1Q4N?@az(0<0--$ih=EOtguvCfxF5wZJ` z3L1T)fj?LMqY1lD;Z6I4Qb>Rj@I++c!A8&q3(s1yo(6Nf(>ZeTP$J=F5*$LT-F-vZ z_a6QCscxcwb*&n|w{$W#epzgM|0#ngbL?2uE{p?vRlYjaY2;@!9H}6G=RM53@clSNdhxcP|{lDM6>Z-4G=$Q zh8Djx+$XM0+nHSI#*=?!Bx&pkYzHdiU<+@Il>t$$!pkw=AoKkOMUf-8Q;1p>`^MNC z82h&9jHM{eFqIhHS~F>#ry=81iT(*o!8bM6JXKQj6u@W>75xS3#h~@Sycf#MdqALa$;VX_J847vNp>qB< zqr-XCT3c=GeljNo+JZm4LiCS;f=E>!54&5qGRF(1`n@*_!QC;y9^H0^VdG{?e{R1r zSAx_O&mhF*gtOQ`+CZ_m&xeWYOu3HFCsU~Gwwz_cDY>wuM97XmF{G#K*?bzGd-HFp>k3xi;f-t9~mpg8gy(ytzZQgb25Fl`(zXX^Fbv3`{(%#6Aekhyk#Uy zRc{zGy0YFVeAJIkA$Z>x(AsTD72Z+Ka_Rv8Ih^RZ@G_Lw7nqZyWQ!r{ZOI4TyAOyf z1s79Q<>DQDjxDC@+z|dEuwr?o;ilWVXidCiR8P-L8iKnewjsJc)IdJG0t_O=!iZ3FxJ`@tF}T_LcP0C5JM?|cAbM7aNip;R&cxCZo> zpTV!Kf6hkjZv3R?nD3hm$e1{YIB|R+17vRuBz$= zEBc^#{m1m&KpEXbT{5^?{41XRsVr8OJv2|P?@bWq`2FQ>-dF{IYHfi^dFv*`(K;JD z0Il-$XtKh~-S(2{fvjU0usq8MSPX>VK5ODk+rC{Wiz|7I_9$%(pSk&M7kkZR93EZe;%~lFjafb4N(Mb=EyS7V;l^CYKZe(x6)l{5}#q@R~{!RB6vW z?uoZuyfeTO)`}-ZB4}KV;+f7kS^TP}#m3K}I=FEp;gzN>z|Rtg_MCh`f!PDi1|UWq z<<8@`LC@F&Xo&@37qm_yAaIio&qM4`8kmFI;z}Xs_-DY|p(m9++ln7m6Pvu@bLv^# zuC)4ry8s`L&Q4DG$vJYPM7I|L<5HL+dxvIvS_?3shN!E9q*z)avF$eh{)?c2t+T(8n zJZ@&KXvp8K7sGKn-r>+(9%TojN@j8f~=4oqb7Q6vTFt zrQVRib0Q*hnX#pw;$WgR)j6fWTss93lZzr73Uw8jxy~4?j83NwmUL=2TWxhAV`ebk zTTlFj!_>0)m}}td0*rTQSLG0wPXhk$daLez!34~(loTd#O>ed#MRm(bSs%8Okm}f;?l>~mM1s`5Je~)B_xQj)6L$I?hlJk|Fl_}}jA!47-8~K9##y}& zhZ<@qEV6iIu6_S%`E&e6ftN`D(O^%DJkBElCgV@(w_^0Fu3EOURXi(AhTwWW+5Fn~ z-F4j!N8#T#G^CQ#M(+?mG-5s8n%s6%L)Iz;&oq<*axz22Nz%LH?U$18pDw5mvoX$~81ULR*L1@m195=JObV;LwnNK-=@pxGS z6k~q8TxO)-51G4tpSAxbGW}#e0U4uv)q*+H#Tw{bY>$3yk3O>&C|?8ReDLfa(AvXu z_0t63%O)&NQU;evS%UKbAJyLV8~->X#IMG$nHp#yO24+yHgU*IZ4s9NUoKm-;`Lym zbht>Q*prM9i@7x7A8C|}0{G#&m5NgUrLEF#gLC_ru(M$w;B!9%6nnDD+9QQp(YqfXpLhraaShSCS7zpj`8tn*}PS~a@1m6EK#&d zN>(#uvX(vf@gcT6o?jiyPk#2+4QnNzr?hJ{8RJb`&nZ00ki1^J8;i1a!W~%ZyrJM| z_KYe_jrm4XQ#|p;U8|86EYI${qb&esU;qFZmT6IezG}h#jolZ}Ua5_0FuZDpjw=ZN zeRTR!xCb9_PToX{y)OY92Y>t}HO~MgM*vx*sveEksQjTPRpnKtLJDx9rF(p(t$`3G+|zy@gKC->2zhrOybt5-I!sLuKM0cNo`d0$l%(QDPbt zSOq5ICIKY+RYz4M-2ek@t_Dm=Zw3p(iyG(Ubf>_jxS!pMtU6cD9rXugRmdAYQ`1MO z`lR6k+7gQNEss+pe$c~B1^!PxPMt04^1&5vYIs-P^#?v9-ZBGBXD$-gy3-nRW*q(? z{gbHJhybi3YPj_ktUaSEr--Qnsz+oB0q=5V{mrds2&@h3LyiPcoOs8RfXidAAn+?S zq_yQ1Of!$HsVgRMyff%L>_H~Ja{mZmn7+B;z(jJjSJdy`d=ryG@EgDp5EV4}v?Ff^ z3-X@Xp<&*i;&Nj_1z$m{F@2YN1mmLk1aBcDS13|zISva(FL;MT@GOL*m(0pMZk$;=rF}~g|E^wSyzLB3BPNSXjg7T5f5UMP#CshdjQ6b z9U%xP6gbSdL}DF1c@&@o|V5Eblpb3Qabg#szQpL1?VN z7ho;rnk~biLQKn?_0gzIlMoZ&nq#awr6p#LkfnHe;va5gtWj;Jr6_%*{>cA;TtPL7 zlgNIoTVz*G?GO7^!B;zqUrChOlwyRQHSRm>9OK4aaMIbjeM)s(UR-%Kk+5~`YTzS} zqcEy*m5G?M?Tl`fb}NPllD8((SgdCiNpYRhq=+=0@L?XGAN6=k*-pc=vZbF{5EU4{ zjk>M?cT)Fj-xl7&Xp6K~uI|Ju}q8yqm1R$2r3ylpk)wIa4kpS+~p-r?IT zh9U3^sowC7cU*!>bqM1?{FY($0`^&Ge8R7BWD*liFuN%_=o6OHAL^E&3W}5!C3MH? z@2prq2ZdT#?|7;CLtR(Yd!Ym#3tj7s{G&cfq%7VNn;0jFaXn0zn*~A*`g69}v}J4D zRdt$59=QEX$~aI!EvJ^E-1cWDYf8AqQi?6K(~r~ZHz~WryTd4#Ld#s0PdS+rHm2(P ztZXeK;s3N6O#zS^Oj6wy8UEr5{%0FX+3j~Y)ruo}Y1(nIV&OoS2EACnbZ{xVeojp17sSknR&7>pOi@g0EMTXmNh)5sgmkJYJyrekD}7Ai4NT z)t%}$un5jA@kdP`$xZ#T{)B#&XL@5z^#0SMYuE~=h9BkM@%7>m7%^N=>Nn@CPo9RG zJ8e#R97^Q&N=$2LjZRg2?7J6kp6nNT9CD#kPZ5qEWT|on&0}g@GDa)AR$Jn-*IoI# z^`<_|9xQ2x32QHwNKqy)aiX-@FgB+zUS6&bU1+Vf#eEyp`4yA9eg@yscPz-(beguH zy#%fAT*7jKvYUozBx0tSOqLi}GEa{H+z{LZKAJ+*s3M>i12nu=HMc#I74*AIoP&kY z;25B4P58J0V6{eZ`t$PS3LgXJQ)OW>z4QWdu&!- zrePM-ptT;Tzs6(>4$X<09+-*?v8+NW@u}(tDd=o~`EqQ1;^6Vj4*(+d!yaWplZ9}0Lu7iY)(SWM~ zXiC@t&no~*=~hSV9_=lC(zx)jbt`fZwVk57JaB8k!Yd2V=z3InBh}pC#Q`ILBO^>_ zTpvI6=9QlPwSZpj&1G)U!LpYDI}87AWfZWTsu?KytB)W!6$D-rxW4|A#ZNnkVa9ff zc*AD;^&trM+%JA~?TV2rfLk^XebdbRnhy> z7a1u^kv*Lizj_G>$3fu7FVj{IE)7TMb`@{cESsu@Si2VThh+rcr(K|Ri*I!=lzqV9 zc)L6gng>q=5iLQ9kz=+naCvC0&~sxJ5r5!41s?hF+DNChk=C=wHXwtbL7?uj7f9?I z>%TmiUjpt|c>B8NY}dl*&PhVAC;Q0F71%U5phi3YE--ezu*^-S^ryBmthBpahgcnF zULXf%-pt$s<&B%C&nKsE26FmQ9qkUVUK~tvd%f&CpI~jF`8Qt@%wEg9Wx-1ix*~<1 zk~4%SJYqhvro;XLlp0{tWe28_N(Gwj@9QcBl+ zUxFe~yeQ(;L`3<2_a{M<2(kU;KBlpAPiAMx^c~xWv}7<|=M5cc4>Hw#{mmJBp^5Qh zbxXDBfcrAetonF|@WO009u=94d-%Q(7QWys<@;Zz4K7bcfqSuT;(Vmros4D1NvpTP z^3%EIyGqm6HgG3(#ql6_vN@p9{vUVJqj9xKz)E_5+~s{D3%C_qYP@J`cp?R zb?W?{$h7<*uGmYt_vA7ZCfInbX^^5)(avbBTfX{Ma6q>`k4_8Wb}_AGa1TgfPke~j z4UQ;E>T(OtJAPgKJ)~kaOkqcx)j}s7^t3+m{o_ya0)LWk_KUc^aUMevl*v`8q=+V? z0-0QB`-{vDWKdE^IJ(cE{FZv{j%>Zx_C~1?aBU!vQxO{!yvpG z2+RKp+6yKy=&%&|o7@1;%AXk^jvH)z;zowI$J6&}0~n5hu_@P3X4hogFkhiZvGsJF zG?+80yU|DHio?uA|4mDN)K*O!f3PlLaeawx=Zr;zj|>bgEd@(mLD67cutbc2+~T6` z*Ah4kfHe8&0(P$4nj4;=s~tGhqlFsr2r)e_!O5j_uNToNG5Zicmi z26t^Va(8YFtMG+S=%_Z&cYaRMy-jT)Ze&V*TwA;`jY5-eo=Dko=Z(s%(ELVd_5U2B}ojTH#4Lt7s{;-#y?JT)^e>p zFOR=RpVu{@9+A7f^!2UxjmL`0n^Utt*F#9R@EeN z!5<*?qXz*j=i0(%KzxYUcu&p)4nFA&*qBa0rDrGa3Y^8J^dJTre^|2$_$2Dd_wFWv zt(!BzGP6cUJnD@XWPu*b&|czg7qDR5pSgShxa38Zw{)ER6GSYZiG$5cx~CYu(9kaX z0TrJpGIki+1;ke?28xTez^eNeI~hcMM45Q1a>r8RLH3HrkB|2kW<7m)9zKfw;OGhx*`3A~*r@sbBoGt=)eib&$z;{*~82#zyqC7VMUyzJS1j4N&Zd z`tKU&k!?_}5!*O4-9A0qbJIA?UO5f(JgThU&$n$YDT*-h%&mL7bVgB?B zcG0?Aj5+Pn)1Z;wF;BfA=Hu*%7I~f3#vLoKkn=3lCEe*=%%8bG)e(MkE0yUR!B+dL z!w3w*=^XYO4od^>?jEW4;%F)kKDWMecIuPz1@P6dFV|l!_ zpE?p0Mj|WogCRuBWlCrK#Myp~_{Hn(Wc#*TGbd|>5v5$QB7aDYM3VtgR9DAr5O_#M z<&0euI^fVsN{-_&D_IHtCMc#sWy=>Qi~Q~M4&X`C?vALQ39IIzvtO_jA=I3>~)U>e=(+c|!e0IfrgufQv+-KvloHfMWkjUOwW*Bs^6t4a} zTd^-+H<)w(Nqb$-FYFmhs{#7b5r?lGc={X?=}RT?wBhjRE7PK30e_fYIliX(Z_J%_ zRFv=k=1o8W0a3b95b2Ok0TF3Yx{;ESlt#KsT2fNFySuw2haOU3=%Mz0{OtaAzvs8R zXV0Gf?e0Hw4#O}o!#vM(-`D%PURTJVDV2=q=;i}ct1%I5vcZE`l|)eo;t!k8ZIDmy zo+G+!VqK)!?58DYrTYAe!;O~p%6N6kWC4(2BST3EvBAfFAWt@^FO=e+CX{l8LDnA6 z@d8!P+|ghWhxzz-fiN!ZuIPN0T?mUxl2VS;?9gI1M&jOf=T;GU{v(_73Q6?$Q{N_7 zJ8xa&wTsMtCtITt99(0A&E1LeyB1M(J&ar!01J=;%%s>;*cGBt-U0ZN{vzS_aa~?H|&hG7R$m%82Oy;f|p}LSBla>Eq>yj znTegcc#WtEL+2~j$BQeyq=(0!tg=lq53&zfC`S2}TEuX5-$}ZbCT%^&He#saa7TN9 zi{{9Ymyh4gd>p<_%;R3^$3LR|w&@+oI-C}kSO*sE#?cAF>aemr2`sy*KJWIY3555< zoks&%-pru(7-hTZ*va2>G-|6()3$qwYQDK$8k<)=@(y-K#(?q`N3N!z1SHIX8jrN7@+yIrUxn*MrZ(|*mRiw@Beezvn*$}ZNqR^`bTpOYg9SGGi-0bnpgtW6ffHx#&$2sl6x?AP z-$dGZyt(?Dlx+Q)wEekgzpO^PIJSuR6BP5Hg}vHhKL3)A?Wbw4$ZSutomg4Ix#)7Q zC1q%}!>Vpfc0L@n>{k!pLB=1vy18c>$l2wr-9d;_!f!Qq=|BI?N0lRD`lEkmYR}~Dd~tdWFP>?>rfbP!Y0}hB&D6)b9Ii4IWG-KtCe%V$kxQLWOVMv zGI)FO*nF}luKQTDci`|y$*qoAXqT&6EaB>W)8}r(3S8q)@AfV)R^wx% ze12Jc{f78=h=f?Aqz4CGx@yfl63e7*?wJvnYf$Ldpc>K_O>42d2-myXte(;YTj5{I zi!!yJKk_(5b%^#m7JX+-e5PGhr3zMl+$%e)TwB!2JEfA+O>(I+?D#c%{_%> z?!u~+Q;a! zf1zq8h0H%I*{IYoSjvmaQ*^o-$Bc#NRB)?#PyhN3lhxf~uo1dis1mP&elERWAfYo{ zWf&|)>+dtR%m1C#_@+&TJfsv8{o6MBFSmrHvCj`;b%CJ5y#GmVejI4S2(YDY=gVpX z4l4r4UJ8_Z{dj1Gx&y8>5Y9Ukw*6#l1`PUxVL-ci(Vv1G&u-On-hFC6Elvh<)V~cc zPIj#>+Q_f5?>hl%c)*OZpZpZnFuD7smCIB!Sb~v3K|e~?V-UvcSrlo0+Y!_(WKxoQ zk!k6{*+;1G1~|+0_z%GYJLSqUE`C~)-^&sZG-3mG!4*=Bj~WdddQCvqi8}%eQnw?X zz5+1q;7eIw^rfVl-y1V?eZbLZ#7VLObUFK0(Z?#oSAsp0Wy0+2#gY)Ep40-HYS8RT zWyG}(6lA@|z;u!a*==8coMXsa{vr$JNBa!80a(SlJwckhyocv#+o4g=$OQ| z2=aC4f;E8GNfTJ!ECCHWBn3QvhL9EC?-~sG2@3eZ+ZNpxn$hz6tm)Q!p1*W*TDfEr z;I?m?ECD-a3dkdNaN&VUM!+?D11|nm9c|k;mo+3+EGG5L4M*?)7HEONcl>;pqYKie zoA#!mivKrHy>E1rE7_Ok+vZDSY>$~b;M1|uS5RtMU6nieeU!FT7`OF#CGyY&ja5lF zQI7wh{jVb$%I2H2+EFC2Qp0>&Au<{m>(YEF^k3!qmet6202Z8C$5aHIY4MtWH2#g`?1 zU=m<$$|wN_zq1&6W^a_P?ji6_kskI|g495q&?r=(r2@e4^iAL;iRIHvrCdUTql364 zIhUGCH7%jT_@VY%D$-?Oida!QKc60Q!y6LXEg$p5*2l!a=f4Fl^;Y&kovi@zBdhC8 zId`J#KYQ1OEYgJa%_#>%utw)&?%=rlA+O@JcqypJypf4EgCbj5Tf3xDyDAn|8GLn3o<&o*!GqlxFAHm{ZEM69dyJqD#)%pFXY%A7k_`xv-7-> z;h!15!QmPdqRx33iD~dN_++;C<0_{lCxFTrspOy}< zuw?xP;3yAPdJj68q20{zJ)#SVrxMh+hXwU>h(P{uvpk8%&?<7v?Ee= zeSqipN>WhzXjlbz~dq9Cx^Bu$Q?--Y4P z==)y;8YXH}kx1@6-hl=NEg*K&(+m%Xy*;g1eM-0p=`%&ziqPGE$Nc+PuW>iEHfKE- zKs|>Z4LI7tURtl-i#t6e1lw4H67m~oZ!^l2bB7>;5>YpRm>6lYUt$x9Z*fA6MHs*+hvrd*QE*rKj2l@ zZk(%}P~PfKhHDPy>ngdr4V96Dv|{ni*tNQM@iw}-o!ZYs(yA{VHxG_fLS?T~X9bs6 z`YTLFYD}EOm&RP+qg!h#6N2G=QVMQ;hy}WkG-Te)f;fELEv(~UuZnk$C|ND3-GnCZ zLoQH}47W;SY%n%8>worFgD>rlm_QWG_yxrI_>a0}O)HkZf=o@`*j_o}sgN83wIhmL z{MAu_Y0Xbr%kepyE=4b(hiL9_DQ3%Jf)CJFZ~--Z8(aUFY7LNAFu}>~A%r5VM)cCR zMbRm?wg=#PVe7F_Qw?j3>S@aT;GjzcU1SAUJ8iXk!|QH`u2;z8CE(F9Ndnztdrd-a zMmNBvH5oGrg=)c|Vy1u>y+GbKk|XFE&y&2~v~vkUZ1lj|#tmlhF7ow)ZYf>mOo3Zjzet^O`qJFG+*W{w zK@#;f^n%5AE$_1%o%;yE<`ciQS5sA^)~aV|C-1hI3i6Jsin2LiHI1qtI;monqpcER z9t0v?ErQj#mnqz|m8n}R&1X@N^ALE-10r;QB>~Vz?t)ix(+q*2C-;C2Kz9+U$-r<2 zZf8uFgCOnT3!ZDJy=)(xfQnWuTd`yIESs+E`KPiEy~ry!&AStUMG3?0^RjBj-ERT2Ui;sLPX=*fxSr=yBD{17q@A4-9K)9x5*DS zNvW{Tb}SDmRXsOf(Fn@>1yf0(Vsula$rIgfI=U(4&L_>sTJ21aPTx9{+~zHy7y1JO zHquI`Wxn%L7icYTePU4TR9T#LxABjQ>-#s$^xJ;HB8UOjpxG&RHS%$CgJOib`?Dr- zI3`>vL3k|SMLrB$SV;K2hk+;yH|(pmsS5M3_aUaV#8Jo=YOI}u)EKWSuTDJn=EHry&@eKcC_(o`ZjJ_XjNrV_J$ z-(os+&!x6I+J7UI4K8h|ht1qdWy3D4qD-qkpayP@o$|~|H2kpobVaXxv$=(E$G#N*(zD7OEeJ+a%C$cOu%cZex$4B0U3!NME`h*b zY8Q@xD6a>Rhuu{|VSO#Yjfkg#JO?l41Hsw?|J+aA8NAW9qSe^TIRsCOds^)s)CKKE$FN z2UzmMXL9c%5>AM1;v=+Y9*!cHP9cPr5MV>@OopV)HCC#>6uZjB)qg zar|N*-B^9tr|U?e9gO<63)e(d;H*(>0a^jHsS^fneF3%!bJvd38jIP`OBJWp`QBa4 zcxp*tMr;`skz3kC(|IZ(QPz0~ciQ0QxEJ!R88n@Kk@p!1$JnATtk#p)f`S;6Uk8Ui za$G>-sTfXrS@;yxDf_{rl%jod8nf4c)bEV>zWk1fix@<7AjJfvam{F0)`Fh5IWvt|-E$54;!6-oF02 z_gKye%TcewB)#iTs22>b40Uu;_xZPmF)+7k6k&J8f?O1tIv;!PhDFAv9gGFRqFodu z2+$Md=5`YJ9j(>lK;EWvXxz`zwF})aH0{7FRV1p1#-;ZL-~9mJXDNr;InbZCXI`B^ z(s!5U=PTr^DGfzlzJy=whl(|}VipV|XBZ@gazSAaHNjF-SHr%Ha%#~~7kL=KKBcR; zLE%qgKu0eji#F!aO-!sOr7Dx^j)+VtUrXqEDqt(f7wckEh|k@KyAIgtd7t9H$Ckn) z%!f0%0A*)zjr+9&0NIr%NhETnTHk@MY~U^HH^1*BF(kAHlP_I?F}QUk_C?7bf=lm? z)}8xxs?kJjCT?RrgEv|I23BXB0KY(-E+R&HK&s1S#vc=sVnIRLJ`fgg2JC;-sX-K@&BSOO7)539(!sFt9PP9KSGxIO5l2sf5~RZ8cyMEYY*!o zShVFQkF8qmqrfsqDjcif*`7!)rqC8-IF7{CoAE`cI5;a!Z$++*)5dz(CnCN-I?qZT zJ31R|*VWVe^HdwYo^@bQ#pc-Z&RspZCv5L-IlAkwvF4*Mf_LjS-t{4$MJft?Jr3|H z4@8EvJdKEssMPCM5h^4?9p+r+GI~p)Ww6rqc6%Y&V!vrXpvQsjOp9Y_%%VK<`1x{L z|D<0pP+Abuq_+>)JoH|~MZABiZBd6HF!4QRmr|?3^VG519%~X^9WNWOi6pFVALUT6tfmESDowU^WAmfouJ* zB;IId#x`S;8$lPYs|MoFPmS5G04uDbQcm#v8OSrJ7=q;;CYUa$pMj?Lr%h9IlNAsz zuM9XooFPw7FyTCubZ4sT_M-A8n1zP27GPjQo+iHsqJI^t6BTGjUF7a0um{C}En3A! z3pASt?C-xCf4moJC)hPu#@G` z4Twe$fTFS>lCdkOkxd+%1QhT8o?VAn!K1Um<2YE78EhM9L6DT$sr}we@|@BByUS!ETiR6a^A{conu*Cb#D?axn*d;-x1e~Lo?9#L-%VCfo>f0G#m zV%PtDlMYaW+N)Q3XjAe@?4MzFHeTQ1CUO7p^MB2xV>Fr}X%4rZYt1-l1hAeZsA3Qb zd)Sl14>pG=Q!Y;z5IXREBBks9<0hTp{}(2mr(XZJOge{u{^us047UYz0X;m9Ngb!n zZ~hM0TfhXHeS87(rkKEHrac$7|D|8-;fT=+feru%r~*T9xp5fp)~{;Ve~EIS&^%80 zYG{1V20)A$=@U5)8mJc+*toi5ndx;yph+|E=V%)z`C&5yEA09dO~jD<^`ZG%M{J5d zKmf90L3F+oZo7!GbsqvL9f3A5I9oCLESbPv25Swy=lZ}_C@lPcYR{=Mn;w0<#-X+R zZcJA5nK*@U;$B~?n1>GHr4pw$8N?3AWto=8>osmF&=9wXe9{Vf3%yFTvgA^dF-3`_ z86cl)BAO3DA4NTcqU-z48DSB~-R9rm`>4s%>A|k%({BcW#X6enm%Yty_i%2X=)Kj@ z`h;y$c2*)Aufd>oxa;IUM&m;zJq%`!6DJ=YIvO^e4+!;41{FU3 zg{ncm5QwjrUk15}O{fNb=PD*%G{{Z;KK1^8AoR$i>Ys$Y{6A*R$pKikel?KiU;=rL zW>Qb|fASm*W}*83mgj&h<4P`x5-#3r8iS%51GGUOW$Hg#KKb56CDQgViO0s!wj{24 zMrOcb>7j=;4nF;Tbpf5*?2?%=Uua*DGZD}P@z|`lyRHsso1?LkZ60;czh%({&PoAE ze)hXkwJg6uC-e==2a43Qm_7^NX_>a#m4ds7&U8)y%X11a{dGtWT2YgeIw|IWgekGk zTDNpdcl((|gTGR=!*;5yNHjM(YvZssM8x~+$k6j2-hKmw_u#+RB}%>a1ylhN%TnCe z{v*Nv`Ha}_SsCv!1jJ!(G~lu6IoX}Pa2ohE5_?}}8Em&rPYe#gSzC+H%7aFi4Z`F} zB)g1)1jblF%Q7i2K}d}ExQW#=qZ4_oTL!xTY4;Vl;y8d@M-;2pNT=JzY=;QVS>Iny zo&n(Gby6FXGqbm?1<|C1T-9MA&$QU((*F#pEC=nZ=OM4i4BF0NxQw~(Kb&fA+kMju~JuodRS%LjE-i; zd(Bx5Z8nyyFG<<9(T6@wvG&?Us3+rMls^OaeYW)~B06hqpvJ&awoj!Zlutn^)}X0x zl#WkJ$#?FQiuxymyC9Yzc@jb+CQNoI5HXj-oZMgM=^L-^POVC;h007n-;8Hh_z(uB(%{gn+^$@l=9Lg$`~Y&_d@ z@QK|>egKXiVzgJDYxUsl#bUMGes)pSbY%|wyCVV>YQxM;m)1|yEIj%ISd#*YAgf;RpuG&_H#cHhwjhG* z?6RQ{u@z+HH8-)zECyx^`FopIi4LPK7p0{sE1P>9Hz3`qJ9{1#uP=TsHTE)(mOiM6 z8qw+)Nh1@uprK(vEWHu}JLMH2T z-*TAh`51E0M`k5kquB}}|Do#*m%e9pt$A#&YsNe7pp0#!UzesLAhz3GUIUwu zoqR3c9&kKQE7@Npt;6=})?(DvE}#fNWg{-Co&M6p;qmS)xA{;x=qmMUbo+%K)E67Zc2?Ux!AN{HaLR`; zv9jAr-*iJP9ky~a5SPt|23X8wekMP-YO^%CDK57;_|9}*Q7je1U}CBbTTj}`kW??Y zlf)VR(U@1KV1-(vkzED8%td-jM2G$M`q+soYDx9m*t3nxMk}|YbaKqCV3Na-o;OC_ zc1kGRRw{%p*%kaOl&Xz81n}R2gLIFLnF;0}a;!=7(WY=N2GAB9LX_}nr&8I3K>vxL zB3!9hn`t?f<#HS5+Kn_3uP|FzQniG2@0J;u7*iE2c3`U$d5ajBhPZHn-u*II1=zTN*|de z*nO%jw^5Zq95|x4!N-2l4#ryJCx*ZOkn=LM>Yt3X4A>hZ}8z*7)S2fPhktdM^D}tBs8#vmCtY{ zY}5EEwXq*2S^ebjHd3GGMm=Ka3}oF+&+o=Es!z_yX)(@oSbAqNz6f$}|IXXDhLb`e zs2G~rsMI_K;xgBwDuah|sL|&)irqquvan=(LGz?Gr0heuDvyaAC)TmZ`EM72AuydC zfX!}NeLzTSADr4_Y;#4mUH14!`&n6oY}%7f*lrwX3?EFjr^Ku?8qEnivsT`e+T?!g zy4P&AHGMhI>y%G)M>yD(TAr+;`qu6OGu$o!DUhe1>7VUu}qH+a|E}Xgb zdzUS?vqH^sApN^Bw%QzZQ@O#O2}^|}bt0v`W+PRypkjMA%Ho9AU`Sv9PL=27L5nVV zrm*CkVxn=!Kb`SQ+m#6j)s&)#a&Hu1;~pv90^Kc{bQ`@}Qw!nQeT_=;@Z3`>CZ43pP>C4{T89c{xO zgTlMCyYw(F^~cjcC8{K&MkNJh`tw7HJY~!d>@4EEX2`XWwuQAgwR;xC z0m{1QF3hXu@wWTD2~Asr%A*59r#2Pd(BnsbnxKEudkH4A{0y449P6=_rAOb86+LbG zF{SgzsDeSgYQC!W<982!6rWe#!d02c#Ax^9kHlww7)4p}xWL6==)fkK@OHUKe4I0| z9ZwlzgxmjU^cWsiHV#V+kB<(G)0;kdXCaNP%}c|OZ;3B--O{TxE`gCZoA!k!%Y=Bf zFpdGsdyRWJQR~V>0EJ)e*IJ7Aq`wL$M=8uqXDmF4iC#KNMupGAc;wdyhtH}i$^8=% zui@)IqW|$0Iy`3uT zPhG3?nKO5PoG8PZ7zE#T6*T1%Gai|XD6*pE3e?5vg$Nsral6Hw3K}zWd}QtjAYN+y zkvX!P5_FPCe=zr@4bum%pE+YQ%R`Vz0=yS@Hd9`8OdNn9f893xrDPGgX_pS7jViT` z%>*iN`;0Jx$*VdecFOQ>~M=4^z3OXh-$;5Ju+CDJ-I^#vKIDE^e*o2&Jt4&-#=xVciRe?`?a*lnkT!KsPltVY~s%U}wLD{eK(p==- zi-0L1QnpbQvY(2{Tlv{qqXmyAy?oj~K8^{m>AxivoiM6mDX#o(-EiLxmWG&Z)S9iB zLQDkIpl*}h<;mCVPf`_|aN2w_2r4qLlS$YiCHn&RgxZhigGFsl~@03advPVaL?SCfd}vz{z- zS4%}}_*1DB$KYBQb#*(-A`UHAaOss2fubPf7LqdVq5qE?*#3{6nKjE1Ob1)R{1(@n zAY{BUm+P)Bh)Q{#lpzqAv06ml1WX%2AVj6%0Ib4oz+l=6VXZ+_3cnK<|z2_ihJtG(qK6ffw68yIwXJfMw@eL|i!c5dQ!WwpFc(udoWQ^ZlE z@_L7vK5wWCcwA?DC2KFq2nb%}2c_}Sn$P^O9lcbWTil*o=@V;oAUA)a=iOehHsa4ohWTi zTsLrrLD_!R$YAK0bvwaLTj44U)jo;Ka$({p$}bh(X2{cC>H2|b5(BiKP(sXa5&+RC zVA;{v!SQ_r<*B~__G(4wSPAg7H9}FgD6K3|B9M202=QGV4cXcr)MhXi>pGSp3V z%Z8^)g&KsX>a+;uzI0DYc^_u42er z$w1+oE@)y{0$|qQwG0vyo;_gI+CS(b?{d1|dk#JU9V;2SyI)!#&|>`fB$=>3PPf(s zLP0Cf*-dN~gsxYFd_jr9b3Pu3jf@Vt$1tQwZjePcGcoHR=C`19+U^cW=~Y`~+i}QB zUP@+r!GoJ+{3bNWED#L!MuiyM5u+Gzo;l5z0h^E!q&d^=ExeYq`8_v$H&6odCL+}( z328IaS#vF&^0UyY!wjegmGlNb=jg_V0IXaOmX^H1ES!)X_bY;{F>)P3qxln6eU5k@nUh{#FCVddXOSAiu_p{C0#E+;rQY2ra?g{xcc z{PGF+uRzivR;{{0`0j{qU5h%}y5C)1I=wfvuY&wqN^ zv5Wa0daqe+C3Y5`P?odMAFugsEf8;bF-R`V?>;Q~X~X`-yg8C4Y3@R0+OIegtBf+(^tB7=;-7k~rT)z2LjRrlH9#MKZT)+yT6HSyS=@T%*qcN|aM61(woaU3Z;@ z6)jR@_L{;n2hHil4HVw&x@EU9>r?-Q3B{x6&<7pA^Go^tIP%%S%*#ovO`GwMV>;vu zbta)B6ZdHO`&(4Uv198ElQ+g0mD$|=9SYA$JU^)qGT!#5x;xHm(KKwe@!{G!3TDg1 z8>&juXfr~$`E8PC_q!!{@5!DB!P)b0W4=_f#`V$=j%HCKZ;NRW`nw6^3;}b9z65hy z{yTR%|NA|bWiOT>Q`~HZD6*Qr9^DVw z;%GXQx`QEI*4xczb-_zHbcCB?G)h5+czxNv)TjBh&X(4_Q9$TodZaMaSh)A~4|ROuuv6FySKtE5axv^pvM7 zRRzyKSvQA7hh`rfeUdfD<9MpM`t?Y@q`&pej1>k0jp0zOi)=>1HovXl;d4YoWD2ph zE_cen910n)Dvk;@hBZnft&tDgqIIJYmetyz0Xd#APW!<6Y#R+Nidlr6xfc;7W8Jw} zW8l{0mf%2DMTn22riS2wH+@h*4$0_{&5C5nGv=r_RZl4;ZJHV$*)o`?rHKyQs^q4Rg`~x3CQsC z2k)XPi|H|Y-TqP&qoX5gTaLY1g;fyJ4();k%t%dDp%U9MzuR&BIop6xRId3z0Y56j zl_!s@K)d&@eR^^Jb=O@m?lFFH>CN#hR`lAs-Ei81Sz?1*T#$xWm6o0jwUHC08j}p+ zoBHKk0yRx>6bJiVAM+g%zY-~CLz~_>FYb+BZeJc_#Yp|>!3wLv-_hV@j}1EU*ZVQW zhTU79xZZU9hghtwD{O5jwHp&<2LC-ys>|6fp_mzoTt^Q)$UajehUO10P+(3;*z@M{ zZQTV;W@}=;ZuKmulJ(P?{|*@|ch71vkwOGt^emTkoz=S9mgfs8lJUu2*VUXGC}Vz{ z3mU&|!HAG^s2f?|4zf4&JWzgJE^5&qt{i%fWIYX4t;%R?U$OkI1D?3Z#dig=-rcp>Vme1_kX&-&&1bu@&RR zPr?ymppu`Q_D^{f{40U4b&$D@!IJ6zE?ZRnFb^S#t?e=kdYz)i90xTMJ={p}Fusyl zKp1W$tO;^)<_FIC0s-t_4~H1oaD@^518?2w%=Z&)U*LMpjF!`TYRsp&AvX)E&p&<3 zf?p6jxWMDWybkLZDP~NB2ClCC+|T@e+qZ*aK*Oz|OZ(bDNxH2e`}D#Mgb?ag-@VBC z5vGqCLBhNmnhFx*T)Rn=_*cVST`Kxb$GDx}LI}5m5{E29Bgt>hQk!t*8QaAj3$Cqx zo+V_gc>JUBxe6PJ_+JW3)|||krVCFUSTYe|m{zNMocs>fh$81DlFK~$0dpHV4OeFP zuEp!9AQ)$c&4pr?c5tkbnfT%6EClY+GyW^Y|Bus>81cfh zFe4xA*GF&6nWgTiqlccN@57@HszHhN>v3`OA(6u>`Sy6B!u=-4g8N_sd!-O`-<&>n zb<(p;`E{0OQX!Ud`J^_{VDTy3n&I@(f^7kRx|vKJ2Ns^hh?8GTm&V-Yj9pE|Ww;wSDzxFxjXe^!me-j3&zJ0NPdW#s04wjDgJ=Iq-*IylL> z!f0HXOhFp`YM{82@JW8c3Ece}ZVtz#C5<~$Ng13(E$7}zsv^_+*!{z{*~u!u#jq&1 zoS(%(g?MmM`(g#GK+e>c>RsXV z6nuWQSr~2&owirJ>O~{^dpajpj%J(LX<0?p=4Biudgiw8OPWlNvwNzg&N~=)yo&cPZPa zFPDm)HD-{ds)}LH%)1&^p5IR*`ebMAw0+2Nhu!Qcmb%NB771+k&V5dtGhRmL?bHJO z?r6{Gq&g$7u(W?9AX;FoBe$PYXf2)1N=mzEWC3e72Dvn>_ z!>q0!92zV>=-4jmw`U)Xq8{SWBD>HJkA3tepG!!Ew*h0G?71}KYvSN~(J6`{46R=M z?ecR892`r$sdD^!IAZDnI0;80IgRhmc%8jSsXD{fR=>^XgNQAl-JralLk9Y4BYWVC z9W-ANiL&cDZgV8kx2n;8>2HNMexKBxW>e94KFoRaw0CY`^{ty~<-<$f&~eH5TkHqZ zpV>Z6K7X>}*LZ)1*Qr)E-p*{+ND6QIUE9JBVFq5!(An>j7;eNa^Ewtd?y8^hD!PP- z{MWkIXkxR(f6thhoHJ?(9sFi{hoQmLLFcDU6^MvvBu}htSA5#thCJRb%cG4fjGl_Y zEzL~$)n{ui5H>%zb@cwE$aUA0RkpV)mq}}UH!!0&kH3fh;CJA(8(WnfP7sakAay-y z)yGr;={Mq6epl}2vF?Ply+wf0Xq8heOP}MM?*?8$4gD)DR}cD}-0jDK2cj^hM|Ewx zQ;*6rT`mpibgfO>OR(s>n2VCt`-UfH^lzQiu3~z%7gbQ-K zBQi)ZR9w1wE|Xlme9t(d>>?5kp*JKXYh_4yYy1 z6MefP{qxb=Ss@zLr!xZduopODh?Eo|0X z{324;G(kFyB1>S&xsGMUc9SxyyrMGEjjS4ugb!=YvpHOvb~WtG)>`cpPYupV=vRaa z!fG!*72J_A6aw5k2)$8#rx(Nz9)raIL)ms=oiCKXbJ2s8yD0n z{YJIf=HF41bfG>0hK$zo#i7`pg7YRFsI}31^ODS4GLmLOFZG0R zxSAEpUa)&Xgk6Vq@Tia!mC>s}TWuqD{WwQC!@sGFpMiP!QoLUen~0Hk8^C-ZgiKtU zgn}P();r*jQOJ4E;gph2!BqP42QMz9r>{mz~UKsX&JbH}XtcmQhMT!JPx zN1AA?wnxWUk+s(gS3tz@1|T3GkkM(c5)N3m0vpE;PUNB&Rx3~%NFVXXihRMICW;8N)jEax5yizTBaJ0S%r zw}Sm0;MfB2rJhJytamVSBfSzZlP_h7dR`$oozl76=Qge&;ltLu<dQyi+Nb1s-0~l?zx?fn{6znpu z?6?Ec#Bw8;6;nby!~;eJtq)KWM6uOMXE87=o=L_*w8224uD5Ni)bDQ2!fpt{BL09- z0`8$jS}h3L8dE}WifcDW^1DH5-_ZNQU8z^^%l1Z^#Y3 zPS~OjnEV)`*Z$i;zpc@=HSa#%W9x2G&rafcdyoNJMFCvzl5s57bdH} zs@MLe;1&`nV&eJQ3q}_p`jA_Y4;8n93?Q|dUa(GN)8{>_-`T znc>kgf{9({mFG^>0y7@OjWM*1>^MLA+SFDL%&0NwiwQNjPs7{Fu3HZb5}=8?JorrJHB)xU7SwRgyo5vK z?cuuc`o4FE7)c(n6?2`W4+~{I&(tj|>h~F<{Fj|v=yTzp+#{qs92l`0_y>e*1ua}A z(Oy_Q?A_~ouzKIxpyD!i;;!S-CS`f`haG~#T(;8(;j|i*Nv#hkuOnFxfwTg9REs2|h@sCbfz8Z86@dibIhC>l zUcGh%8bDQhIkA6a2!A+!@79WV{d9_2j}q3pvmyJb_{YHI>*0np!GRr8@6 z7uO%8@jhh3gmO8SS^2y-0iD`(-di--a4?ZD#X|VmfQ0EJG1uttE}Jm}inPsi=Z}Y? zYErRGA-MOOaQMr9cq%?Uv<2?Q>e@|DqR z;R)V$4SvuWmh5lIrY~B7kw{)=1sH|Wx}+-tUGQwgw>-0`NJv!Bj%zo;rA_y^O= z1Ne6kT4|))Eq|kttc?2ZrIfGx=&^Iv`+wql=-PmxO-8-F%;K?b0|o*j;BG#D_SSy# z4@f(k@#W>kqQUyeI}tI@K_ogX)wN!oG}f|7N|VsFDacD&NBnTg(%GD5dzaPu>=g>+ z(gIm+f3`xcd+}A;fYYnrbX1UP*n4-KAIk6)ctTK--lX=-G0C3DxA^k#j_Ks0Xqi#fqxAQFi# z=k~N<5Zey=XPC`}b=Q@V0#OaOYvT?-xrC}{rtvysd*Q#m9&fvr!YX)*QB8T$Nu=z^&6<+Axdnv9j! z2Ol3;!c(13R5X*u|2(S`*JpRdc^!|Or1<<$O6HZrdL#0NQ8EZ+geo&d!y)d!9r&VR8s~t;rK#4S#SU_ zk5din(SpeA16*2J3@EMM1Xwy`P-hLWiZ!sL-3c*pg`i9KFwvig^r_BxH-HsaD`2@k z77s6mdOrAl@81AFVN8}C7@qhZZ%;{VLv`eV7ye-|JY|Ji6Ef!NMbAo>7(sYss1azt z8R-!Hu{w(o<_8EeGkOxo+vpN5?WRov-bn!Zly^xdD0H3MiD(t1r*E20p%zHt?%^Zu zGR{lOqiMCC5Yy`2nrc-T0^^#E)GsDib}!R~-e}%UX%`h7<+sIkXEIX|bU6>&>YbT8 zB{ao?H5wRHxapaz;Z^?1Pirv)4!2a;t{-q`L8vBjA)793hb13}%OLGbJyVDyj1mg+ z_SG;!#(tUXK-zX`*Rb71>2lGn@vvxCa8Lx{jAVjelWb6K_E zWV#5}Q3Jk|DT3z9*OOI^(U?*^uGMMWuH1Rti0 zIx)iT2M{kpw!YuxCW_VTKTOl^FIv(dErFZ82#*(3!Iamm4 z;8ni+NqG<@RseqBU{mK{9fhcr-)i3L6gGDU+X-XTo4A8zi*5 zY=O&ilw?TM&A1Aw>m0?ch+4h$!nbvbHMN{&;in5#w7R9@}@$Uxk zW5)!vWuwzb$7DZQF6pyh?pdNu2iMow1+fb2_*=GKG90S{GG5kg5L)Q?6$=Z?+f;0B ztOI#_MA-1C{b~enc|h~%^5bM)8q83f&@&#{dhw;et=m7PwkJj_13V53%+~dO7VUpP zT`C0rMKdDtgX}ne+^W61M|?Dh^1@%_NVb*qZpLv;={M_tw#UgC%(B@6))n%E^(TI~ zPl=-TsxtahBqfU6UZCw0TL%N<}sRJNl|G}d+LD1D{`(>(etEa4>WF6`^0&16WpF^WqVcK;ti0+gm4C>X3wBlkO6OTbZ^1F;QA7VW;aYzE4f|A# z=I;2W7EW86KYxcVm2avI-OkU$>07tz7}}K8yD}+Py(f5!0(>#~M`iAhCqL?b5Ui>r zUWj$~fJRH>o|y(7d|B$gP*QVmGm@5kwMT;s&9`fdcYd!WTA%5$&}~Jdg&$Sikm;_s zxTkfi*VpG~p@NN7=I{)Pgy;rm5eafiU`yo66pS#3#=6gYYhw zd792LqoL3g4KgHu{Kq?+6L*vzdu0b^24(tvdmM8_CuOm$)2xhhNs{PijN}+Cjl+(9 zU>jlgBapxf8)Zap_P$7ZXwKJO%_oD`uJI>#3!D2N_v>0^nJ28r(i1I9YATQ0s9ut_ zvZ_wY{3qt#Ix5OH{_~a)QEKQ;6;Qf6B~(g8xJ%w9SoX)ASqe-3{GQd?0|9lM9jwl;fs30lg%b{3{(xy;=T0j z=!yPs;T!juM_0~QGiWoOH@|!Y_;k+u)w!rPDqo1iGSbir$Tp*#Ut4wmnVH_iU=-@? zKzxK5qkLjqX6XC;oz=Iq*Qojh0e!ZTg@jkt)YsF;C5q_TrhPP1JS~Ag#Pa1CaacRc z?VqfVBzAOIUL&T-PI%+OvS*IA8E^DFhaXz1a=5xk>#Ox`RXeYZ@ms!ld*N#Z&3J(LS((1~}12po8=AEmd{k0{`kZZ2MQfw*=f4}UA zJ?uN^#kyqm&U$su_b|v}JUqUc*zd`pEOZZ6c&`i=z4!k?*BKfj7Bs(DrLg16MVp;L zgpbxav%cT>X5RnMg4CBVSIHh>b%}3q*g|*%5azaCCIMBCIV@``sabE+8J{2@Mf#=T zDISH@<%t&{GLTG<_&a+LCMx;kgu>YosVFVKk_0^bd$q?-JOgz+jSpkC)T8>~ak*s&9EER~e+E`NU3r{fYL4tR1aBtldEt@H zjH-t>xJRtEdaZAoSaTwGk$+qo%cXSO%!?@Iw5T4whq^Aa2>wLV61%Hy8Mj!xYG24+k{$BwiRuB-I zb(^5>x$FfXUWPS6Ac#`1r-Ue(XQ{iJVGAfawsd(h7&z5sQ_aA=Iu~{03N{ z?a|RLDh`f8_J`oP9uKW?d*{FiN|#(%YWyGPfl0!W#t9ZJ3L9N5%d-~8flqODA~X_% zNAADkXtwKBU>d2sj;s`CqnYddEu80A3?`tJzTq3+nA5YIotBpbE{7Veu6F?=)4GeY z<1fc`TMYm&1dv@vlG9eYI8&l)4MCutxry6^67R=gv6w^r6;}c*0`0Gl$2ztTy8gpk zKgESM_7^hs0aR=m8B>RKEZ6gr8f17?{n;WQX<|Wy3te%C0T|w#&qcOz(-61w$G?^v z!}-RbalZiYO%_h)obGG}gLG_-grf&tjYJ1KoBp2kQ6OE92#a;Xj8_P#RU9f6rr!cZ z`R^73082IWjEZFT5XupbL=V&MV`F0@=AaqH`SG% z(0Z3tufM#OYzvD1POnN~<6}*!Tz{d{_FhUCuH-#a7JKF9El?1}yV94DVS|PIR=6~> z5pR!~{|nFKTlAo4&VDTas!*(1DnKh!V|woZxDQv)0))hTSEjp8wU)&XJlecKD~ zP{wup$iqC5-rt}yK837wc5;aixEhf67LNfs+;I*z>Wir3hn;%P>Wp%ik6`uj&UDuMLllx>Rc){fHN)C z;3-ct%*KiGOreXr)Z(wXdeU7ZrRzh9Tc@sH(v$ftAEn;IjbOpG^I9qWAQ-AxtvBK>N}WRq<0|Jce>XjlOirPD67icgPho>oDd}cWHi3l*FTPMEqW+RI z{h|!Kz>NKFMHypBf|Q$cS7z>hA^o@8VarJ;zfs=Vh6BJp+f9}7uI!XiKb@zUeM;y2 zz6olYdD1E-2}rDDt1fMtNhD<`5(Sn#SVmAhrp10es149sd9O)MmWv;R57OhH-z{4> z1xw=r0t-EgcloQmMW_yh@{_h{edqz0uQMujb=rApIwL{U`tLYnc3MRC+BDVC;{wgV z5k?J0@<~TfjocRqmfFbr#sQlhtau@MOdIgK78|Zpdql~|!N`aF?!9#x(R3E!o>u+| zBT>jwgO3EUmPz8@UbNqhYg`mDw+-{;*Q1${ymy?m?7U&;cR5wmyBU<&GWGY9K7ayH z9bpEO5+AzpgpR`q6;ADLR_u^JN;{^}0u`9Tm0=Pe|F+Nfo@b}9IuZsn4ZOMADQMar zX~CC+8YZhCtmxaIW383IC^&0|{u$>Ry)A2dxu*%7AqJCqHDy_G<_fI#Y$_5PZkxan zi!TI1(4(s4IL}d`%UPNmW3#=7$IzQCC&ryW8Q77nQtSJgMb}iAjcEFFFZ%g>#+F8!+LmR69u5BE1G7XbRH<5ZJv@v6 z>H^LrO{c>%^PZl*nW(;aVTPvlD5(>AQ9b=P4u50ik>&1+pRZ+>?O=)Nx_76kgT>NK zUop+TF=NU#r8-WR~}}j=b=~uLH<%9?JrpghKMkTH6E@TKQ3zkW$ys*NwYWmZX_+) zrhe^^=dKknzU~Eav3w0f9E9GLYphEr%1g?sC!p1!KaS$8pwF2RcZ(*DFx$wW`i7mY zbfu0?@n_ZVy5yEmJY7oYJZjCc4H5Oyi6{BC3cMCKAWkUU-YVCi+t8l`GaLMd+bv+H zDd75$)BMhOR7bh9SauMdZu-M3gt1w<`K_8j8X2YHH~{oWuEpQ;J6$Z@2%-%!IBTMD zvq|>+quF}u$M^7R>M~X5GM9G0+PFQ=kMavT(*JmPDV5t*ty|)uxXvJFi*kndTJQpM z6Ia@`G4GL>s>H(!dE!EIgvSg^lLg^w4mVXmqhYWq3{RF~CFg0KkXFzFQQ5*4-uG|2 zVHf18q#fiL*BV#e^S7tp>DoEYdVhPDw5kATy$OPKZQz|)#5c4I-afL;1N~4}x$cjN z$E>2D5|05^Uu>IzN+`_p2-Rml<5mI)7>($twCO||P3|Fu=JGpcH`18K*yl>{5f1jSTLQ##i(#$Q=%Mmp z(m6QY$tA(69jZ$$OKiF=;DK9$_qMy=6p3~pP+j=zpbPs9sN&ZM{(N0k{&L{L^@Oox z`oi5;N$66SE1P36r2KegaPj6U>v-95^FmvzOW}*0jvPzwZ<*Jpp$QWuzqMR?>UkS} zEJEvOfV<)hVt|>fDke<=|)yOQD zO=}!M-KiM&(7C4ep;?lo;_D<`!|3Y7bC+xDZAs*>1YW@q_d>-g#;<;lAFsyQvB-l) zk;jqC>#BDKw&^k%1__Si<%WqE3kB@Bbb)ztHUjr=`#7dyJD%?h+*hJ*45ni^4c)h{ zUK-nw)89NzE3Vlx6bq-LsPFuw$wN}4YtA8F?X*4982SX+<7RMaX@zhQhky2J;(%|n zojY$!>IMZ>CJS!Kp8R%ntY4dRMJy)8ZB)K9sLo!_WVcS2i-q>}L^Tmkzn^F>vx~+0%;q}V^{8$FA!_CosTod>t%Ts(^@gbKTYkE!H ziaw6{zh*u=K7TMNG^!dhsY|URW@i)xSv?M7!B9_E+hCR*{(6_S8QmN(d0A#*It2T8ZZM`5zwn}B&3jPsP)RG0fA!>! zuK0sFUX2F*7q8@I3#>=EFB?*GpUN)ZL8rhQ>tiIa1RDnLJ}tMHx#>5HmN<2m7BR8LJthtna&)UstuWeOVa&$iqb!xb z&}{T2kS!%jqM`b=Uoh7-9P*7?2u2y7qECIjFfzrFB?&lIu|4CX-d@KRSNiiJsrHY* zyIS8&VHY!Kuj-6GqOy6TU0tk}EIit1`f1HvYC_q$E}ELKP2ze;!qVe0Jq0}PSnBi{ z@xTVrJ6_iLiK6}-zer%zVO@NkDf^WnDHvw*mMjUv$&ukiUZe(s61B$vKWn}JJHOQg z+i){D#HI$jo#N;P_WC`zJy5fum&Jof0!MechyXM>-v0-r%27Y zn%tqA9^lsjUm@!IvdqhW?P17;HeFK>MZ%_J9&Dy@ZXJ>cUJAB1h7mFagMM;iPJmb2 zc)6K^^Iy8iG%s*Oi&wtGcJsO1n<$LMV+!n=1UCySOgy!^Gz<=w58o9tG;!QBs{!fz z)?ge;q#ZJg%8~|Co@V<26KU_kvl~{t^vQ>2fHA`5&3?_Bfp{Ty^r;cH7=};02HE34 zqpi}0)>o?#I1TE#Z{%S1XmlS8$o9P|X27Adsy(J!@cmgx?F!8|nW<L++Wo|rgmsu7e(n3$=6qQ^uYf>jr4PhU=Ls0&G7qo zsQb383UkGGyf23RMvhVf3$i&7?nW}K78om_5P&=do8DinDi~sO=HM8S?J0WR13d#T ztO%6!9W*35Mk9_dBl-cS&&AOih9qXV?Yl(%_fE4Q6@qQ5D?q1}7VlJ$y-w%(8E4@a zH{HkKq#qHwLH1yJWm_P>k$gRT*T%@F_zj8Hz4mxA!5nI%4}WKWf$)9v}8)y~$r zj5Q`7`gR6DP}C}jJ)A1XYcYlq_F{s;Zo(ts{ z`V5#u04?&2c&nVI3;!E?>mXgz6UI-8cFi`i;;5E87;tz0UZtnQ#K$H!?_M#98x*?> z(z>Y$tY6k{F@hh52K_kMS8vVAX;=PFzE@ilL+ zE%cIeGKgDHI?HO5X)9pz7->(Mal<3kN28Lpzc6+SS#_WI>^NmuP4zt%04!(kyzJD& zFam+|y;-lb9?9b!Jn@ECo=q+S$@X73CXKR~ov7Uv-8&K08_R;0 zuQfW=h*R?b4pSXv-##Gr+PkC8WZ|{@r#869);>QilZvWj?)`yj7BFdE<~hY1vK#mBF=6FoV8>U#S%&g{d~VQr{@+vO(4fHZpPk$uv5{5{5At+M<*FWO2m z37q`RkM;;zvWSw-@5bO%k!}XcFNmYG_PhyMhv$zVY3`i<`XNVN#U_ zr;5+sgiL)L4{L<5B#xz0DgOk14zpz*g8rZ;eNsFh%Bad>>oZ7=rP4x>pAw~F>JVS) zI29<2CGR+@L}imOpG#Z6j$mhdM!X;!`cpg~`FlMl6)Ay-|2!4j(QI#FYrn3%{2=gd z$CCCq4qhNyiBoi9&U5?MG7a*iHydH?2OM%iY2$F09ws`O) zx+kdIVP9@n8%~L1l!o~GKx#H1BVeATlGw=mj?s49a*r0V$mwygB(+bV(zy^qOCte! zu-$zhB-Y1-2m%(WC^Oz}{h{(1sMxiF(UTza9K=5tWeO6+v|Gr-3b=~3&2<`bj5lP7 z@6)9SNnlCZE$2S>$yN{_I%2&Yt#a)JKuMhrp(MxE-pBO`Wrbp0ok|x*9x7df`BYVX zlR@=4J}n_#39W-qetLZ`G}O^96m5RHdihc{ohS-rvxy2Yn75{tm*@40W6uh?`F|dL zch<9yZbFLBe?UX-f6m(f{9b85tLlmgWg_bgsu@?~2YZC4uLE*$lXQ7Z49M0hYf;N^sm4nQ`;1v`rTGQ)v2jcBu z@G`RL{D9c?<3McwuUjXA(GdxW<^&6^8}+EXjz=^XGgbalA71iXkHh?QMLhCUFzAj| zJUQz3q;*9lZuVnLDVKU5D<8bL?BDS=r#*H840QzO=hPEAoKB_lKX{g}O2E0<)%2=3 zY2V>_RaK?%pM*tldK+_DsJ|vs8T8AJqW41e!Sw+MTy%{#>@ro7cjOZun0ox%Wdj8+ zQI`za#hq&gCfw{}sJ1?Of4^AoH}_68*9V0-PX_kMMW|xeLB)` zE0X*mnX+qG!jg->NZ$f&Q=!q$>na&K`zW-#C|C{s$cT$=`@WuElZ3i$d zEh8}R`9ds$nIHz@U4la>)ZV~oUB*4${q!L=fDytE|EcWar-40UGb$ml7@K<;fNM>C3FZHMb*+rx4AQw7zMfr5GCH3laJRdVT`OID1hE1e zpIEXO$cTmuelek8#u>p>-9CE(DUHo?j#%>anJs&Q-erH{u<_HX_IMTXiSkEc?*z53 zNrMhKV|`|LES$7xQo8eLCAVO*7lrqQJDfO;RoQ7ry|0)2Jpsi_VTw%ZD!&36p9{Bb zzcpJVv-IG4vhgfio{EIyd`0j$KJ|l$RO6HC5HB(ax5d)vJnf8j9V(gu<j?g z#9bDV*jJOA8tl^ZB~91;OcHPDIY%F)U`@FvdFk{*!Ru3u-fv4g2~glZ2$|piE97mS zNvvIuXjR9Iw|L-@89CaE34KneFTNGp2>(hAImx-2jrvf-t-O{>B~Rs@{`%g^`|`b& z6{AC>Vgu3f3t%|4K2mVfCriJGQwb4P-fWsGGmFo+NhD>VH9Iv;sVytpI)t|`CFyjN zVIO%hPG?=39g$*(gI=u2$+=zz#na%KkIH2!-RuQq&fOoLj2ich4P%YgG&`IEM@x%oSF!RM)~!chLXo+O3jN;aIj;a+Mc_RbG{Z^d`hc4wcR zl`H6A_^KK(a}bhiuv;bpZl$l~pJP8?U44pSym;nO1B%8xJbW6`J0>zdbRY6d5v(c7y-g?mgcnxjHjICvPf)zak7H(^+enM5K<%Aqx+{(`F*hSAe^ zK+gS*NR!&{p1Un?O$lj$^75&Mis!i!nUfEZ{(Yl3$6t38dChDox}3B<%6dB)RSp!$ zVTzL<#Xkk`c3w~}GZY=I=s*3uLXd4YlnAtn+gi9AIAsUNFLb^-dru}PQsAM6^QDeT zI7~%(U%c`p`Ly#Bp~XgQ{SfK8X6u4q zu(6v19R;JWEBV_Bg2v~C<}Xp_Y_Ma4X`f}sxc3_%B0iisg>@BL)tO65^d$t`EHk~C%%ogIFc;H8mLE=w5obQJw#g$hLih=aLMTZDLU}x0O}j`_vs!M%zkt`?0MH6%SEf)33-^ zPS~CwEVISs49(MK!}n1psO|ky?oL-;LLIs2^>~u>&wGf!Zo)qLepT~wh8#(fyrO8B z4q1n)$_Fp6Um0R|DueXYE{v>n=B)F1Olp$k7unT88d={tDlN}pE(cwo%hcfP09juk z;BAwV%#h@@$?R7-`+Ddyg(Gv(1*J}FV*G=D=)a4jRJZl!YO$ZdJ0i!EHdSGaJuOd7 z=##kh{t=dXR`an{_8Dz1l`nQIhS?((Uu^BU=AJfR!?|Iu_~NLPN~)8$I1aJJVG?p^ ziyzCzl~Uu!rpcJUSbMd3@0yuT>=co?5{_`PaS7;njwDp+Pbh7EGx`TmhjU8hetYH2 zEKJfzMxyPZ@#01>+M7LM(BDW!{SE%wk*Kg=LW`)L^UtJ#z~8E5u=LK6VaHVUM9N5h zkI&k@*RRYXiH_%v^iu1c07O=uutSzf&h%>mr-{J*{6FQL-7cNwsnQK+fnS(Erf-;4 z4(97Au?cuQtzDHer0S%UYlw`?a_Z`gi!KJt11zx99N>yN}HPtpd$@f)u3-AR*IRkr#Qo}eSwpRn9zpz!6pMML$pj@|qi z%hA%oQdghC_VuJ?`lvRm@L06VOI^$XQP7p^F9E=tvU3;IpWD?mVXqJT_o|70^7MDn*>iv$l+bxUIT?%j6zopW%p4Nla$ zSb5X(S~Mio&6{N*sCeMNyYLdjre;&sft{ zR}&FU^)KXAolIfcO+tRGt`qD}QyAm9>|2irvgP?YKcLyRNEcoRIx*UuJ{R~jap`hR z;j%Q;`|Hfn^0d4+4d@%mTxp$cpHKyMjOy`NQ>~<(^A6T{Z_^3)F z&8=u0Yqg*_DRkND{M4!qUjWPF!1K9?@-?tGmL1#9GB7i(UR-2Tg_cT;<@THo2R#b3 zplQ9RRb`b$_*bVkfJn4WM>wm#Zb2#dTQ*0)Q|`c6rg5~s$QE#TX>qlT!n)b+nw|d% z6SGv;CmJ@0#I3IzJ+LeIkX@h&%OOnDJ$kQki*(3vjcYQ%9AFJr%ETAc!~9Je{IFNH ztLKe=HLi8bSoz&&YNZC+T;GN$K4R+Fp3@#g)o7xeMua^XWjlXcBzWS`T9&HLg01^u zB!II5ulg0cjZ@FKu#0r)J8o-sTvoMdGNA#P8G3SnzdN3WfB_lF3yE(+YQ?#|;=Vf@n9hsPppJLK|LHbn2~9SgxWEBp}JX#!7m zT4LMu{XmKcN=-}#AF#8!OaDdL1~uxj_pZ}zj6JetH5eIp*P+-d_`h;$z#m`WTRpTIsfz~NqTPi}DkHH2e>;TKOyRVG3m?Ma6xT`z zv(>w|hVLRs5Ca1P4xn+Qffn38SiB}z9JiOVYm=NAJjkmS+*3Jq`=IH@*2$H4!5haA zuK@YO*RDGbM5bkVLDbyc*y)o^>Ud`|s0l(qpGXgD;T2GfEGb2kJ1k#(M` znmsE`GcdN?4}(pygD^1^QwagsWL``zqN8j1gk!s#@@;bSY3hc9GhBr<$`H|oeZQ?x zLKaU?($$CEhpT;fAg>Y;umZVMsJ+gYlNMLX7Jr+5_`wIob*L90T8r)~HNaXH*+UcQ zWDxP05*IOt{3~F18`a_Ot*s+YgDjQMb{A9@5A8_mK)%bkHArMqNImNnJ?xgUJYW1g z1^5+~XSK`L?31?H2 z3EnFgFI6SJ&E~W8o^}k?{<3dWj_BokK6LV9dpKVrG%nW;>kFkPChz>GwKh+FWE0Nq zqH6uK6EWc{T~dbud~#+jJ}u$=RJ8p@i1hb`&k7m5-1_*Z_Vm@eR6x?jUS<0ZpgDY0 zPTgGpIhsS}Y}pmqtcHSEUJylAT+f}g3&4pr_3)vnkA^7lXGC`V;jsL~zpCX+CW-CZ zdl<{O@WJ1F4reecP4Yr7i;&hu=1cZA(_>^ExK)_W){u8N)Dh6zZB^7X9wd}hB72vk zYWJ6SNNv~Xb6f(}7RA?zQ)?9OO6Eq_eE-sr1CtC}(&GqGN zF?&DuN3d5F^34E(F)C(fJv$pCOQYjE=_h?RTYV;cHoHg6NZ#Mru|iB?~RkzUD)wh2E?O2nY1-rr}iOp2Ey?rJlHdycQRjbLDo z4*tsuV@He_x_*+NAr@JT3-=V-&AsH3>txt^;cD9WTD@F0K$P@DSVjHMN|wag`r&^oz($d^KK)d2CQx7j&rf z*>L6}qj6ig-?EIkPk6I%R9sjneZ=s+qSheNIky;SW;HJumSB z@E4ZK2RmkZ2=8c>en!Dp>{}fC?1Ra}@LnLF%w11eP0o*a{+n;|E6{dyPH_+4h^$wo zIT_pTTIzcQsoL^Vp%Gf6Q9f;+;jV4xjI#`D3W#4@6 zLx)Zj!yWf%(#OKZHqN}l?gKmnp=QMN^tkZz)Q{e|0gI#0Ti*AE(WCWBut{I!W948o zrVamEFy7;8CjY#ifO44^a+H(#Lq!NieyKDoxKr|+6^B)pRZc=mYj*HOK0AyJQMtj> zr9Qtxm({oVyuie#o!?3Ghf1H8VVS2QoA$+17Yl)3Vu9Zq)}A$pqL?NM=?)MxY}?rK zXR_+uk4+N(T8n=?P%W9;$9hDKOIeb>MDd$QjU5& z+rs{bKi!b#9|4;>KqsqeG>P{eAXbtXf2+C@&VcRn@oxYC5|Z&g<7)|@&0p51TEFBe z%{vz`9`Qp(j@BTT>ax5Lvzz{cQwm96P^A&0F)_u_f)^+SIP`1;YKQs)J$Txympoey zG@(w^e$)b`()i}n7U`4Z`|WJ%)lIX=MsV!#bjEajm=^Kpb(b3S{Cm_7Yt&gS;d|we zyxznJOzs=RkmGnSTU^Ko#f5*TeO_nH`6VLHa`^lPd)6W(7I&FNzH5@4^!Y`ly#5~M zyN%aRzN`7c9xAY*+LYifXZX2Yhdi&?74bX24b!k!&J&8pG%Rb~s7m#Bn-KZtwspGu zi3C-X@MGsC4{Y3^OkFF~iur31JDOp`^+Nud(1CArP>{$EP0eHrn&ZaO+aTJGCQqlu zy^k`<9v*`Qe}`y-4H>W;s#1fbv-dPa3?}=qE)!hII0n1_K$Mr+0i`6Ieoq2wL z3#bLowtT3jj~08JWs7mWzDcYm>n?H}XZa4G*zVB}>UACl*TpLf=fBFcQPt*mvVs|e z4m5-HW|vbxtDl(_j;jtYf3-{^%xs=rGTQ^^$(|_B?k4BAs*W}5fpOcUKLlC#vBM-O zG50UV{K)6rPn%{c2En=hah#vC$$D0~v@`0r6_@P#eO#_~6O2F#F1h3`k_6(czu5WE z-gYgWYrp&vICzQpKf4nDUwJlA%>tl2d94P|^GYAINO}oNWzKkM^Vr z+yh9QnF?JphSD!Uen7woJgSk9LbV<^X#U{_pKOJI)q3f#U4S=yPk08J;_MJt-uOAI zg&yTUlPRR6ya9AUc2?jTE7YyFedRv=sEU@pgYN*WRb=CQ!E!u{j~%E=!syE~@fU`a zMc6>D*|NW^;bf8p>Rc}X$sryX-v=JqGX%Ge zIMDbU4NRnlg9nf1_uT7=5|ts{tbU+1Ao^SNtxYN|rGMhBHh7|ZrOZ=6@RlkLSB479 z6W3>DOp3|5G1v;PFbZ$FdLY?nufGE0Y+ z^#Fk3;t8m)(QkojpfRKmX3+ny`rt#VlqnF(4nYh9rURp?+*1Se*|jkL$r2JkF?jnP z)KIw|hE{-tyZJ0w>*qy4HIhq`wMHLU^2u2m*Cyzh)(3nGC+->DMI!{FU;&i%@QINT5w#5wk4}~h zxQS&5ge@O^kN?jK;RdK=YqAy#J?cNf^amD6r7`0cpe`fm9%4crL@+y^;9Rp$zOG>xRI-k|3OxzAh@2-5dm+uVo z{X;`1gbOHG;>~;%H1OVUgFur5ZT^x|KhWtu10$gUQ6B`4yn$rXi)QV>^=3jg{Sch` z+y@J2Y^Xx%>_7j<9P|eck>Y`FAYSai@BvgB1aqG0AylR@51|w~*lC-30_^C+5RLRu?skVnJ_T5|^2sx>xAedv8W{T2w89{KBW(RtB9SsTHh(348x7X3<&KEH&+*7YBu_6H zw?nY%DbYRD$T}2FRHPMUR<~lXyXpPKq(*@A)=^QnM=RYp1fC96jLDBH(|~wfcIR`E=*%CKri{Pqe!ZcNFhX+1a3Uj*w zJ3u%Ko#g`11q>L#w-D%_2=D$!iWp}}-JqPp;Ria_f$66!(ADY8otk0-4?s&2!-{mP zF~Dtdm#)|1Vf$w2gG%jwNNNI|$A5p`^@#*%fcwR7zJ+$VfwTUtO=>E+Ilp7MYh*qxuR$3A%xTrmUqt|qFrD+#)y*}#8PlK%5pceJlyCHMVYUr@oMT*J|JR!zi(*+dO3%OdRz&-Sx>o26+{ zI;H{W1%DR6w$Th=P}ty{lm)-LJEy4{L)H(s^GQsar;&bWQF zpPiK3km1i)1@YtD9oVlm--)QZPY7KHuO}EBZ1n{Rvkw1U$1~H{y6RWDbfFYyqH+l} z)UNTJ`aLFG;>GGrDPKb9Bw;Dwa)oz1o<9PlYM83Dt&J9i;A;K;e`V3}zw?;k@}&`K zw`qJ(cT5)Jw;ardRII^eaIiHehen6WBHNW!yWlqx_*L{m5ZvDF0ej}xHdr~V!l4nP z77|?OaUnc1G|Ou01A{m4?tCU?gW3Smk0JY=%^dJw^D$3D@6I5~(qcS`tG&^(F+;xw zHX3+&45#;jNRS}w6*R15(-{;4*^9}8*0QWaQ1nXQ1Jk@5}%;i?x zW}`_O&!j^0M&7cqc_Yxt|3E8!8OdCrmJvPDqbg5L90=<%9|Lw0ed>#){M@hMS#b~0 z;6a>5`mJEDLqY;p8~^Up;*fluC<@SpxoMifZwm+ib%vl0>`Y~>5)MHYxmXLFA6bGnfZz-1AGsQRP9~VBocpD? zSUrS*z#SuD8(be^_TzCqJV3VMJ24LC!{rIkn%I&7LW1A*MI*k_D5qUn}TA=Lp+Ra0`W}(HMI_tfc`g zkE*jzjcp5qOr|2@gEOoYL{_SP#oYG~`-sDJL?Y2-2P{(-HYQQ2Uf(bogCGrh?A%NM zCkU*G7n-7{^dR~D`BD1(6&|vYF1*MPRm;t|-ZIx+HfjCBq~zq29X|&$K}#zz6C%z+ z5@+Sm`n%!kp+Oc)R~16A{OM(3)b$_|t3miSa9-H>nj$W?D*B?cTtQ@~tw(p=QXArf zyVtYEV2Z_~npiZx$Gh}&;Gr9LEnXJ5yIIqTP8Vpw-U<}*p7^i%Imj^6Kr(VY=8W!b zC|;sbLawBs1hE95)+n?kgBczR8>^Kb3RoN2M06bZM`U95wmv;hw0W=$_dMQD<+J%b zqsN<9LL`$>|4IBf@RETEj>&t;Ru69WT+m6$8}zn1yc$LM(kmSPLJI_5T;Y3t$BCHO z)Z~YXt~^C+ufK{CiJ5(LC%sS6@yB#0C-a`M;taV#+C<+7Dm%85QgYj7k#FEEBUZGU zA0eY+=<(m+=0&xWeIStK{3?H*CvUjwjqKd_z?bHYH?GJ;QNZI`_(QcRG@v2T+U>JEBR?$k8$npkxlTl9xK-Alko3#%FLH$oUgsV>!{VxiG?i~!0iG*#KLj1RgNFZ) z4n57D(^M=zmbGrqc;wjObSaPKvMLr;^8Tt-HN+)Hb(HoZtm3`*Gj+p;&n#}r30EV; zIWKR*kz^ZZsmkoTRd&psZwe&i2LR@*O+v{V9I-5b%O@m!Ok5D#tdF=>%eZ)R62;OGy9UjqR@OcGq_JX5$q+lDziPT9-S`Ay~%t*wMiZi^z{g3_vfgFN1^w5@0&_h zyZ~uNq{IRS{pA0fa0XT*kmeKU)a(cz&T|7LFx>Nf=q%>^Nt ziT%)+scXZR-5Bu;3vW01>Q!*nE8jf)DP0fHyPAr*nvm&g57bzbg4cg+Nrx^hgHI?H zxJmd>^+isAtYXLh4AymxkSEESF9GD5(+mQm}8*mm0o{{S)kXWVeCXN0jL3aesr( z0OoM^i+H44;R~6#IY5^4n|AAbk}Ja{%iF^sn}@Fxjncs?YHZWg;=rmCtq*V}4z$FP z3Ekop&2VF`3OjIy!9@$up1iCoa$oEez7KgcZl!m&a2+W6GKex zm=%|zRFIr2#G9MIgx6ot>26e0N>o{Ef(URFrt+98uO<3sAje%oLiMRV1Dm)Hq+OpubjYAf4?>?xJ z=q`Zj^nD3nF#gSBefSKvx;$Cd6lf5&yZo^fM&2AR3t#hbvDb!M-f z(hlKdQ3#PT9cV4D`fkr97KsDGW}qC_p-ki7F<{d=9)0TwF|q};>8~J04r^{$BZr6w zBTc8xGF^1jMM2X)rzr4h`Qmro_T66fIcPxRl|}S`(wp;)TMylIf)h}?k0vCy{6ur? z)<&#Z>B2gg#$_tkU4pI?nx2iszDH#*NtFu?Xs&?k%WwRhp36tlvnlvvF)TigtzEMz zdPy{B8qy55Y_;NUV2ei!COIxwzF@V33z_bz!2OF!ry~XcXZ&e_KYstR1aM}^W}_Rx zN&$^2%^uzy-T8j1L#WCQC@LH>+En!Z(PxqxkA9HRUV^~jh;YWCt0HF6Tw+dN{C36R zU$pZo$Fp*+NfH4MFA%4_myj;#E$*r)$Q1)&(h8^oPtBG^EVEtS8#i6f>{bmjlvrvV z$kjkLG5u;#fj4!yY{B#8v`8yU8O=7W-3aE-inA~)@vuTT_193=Eb*5*MtpT{{?*Kt zy8K}Rhh>0O%SrnVu5WZ4#*HDXs>1iRFdU$Hyc9JS$^c@we;x4cRB$FUos`&C$IF_5 zNJ&I1AZM8~a%HT?vx+$*GxK$a8-T)ed1O#tsCI9pu0(ImpeRW4W-UkH)sD$;UAQ^{6x~li3gKT+aH?POTw1Iz8d4FqsQrQpoCo!arNwk8%gQ z@p$r30%=4p=^HN{)Nob@IvPEg-pvOweCh8Cqs*-bCaZCM(~CY@bH9E)FZ+gH8RgTbDhyn-xF#VaV^O1=P6dDi8Ry5D`e;&^^s_{c(=^dQgt3^5G7vW z2DwZr82|*CQN8hSk$zp3OG22S(@6KTyRyN$)q7f7kU~W>ZR7aeLLSMQa`F#rfxbU1 zqb?U6IP{1!e-`y(#~vdtv|yIWpF6;&-EYwcTp+U*k}>Pm6AQ?_+dV>QOxCwv$7uE= zosH8H&hlTlY@prjbJdW$MWiSHb)fVg#i(^FSz<64eI`H0@^kMTEI*+!smMg5kC$Hw z`8D2!qeCpjx2AyfumASHjQyM@Rs^3=ZXO?kWO3Irc(`%y0`Mc36|# zWuSfo9=}M9Ah+3CJvaZ(;V+l$;7}?`*u_FWSe_jOTg0!7@nc3F$Px~8__D1v-fl!m z@~Dkp1Xjt>7vu4R`)C)KnPo*5kVcR@v{!uKKT%+N@Lsyxx@E43Yd=NltrAdP3a_+F z-s1vWT;ExvF%q|uUF37A$dngX!Rlg@nN%)stOYF9UpNUK@=;ir_~b>&NiqTYOC`1^_^fg?#yTPGd)bF#W1^82)}N^yPq z29SF%AvZto4v62heD$a*Vt?;Kpu6(Nx;S7sK~8mXEajbY>=&wCdo_NpVe;zh9f5S; zMY8ZiVWm$EpHlNeveJL%NDw&)*j$Z0>9pA&T?V)|OjQm~?N9$%KK&mIzW*ykhd8BOUqxU9}a6VWz8g0YNI# zlE!6N6+-$^{3?F2CZ!1G=x30ir)t{|f{20=SjDR7@vs_~=xPos&Xx$EvM!!NV|gf% z3LU{4gE^gQA;k6LdW(t!4Z}%_{evRUc7BZ+OzdGE0ly684tV$Nfl!ROtQ*LsTlq+= zWd{69;qop)8DX*CoRB(+`?ZKGxT1Sd4yh0@SM`jKeJU@!uzcBue>bvPCNjJ4=hDg z!cGPiIQZsTz^h{2xI0zd2N>${DioU78yE}nX`tFR9vIRrZJ}ALX9<7yAr1pB?M}bq z>W$6$oYLc2J^m`l{PTHCqEXSmbsymL4~9t@(Rc3gJKE!4uMVXj-j zYViS_mn$FUTzy_urA&aCC~%Qk{0=`Lq4S zjxO&%?8T2uEL~k(&exk6G&q|jkABgVBK7CI_!eYoU~bZX_OidB;us12Jf?d5xzrKh zVji52cZjd-2F$lekK7l&6IXe6LU!gZKkVgM5|?D)Z-rR?Xg2-YH&6W!Y6wH_T+(Ib zrKU?vQ;@k2zwVfO`H_lWk`7Oqh=AMM@+{zKDFs;El~AJKK4ZFPZ22tGc}Uk+-$Rw7 zG)ooZ%zLEmgQ#YSfsG95Ib0Jvqw?bjQ}HDdj4cipp9#`8CSYKFIQv8CF}`oCzE}+Z zbw_~yDipR-0WS-<=w2sBVxfs!E0Qo0Khdg!S%{*eu~49)GU6B?n*jxV0d%;uD&;DO?>SMGCcCg!shteMPFd zruWyU1m==|Dxb}xAQGzc1_@%}q4COMMiI^S#!vzZInScMya@-k&Nvc&I1-tCXyC~A znLy4)oY+eGkt_TB*^+0(HsJA4l3= Ifl4`AIe)vSSwmPhJ7F=vM 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 Mxvl<={y1PWzu%rgK}`&Q0Kf*LGoTPvMHd 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

mc!W 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 literal 0 HcmV?d00001 diff --git a/design/screens/mail/Параметры электронной почты.png b/design/screens/mail/Параметры электронной почты.png new file mode 100644 index 0000000000000000000000000000000000000000..f39c065d742a350736149040a37c084474a324d9 GIT binary patch literal 107119 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 v46{=QC+CA@HKm@Jm5PMY=-LH28l2be&ms literal 0 HcmV?d00001 diff --git a/design/screens/mail/Пересланные сообщения.png b/design/screens/mail/Пересланные сообщения.png new file mode 100644 index 0000000000000000000000000000000000000000..97276dc2bd4bff999498d14471881d62c4b3173a GIT binary patch literal 51813 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

khmnG4~m^9B$EOPnaml@xWaqo|y%E$hu%0_? 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 U66Jf%SHRZ?sn3#S;=2C-1syJwKL7v# literal 0 HcmV?d00001 diff --git a/design/screens/mail/Почта _ Окно сообщения отправленное нескольким пользователям-1.png b/design/screens/mail/Почта _ Окно сообщения отправленное нескольким пользователям-1.png new file mode 100644 index 0000000000000000000000000000000000000000..bcabe32d5bf41dcfa863deff41888beea75cbe5f GIT binary patch literal 60188 zcmb5URa6{Z)GeAoa1ZVT4<6jzHCS-z;O=hW!`&eS4ep-cbb!X8akrq2J2c*>^WS?P z?ilCcoQED=wX1g3s$F~6oNLY%^I2U13!M!8&6_t^N{X^tZ{EDMee(v91{E3Jg6($y z0{=sERW$H;^9BR|-|y|4AGsv(#nXghQM2_b0$3xY2 z)OJGr-J1*|#JoHPB{psqYzw>%n|(&cOiW0davVw~!Q?05inji9V@e+`iEwNB#VO!n z(&tRPdbt_$yW2<4$EToP99rBB$>*`L29LYs`&olkHI0mnvM}G9m~=Yp>genOuYmv( z`JeBPh%n2nGe+MO$Ixj`hi40tM`|8`4s~p7Y--B(a^B(}eEyEr&lQP3Ffi~63tedM z!e~Kj29VH2e1;(RS>*_X@&ouWE$G8^6OIwDO2dROJU#zTa=}~P8%{lN>&G#mXkon} ziv+~$6iKg}Jz7cSi1c$|((zR#wU6Hquly&U>-5?LkHk7XJ^dc`WT9rmFvS8E9sqG+ z_A4fkwNw=>CpXUgfX4;6p>E+ZN&zc6spY~$a%VD1QLk=e1V;i$9_YwZ)GIswpKT`X z6m^k_M7&{R$Q7wflGEz%5g8mY`bh~`7n^>AzaGqnja*OaX4%kiP)GX%PhE^*x6z?`7AG0 zKlC@TraV>j<*!B4>Q0R-pc6Kt&f`p_oIK^qB;g*Nr3aVDF*^ z9zi|d-TZ&*`z8F5)H;ts9{bUsJbf<*h$rShNuv(Ejq48^9RAyJT!(LA3z(%=z<#_! z_r+K-RVEd3T<_4u7QK-C6iIYnXy$*&a4nbgMp}%65TCK%|AK7*VHN@7X=b^0Y`D(1&&@hoY_9_D z^pwx(Je4AI$LArir$(>O1|6Q2u+N)^e6W6r=di#-6|+=N(Mu41)1qm>$XuoN%dg6_ z6g1m`c1S+!YO6~YeDcYI1$Qt>F?G^ZFqXS}!@{XwFQQBfw?3NZ(4b`7@R7>&8PIj-Z^OK$4&!2 zRs%)O83>taDf<-q7Y^b^9cu2HWOKLb@|Un@{QAv!(M?kRpjA2@U_;qWW>GkQMN} zekHsM{F(WzAby2ck0177ie%#S^i)fjz}h+aBS31Z_no26-k8~|dr|~65c2Jm9@1Qp=IVMXnu-EtYt{LzHLX3(T`bu&RV`b9sEU^zKV6lgEB}t zWqh8b<2F&6#fW=`n^$jpEd49L9n3Vpte*!jR&!JjjDGt-B;p0l&@;VUBtppHcS;?S` zH!?xN)Tz|^q&MS`d4t6eHmU8i=z%nmZ8%9QBCSfbGV9o%cQ`31#DvD^?}z3RezLnY z)un*zsg$m(maRvu-7(dCy%FEuMm~a`E!NP(0K=b?+Bt7EhJvIkI`tRZ1e-n$Bggel zVMqf;2p9!MgrbN(sCqp~1ES^tn1T+YL18+uqJ2k^|C+#ZNih*zWzdA@XCH1Ub~ zbYl+d3;nwt$C=r>;XekO5L9QJUA_wK5WZPQG^U(0Iua2xJ+k8eJe1ukii?E_*bW)Q z>D~-}ddQ|lObF2|O=dqRP81$}`dO5=InP8%L{BMLvZsq{LU?~s{Iv#XArw#G7&h}0 zW73&ss-wB{&$qtMGlyRK*V#Q6@B1*Zt=$VT9(dch9vim3n)=M6o3*Bhc-P61(MVJU zA-NubWwWDKG$Spa3lF&uF|nPb+VeFC_I19Rcyxn{sXk7TTy`|D_wcm*&Bj`c%n%-B z!#=&#VtU$HFn=Wf!ZCKRO*S#)Dbn&Tk4ANaei!L`Z{Jg4={G4)yLCIweqt5R9`|(V z8(l)$EK~nVv>RNy+>l%sE^nRTIVTds!ZtCdV39bqZPjK0gV}$B`=NMibwr--4)R8l%RpOmulQG7RN9hqLQK8pc?I z*8Fpc4V&&`jo9;)49*NFec<4)#_tpfdBTztsfzDvR}nt*vfj32X~ z*<7^{j?w4@__qCA@dyL&R=6;WB|jeA{%e)zwwC&LDv7;dR-_pw{Di)r>Fai@tE&On z4VoWlR-P$e3qFq2Ve}`8XoTo#t@B`tEN{9&%FvnC+biodh@({dChs<~2icdQZ960R zq~Vjyk3Qlfyh$?|^~UFfulZFRve(RM4ctN!_}qSj%e!&&u)Yddut3I))<=7L`=g_i zlXS;uR?BRiOjRo5wN1Az+4Gzu{SHqM;rF(u!MwDZWcoOdswa6^VyY_J&P*QL%Lt2f z(`brasS=@e74UY&k>&GR&`gX?#|=HJ!t`|!U@)Vzt!*eHNp-lznITTE>0%}?ODVT0 zp?DrP2Tgc2F*ar^J)sz5GC_E}rrGI>ea%x5%zoY|2(Z$Me$-xmRN=5w^byTzNaI5| zB#ZOhl7oRG1Jfr0!{-Y`hwp-y_x0+azaN1C#}d#6z3zWwi~DZH+KuGjkTXufIS^7T zS__;eFB8k*2#Eg|xD6fJaCOIS}2nAcR#KyG254)fb4&dea*pftkn)#T4Py|ft zsqZ*q$(9HSUb&V}qGE4d_s)U$!bCz>E_}k+9^WrJY@kfT>L*d&Jyq)q>~YU=@P&UI z@?Z@aFSmeG(tup#-_?5$n*B_&K z#~=xxvo%wQ=<`K?lh^SV&a2T_Le^b43SKXULp*Y?cl!D}Aims1fPsND*awdM=R5d} z8xcA0+5u7rUi7|pHMAzPVNVC7@%z(;3wa&s2wji!SOie!D*V_%y=GOFVf3SnxbAy8 z_Or?J%AA{@f3SE|ErRZoKvliW`k6hiXs4EA58*h-9`d|Hy>~OKp}{hh>{3nP+;PbG zumSCXz{<8aycSJf&oMaKB}BYU!r5B@i$&BiQ1iinLXjN0 z-x0^rQIV7r-O&H^F+5|ulpxmf`{IY`uAYbeoU}-v+j+gQ(k#=JP|QjdGUGo4F4P_Vx6a|a9l$9;(zuPJ{9WbY6u_F3+;cm(8|woag(3I#e8>i)_Hyh zqYIC2L0`fWSi=oq2hwGthQ=ZygbU(hXHbtNUi947x;${<4fB8ni-*ubRXc)<)ybb+ zNuvzAKqx9-kaC`09tvQ7No|+p0K43|ZW%;;etJpc=;Hq}FmvMy@yrO-w__zefR+iU z+m)A0m`*f(U5sq+G6f_3`rD`9uKxROGO6c^*nlYthzJjuc@sh8y?UXH;(_;IueE{( z+*2dxb~)?G{L@K+_z!Qz4~)g(;7?lcbib42)2_UF3&Pjf^_=u92zglyIsL%}kX{t% zxlAw}N)p^g4S9wW_XCd!AxQ2{$kRnXPC(w+roe`8G3;s0V=@8jJQRiMz$^EHFZaUZ z>9lodkaad`&<#%bKTgj2+EMUI+)MbMX={k>g@{}Y(>?8uX@op#!^oj(#7SJhzH^^7 zH-&<(Wt)PaXO}e*j`Q1ozw%sn<$|XU`5wKl**%nkf84PE2B%VuW_~WzPndToPL#YD z!Y#QPaH1DqKbDn)7)OAiU)#@YpRzrP#m-;zrG~fWuj?Pper;AE`pss!gB1^n(@_Uw zsap42G>Z?BnU2D9gt)gxh?!*_JaY*MWWgj!xNDd{7Bw9*0?cpmZDt4z_jkJ^M_ksJ zz$*iWi#Id)v4b)%8=#yvbIoe2e69=v@b7agqG{sQ4ii6)#9H@l99b+7HaQSbYq7V`U8S!nVo|rr~54wvk>Dkc_ z-RJhe`(hIx<^WCPpP&u${{aIB6WZBQ;iy93+3MEm0@E!karK zpz5zZ5sexl%Hg8J#)m@~xbIIbX?sa2@pw?&4QA*LmwF^!!wfpT;g9C&d766Mf4-iS zFvGN9{`9xre{pef>}M1e3p~TP&h-4fdwlD{#@=y>iku-BZlTxywo#B3qgN95o?2?k zq5p!U2K{Hi#L0igHT->6h6cPG-`+4Z|J5bnLBf-fwEI?cSt>Q-K`?`?>4r7k724LN znWb69C0PqOAdu=S|G7)G;>t3OEcXdxg(P;@QOahUPW!`~ZqpYx{)s%0?{-efV_iml461CFr)5#w!%_FN z+o%K(H*qY~%lU`t5o^hCyMA{@jRvj}{BTW(>~*W*f`0W6e(Ty2+Hvx}55a&9*Pyu| zyvIT>XQ7HEg`Zoy+2PGRBshPC*YuC-AtG*nUA85c?!HuhA|N54=DpD?xfYsFRF0X_ z@*^#o5t`C*W)Y!HJu)oIaI5w1?7z^N;uYP;DM#m|1Vs&g6Ri6DfeR$XZiqbW`A9+? ztfxt<{&=M<>?! zRBg^qv?%&;*2U#ePE(sbN$#t41jx@yJtDJWN2Xx-t4Ag9y}9#Yd9zIMfPM*tT>4L^6S;Q58fGXvXEoR zQ%}FO>nBnF9#>55 z>FxapQzP(}*jn=o;)wiY%!MJ0f%{f`U|^w+knHuBKGeA8k~b2+jF+^C^Y3>-Vvfi7 z@gMw=7-jsV=3(DtFq~vh+eu|8@eg<_jQTsqWiVt73-SP%y5lH$$Sl4}N=lA$F2{~3 zzZ0$Pj_otSb=V;_B^BdA%B58;Ut;6f0(_W`(tZ!llT=|oX6nhrScd&)Vv;vA*QjPF zOr~vWrm01z%izU`+lfbL8-P6cnXdj=3P+)0&277@+ezEdEiyAP?`$n$VPYepq8hFR z(e^7BF4N!a=eXQ;3N(w{!ZExANMAjt52iG6O8uBS##b4AW}O$GWFZk~7eupF+` zVPztuZ&CN1a|Ip=In&|u!}Z?3|cj&s$Sc}~(z0o!@ zvPkDjnjv_MY~u7qZgH;|!aXp9$d+KWQXcDU5xRsApdyn>e4Troy?k>TWQuDaE4`3q2&$-^I(n0w*`-L<-0Q~oEc-Bz_qykY@7U# zUS3{Tr!FC@)MgFlp=_pIZ3+$dG@k72?60utVg)F=#yUA*&)ISFh;93B=}DsDAgU=C z66HPxO0x*zWMN5ZqDR2OXHvhp)CUH410mhe4OUjYx^#nP>xa#dhcUCqHudjZy)JDk zfkG1g`O=Th?R%N|4N6ZA_1*i|va_*-U4VXMYQ`Z{z5ZR;=Wl39zIZ6xioxz!5Kvw{ zRM(cPU491};BOXms|yR@rTpX8w+$N|RW8Wna>QbK#FW`y(~Z;|#w4e{$@AIxI9sj( zm8NjtiXa|^3l80a7Z11fA*buq`U}r$5eg;wA+Haniwrr2S>wN^r@GXSSeZsjGy|ae zGny;HIrOAQ*uL-_rmK3(X!9`>C~&B?h=>qFm_ULk7I_U8nT*2+Ubc34-WTvr>wg$7 zq2y@$i*TO#m#h!He>VgxEg($*@O_u`4A=jofBdx&_+hu$;pC|#CIAonavCTk(3OAV zF0nlbZF~OU*nL(M$8mHk@=yjG0IXJ!%47hxwk6F|y($}zbZXv&4kG=hFU9R6b^ql@ z>bU>wPLs%P!$|pq0r@i}WPi%e_fYaV_^!F&0XPX4P|m5#wtgx!1U=p5`_g&-<7r9r z{?C^~Pc3ekjkMkNx7&A8AYA)8h5Mbp-A8z;RLi7#rPKe8O~)&$;_rrQKh~=Vz?B0^ z6G9lC@npMGX}A47^7^1S=`r%%{&@E6bqzsZ*X!f)(_R%qP$GZ9I*C0d2F8!kJXKqv zx(tcsUv5AfdpEw;^W<9*@#M&|Uro+K@0X8i4m0oaX3TK4<aHnqr}M1q%4XM<52^?!`vRg zL65B9%09k$X&Zf1-b^Z@uR7zn+~Jb7zf_feYkY0Irc>~9*}2~MrD?{u98$JOP0Lx^ z(K_kJFkqFc;i^<35*ZMFlSXyh&V=|j9{=1Cnf^mvV_YO2q@GIAQAx|9f}8D~p$US-55T99>EjB`o-8tkxc5d_}B>JR*R*ek4i zfm1D49c=$PrG(%yD@!p8x%2tQWA#BRJO0~QAfxz+4yJ+*JlXmpy zM%E~HKO~U(NqslIE~b8Awxh7c9d-dL)QlY4S`2>*H<~Qg>@CQ}_Ls$c9z+uYY!B@V zY%6tXW4-@zzD!cJRK4-(z&!)bP=gKiY?XNCIS39_E0{?c=1aY}aVttmz1X>MNp9EO zIjCi%>XpUB+CZ$CD8PK1G-vLL1PI%M+cd(Woyx513|)oF+=Nkk%=Cwj#ahfCLIJzd?~ zrXu_}1}6;%B@3aQ6)wP%Sn~PA#KbESp|S2AMf}fqd-DtZstDOKStJ4|JqH);Ek#9N zAx$Lg8S3BgjuOGY^Rx8zzY>^vZO@;%fAXg0tqXK@`7THU*?sZZ_u-EeWSk(TMX|BQSn=1!vcDqM2TCj zv9=HdTo*pY7~0y4MQ!J*7J6NlTE-2Pi{u~Pc5nKtZtBxxa6TI8+@}sO_^TPqq;QyK zm++lgko05WA5eVO{4C*_D_GhoZZ8Ennp7v2FZ(ZdT5veF7{tvE%T86x)m|5% zb{nC0{sLntKNi}TP|tPxN3rDJYW=8ufGZ9FOb&jW|5159h5i$OKL76op#RH54CkHx z&5rpTX2K+6C~yzyMBTHueS7=s2z1*+&cshk^FOqKWw_T=5~_GTLhOfU``^LA0WN%y zQ?S2yDk;V6hIJ`+w{yc^$NSycwB%--4vCcI9;a$HvmRBV9v-uWS`$|Is?;(y_?X71 zo{EOgIQoi0LI2AOzM@6p;L+r?%KuMc(9ZXP03OQw{q5OQG_Xn_$VyiV2*_#S7ibR-6)EqQ zIg(FEE!w6Pde}`GEj5FcopheR`)!8vG1mGXdWok)tS0XXvXoS1 z8$LbXX=i)q%u^BXRI*CXFP{CG$d%OEoSdRh@oe8=k{zG5Lg4fkICeL6G0%wYol&l|aUZf3xKqXVz$e|j4hitjY zElt!F3LBP%JTCPFMV$yZm}PTY;f!R!;ZcNm>`K3}9S#&$d!reReF=)}a0RJT5nKHJ z?-GXuQ0!((MjSKz3@#O%TO@q_sSwklJrfZorxK_Y@pH>n;#GsFK$XULMm5m7E1K{I zAqi0`FDRyuz+{uvm}RYpQ0fqz-=+6si?AKG|MP}a^F<99)qbS&uWi1Z`82^^pPnWa zi)h{nlh${?HU+jhR^o4QJe<}Ce;{8AJ7=j)KZ;cb&|N;RXll*OAJy0}%}_dVHwLGx zlId|)e@P!cI8y%TZpX@5pT0-UmSU6ds}B~0AoxMneM%ZDHSd-KGItR&Ug50u7GVO$ zf}kVc0gd)%rih+~>ux6l21vN9Ip{%f7JXx!L;|ovAT&YR`{$bNsrLrGk0smk=!sMl z1&f@EhSWxe{r&&E%D#dyUt_O%T~iP*=9xwt2+h_p_`aX|(KUu{Yih6K>8$gKVPQi)D(N0(IB^JovtyZ?A3ucZ_*DST-S9qO4SR=^@K!7*KA#{-QKtM+_L{;r0X6UWS&>fZRj_2Nusnaz?a`A zt((EGPdt;NbpJHEpqGk@iUThW+SfmbIKyy3CND)Y&4KS^u)x`+Oe zl|4(q)X$Wt=cU8bGeb$&uJM|uRmH^X*PI^F$nQvbQZoVNeG2zNil#~4LpFDyfMY6- zo{KADWJZ&nQJNrUqUg(#jQfG+&`5muT?U_n-czRCg7}j%hq3zzgK1%9E-LfqpOxX! zcFa>cpA#d9D8IU|*p)wAGlK#ZKzOCpF9!-@kPoQ(PMRSCeS__;%T`&p`eok)Jtl{! z0&18jwg*ufbw5CIkL!Uw5aBZ!3RDbMO%p;EbyT+P=!Q-2RVStE$m^m^c0f5kbDdOt z+D|N;hXItij6N5S{qe&LPO`Gt@;h%{iYqm8x(T|TZ3>0|!A~&=KQHe+GAGN*;Gbll(BNmB z>s-P5^qD5^<#vzG=ga9$5i^ghYoWN7mftG6y4iE>HX;_D*?~7L+E&j?m)zFRzLhMj z-oV!3lggc4s0NTlqo@7z;QZp~=&i__qGe3i&5Z@O*NUo*Zq`Vd8u^Q8f4B7+`%A=s ziV+GmI&7X7T;LAS5&9N|_<7fLA}sOShxngzSS+vTND_qh>QGS@?3zMV`WV%t zJ&bdI#pSEpHY64o$t|tvvAPn3W8=+=CWH;5r%Vn;srkov_+r`Z3QaF1GyS0E{qJX+ z2h~G;H+9XHtuUTzANCOCTrFNCUoPMTf?;+qU2n01A(brS41DoEe}s$ucB5Q)L2Rxy zPNQHI&hFiH+UTGI;SYhx`HQti5a8tZPcrJFm$H@h^>D`(p1<9pXYD+SaFB`{U&Dpt zrzcz+wt(*7inPUFf~LNgq>I}eH;BRDqz@RI{%ZVf@tmye8JWMmKf3u;vz(@8-x9j_ zW>aU-VT(vxpZX-L{@^x&zb=`<#2os7$?qQvUhmzmQe^Hjz7mgr|ABsJd!GJK4`dek zP3J84+B_X|b2MK~PmF5~!o*PN>>siAUh|w)bB9Z5qi<0t{<4eJK&B)r&yqar5M@6Q z9>EeZP(ruF(UDTyj!^(0bS+mu8c8yn*GUk%&X~yKhi+mMPt6m)Xc{c(+=vOUUCJ}; zntDg;P!JmHL1P0Xg>8~Im-#0DUTnqu;O{4(2j!&(bS;ux)Mb=-yZkS5Z&JKu8Nzfa zK(55^EV>Mx=WD$Fu^+1VS7npuZDQa73_C!iO##<9xY+qUQ#kegQ*G#>FoFzvEqFaFc!n)gjS2YSAJiI=ugL@r8Yv!lsHnts-9684Y_3gDAJ!arL-d@p zMvJ}(Jq#~5L2k0Oc)XkDRF|}?)?gXMOiH>hvZT5ari|)8*vct9D&_>Adb(@pN8HLC zm%9egUaMmiuZ2rJqG}9U7akf~RXEIJ#Nb61Vm%PS274g1``mAFp!2-v7=tr{*_p*q z_$F6yT1jE;FGEoUHM$UCSU^R6mb}c)IPB#YdZlHwgdZUxYk0iH$W@ZyjtC@VO?mkb zpWAlD&`eBF)3t9IFUd3&cJi0-aBe9?1@SVnaSC-B$A5-BRH`8O@lXsQ0ksNt-PdVJcvDo8#1`$utMd2auQ@^W0BK3+?gx)`up0Z^*8S|M=6YE z#`CB9+qW_;ws~m=lhLX9<)63um6PTP1)32;Q6r2XBuw~3XT5yWuBeD{f&|{^ypUs* zP>@7Yr<_gBu7|R5?&qpiq%lF#qyC}uiT34a-a`g4&F_^zfvnm2 zCV*Z1F@ zp??_8drlW2woa$X;5yn$>Acm|-M`&7iY89A_*YsVKXPUjrMfe)T-Qxb!L1!FJ3Y8Ovu>&lu z@R^+6M3;k~r=&!GDQg=POe6o-66rBCpOruALY>8L?UGD%#haG(O^_NR^O@#!4aFx7 zn?l~EACwo>774L)`KarHFqSQEMUTo;5fRU&P&)_R2$+mxsSCrE#r-g#h21;x%_;{Q zyn~+y9)eCq#S_-u#$U%c+~j|7OOWR`A5d5q%>K6w@eUqbfGjaktB$UK;!3xuz`udh zZTu_39VJyosw+mTmYyaVPL2t9SPrar|ibb*9}8R*;0`A(ffRGmDSxFM0@!Bk`N~LPZIN|V7V&c2v+N_% z8yhYU=CA=}0WtO5w-}%78MynyEVeLlkfh{fAH?jpwmT#P+i|Fk@!A+~L_vhC*%s(T zjp+Q4b-2VRhM-nlgBbCHh>ReCb2IAd8vtCr?6lTq>in1lW6GH4(~4XzB2n>aeBQq+ zQ1VcTI&nNreLT{FY%r%9fSo=;F8WI*DqXyEBgVz9%(KOv%5>TsTH#cL*wjykh|`Fn zSYCH5{85we-GPVi&+VD-ULo&cUq?r+sFkbnxAuQ?R5G((E$|@( z4R6d^#yMQ_JGx{Z?i}S7_&3JaRVH5&28?8?k(X4JsQl(@9gW2@D)9!=E?aDq*e&&_ z#VVV$fpwew6gsL^ZThY*LfI}NZG;YD_*G%7H3>mJ|rZtH|@S4aRX)uKDt3~tL58a9=9T-gNjH#(g#|@@7972C2b#Q{&fBP zKEAT=+qB6|`mGpGiAcU`aXtz`2;*j<)~KV^|KpwZ(L$Z!nc4K9o7Q11gx2nmC6n$h zhruIBNR=!{q@-iTK-z+_!(*kSrd!D{=SNVSz?c}wZnj)WW#>y}W%g-!yYz-xlMYz$ zh-SI5R`ZKf_PKn@s^$7oMlhi$GC?=msq@0p67%42#9Q6w9|>FX@R4y^T>$Y4DvbxP zHd!?*DrI{(5d;V*SU8l&Q|dDA*gKT=R2i0?fBG`2kZ?P@|635|RgS+>^!tk&6)r@f zD*b8%tTw&DVluH>Vg08CTlWBGVx({A?6UNSLwVUk0%C*dn1L zHmdG$Rf1q2a^B~<*W6Q4=kwv+N_$l=h;$=+D`qj*2#9iq`f=w6sr~MAk@EILFNehE#pUG> z_;9_T>=a8&SCbZhFd+@iVraDGW5DoT8RPQdGl0SxC(k@{(a1vpTz=@@<(TdYaj1{1-PUyaJjI)HRRr%gG%qYvK5xpfD; zyrMHNm)(})M!()97~8Y_np00j*D5=nQbfM0YP58@opwK@L56W&S1`pny)my=Yh#1$ zGyzO(qRp<7#g=Imx9OGXk!?oYG4W6$V)&zUB<4PGkn*aGoGtL;VX;ehW35e_MTJo@ zr+LNAh29#K=;7^XDy=rWY$uW!KI0CiEiAA1v0hz}(T(yljE!{nj0sBN(|-eeM`QqO z*CeXlps&q41e399mghcpSR zWR~OKKQ(zhkuCR1%d1P~VUNxH$|+e#vyUSetZ^O6?CMtZ4sMe>8e{Q$tEtR7T2kDh z!$>WxHkeqSmCso2MdVdl3)kO4Z~fmcA~JrUAoC zF&37O`2k}!1}Gzz#NhlV)s#>8gT5i&apdp1&MS$#IXh}E6~Ts5`_ z_mpT<;J8qhCsMl9&RItF$;9&9-EOl#<~}9O>Si2Ge4G(t5xn_Ob{_nUR9Rh_&TT`f zClccAr&QTlH)u4@n#FN;8N@RI-=2j}tp2E6q>iR0Wq1*1B=LchQLExkBBiNhTx>@! zb%*v!p00_W$%kSV<(F+G4d7!3n{msqLEnUyu9!08IiE@yrF+{PJcCh=Rk0enJH6V9 zQrQjL8!H*ddYu<^Xa~KRZOL}zzF?Nh^4FO$t=hg@S$zp|STncq^J}+M@igdH{hJ`S z5kI4+kAl#*KR^Gz@GK%*2ST?+1qiMo?O5=bs%ojgQ&SVJ@41J zGm9J;VF<Ik{5&m06!4``h|kIdeEr_JGaNf99GVmub8&6xHoesPG-gD+GG>lU5Gc=w(? z1}(@M879$}Po-cb@yrijJnWVQA+sA>Hu33;8DnjY7NrsmzAF6q>v(G5q_fS;j~%sQ zooeAK%#k#?U6iHOepm#{WkEht7HNk@w&_WhaZhmPo8CpFDsUH+q~u{ytdm5_#Nce+ zP*bvGFt*oZRZY%isoQzQZRaI!XL?%a#St@-#z?=fDuP#6#gVo${Y#6l>dRn!LHhTd zwO%3v%2(}^ukB7x{4R~&!lBO2R+Nd{z_~*y6bj}Sxz^>-DR#-7|2}V9fA*}DefRBJ z8j84i`z+Y{j@7I2nHDNZ;wP6e05;$e5T*XKT?|EKzqz3L0O;zU@1HRtE)!F=X!6A6 z+%D#z5+5<<${lm@=U6;!Jb2M+H?SSo9}`X!+Z;Aq#{zLhVlZr4G4m-BDw+ygI)5-K40icYhy6p@-9TM-rIm3^RPr=sm zmH6u&(-tMQ-Etd0V2Nxd-5XdWzkM~KE;!!pp~IQ-HrZLD2WZ;6EgFIHWokJbFGz9s z@G>`OwRx@KuPOyuH?sy-Okllfw;{Ih0S%{Npm)bxb#N~_m4I_DFcSWl(A$57Nd}Xd zd!OIB$uBiV3!wn4UDG1&8qM2@izZwgYa`4rMKDtE#V`MuNQnwX!P-%(!#?Z+y4+%1 z&BFDdmI3g3rEc6SiN(ea;;nEy6xn2?8@$;Ba)C#r7qpOn@*WWO43Y40F5^BYTHf;K z#31IlaX6>)n$rwg=z4)$*vI{V&W|$zyD18fr?G-W91KeOAPMJgfFj#Rqq$~?Q4?Q~ zlEk5vcG&u_vw8riSK7TjnV2~0>LKn`nvC3M_*z4Z!3&(Hx!clN(Ke=$A)~JnE8IQV zR#~dc*g2}V%@XKml|cR6uR7>%&7QPh#wgLIZ)!+ul-7pot;(z|HbCC{nW{ie}l zFPbhfHSj;?$ftYF!^-Dx$(3GJokD*(<-heI4ddazyCvVek8IV#^D-gNy1>Pi{r<8k z7(db+Jz&?B(0m6|)gm(hg-dv6B#>>zZT z1{oW4Vh3*;pV*jRxQ~Jvq3iA9@{0?M3$7e2nJb!JS_T6r@hlQ5#U(YyD=WqVD+b%Y zimP7!7MbDIx0`&a*<^E?Sj{_@-Mwj+V9E-PhG-Hj9l{ z=gLa;s?dPT1J?Yx53>wQIHH}(OC$s_dp5h~pT+00v4bw*4)fg?7XmW8nx&~l710=@ z12VK(<>KDWk*i2GnQNZa_rdy%jA*)Ij22ODjxz^6oX`0)3jqg~1~h0klx-awHT6`uEC*M1r$oAnyww_=Bcm+= zOOS}E%>EYS+FPw{`FA9_&fG-b8d)ay$-Yjsh0%QG~ znN3zaU?D<#LkqIa%+Bs1e)Qf&H%rjWI>#d_UGIxhH+~d0)0%~Ya>>t1?Yn|c2I4On zW4qOGbA$kWye}Ht{m^`SgsI?UK&{rIrrQH7RIcDCqr#Pql{J+0LPTG?}$nM?ijy5K;a)tr)@Y0)+G56vT!KdfRF&yW1h1Z)nv%4P1 z;Gp$#msK1bX**&K*a_8hs}<%u-}c!9%Ka?TLH2cJE? zq;Ad6+nD;!Z9?~N{_Fok{B@LuisL=uXOm3b$=PMBO35xRIlvI=n?t60lF|(IT8PmhS;r+L<0&cD?*$( zhe-!-De6oFQ&P6{px1K(S7{DYLMfPI0$vIk#oHdLTi0KegwF?N0RK<*t3_DpgmrFq zM<6alC&yz3m1e3$hP)vuaF;H4KiY6GJ9R|dE3&b3BubLlt5jpP z!nZ7T<(Fr;hWHELJ!ICLL?+?jX7)9?Su)IQqAozZWtv!)48tgB^qZBMz&f1CpL-M3ij% z7io(PovL#G3anGRfJgtF&0UoLUlsfRrHT3f*1rFr_DWxaA|+XjF+!J@p7eEp4X4|E zg@<4%AB^Nbp`2n=hi~T`4+|O>Oqqm5;2%}~J6OUP67c>jA8eO84>gG}`^gOoyWao` z2u%lHa4>DC(QZBmq&&L)JCmL%1R)4IDVN#9#~Wv8E6v!_P?teFnNso)d)tdO(t6UNL7_AWe~(muRc*R=ryX24R~EP zwuu2E3B20b_B|C!SuD`dN&TE#5G1-4AbxcZ@-e2MhUxUB%Ky1r;S?7I1)rj)(Cst! zc)U7rJYNHIaZjX?06h@m7*8r+U)mn|SE=vk4}RO{-B2H^BS(CQV_~qSd}YqzJOAdf zV?I{UlGv_7A$17N;sgG(SszH#bJLIN|iz0Yd^vzX6rJbHJ_Xu%a=z+^xRGaNmpjkJqcraPi z!AtSwj>sWqKh0X%@V%U_+U9c!TketUL-bB5&h(S*N~@!K+h%G8Wr7L|A`M5d#nAa^ zJy%jc6}4ZZpT)D+bQjjFRL@07dSmF*=X1))v=ak-oEk_2l#E^b!|uq+nQ&^=iQUSG zMZRte1p_PbayZ_?PupO7Q^qma2h|ZMMJmS6TZ+8W(0L36@M%zP)a}|1nuOQQkC~<( z2qHxM{utyk+3B#@QMYow4y9Fk?%wRBC0}4LX8z?BQ@4g+x3%N|13_`oH$qsL7M zx7Bvu`D|<_>M_iy8^1y%ykG9_Ut$^bVU>%pCN;t8y7>V5E#46)FPPe|SbW%#;LUcSrc85}-^r3@2a z<+Rzge=t+3H&rmbplD0vDu!Z>y_*bk$oHKRn{=WjUt~N&co_2wmwLUT7&c>Hjb;gn z^7`hm@GcTzQIn&eyHwQIhISG)>WMZNV1hbEwH6RHyvoURWOF0F#e+5`#}5eiir##^ zkfe3q#d-*3jr5NftiR_kzreFSO}sQ=#YGB3_zzbVJSCxAN)rS? zVoYjK*5#UqR@o&=OV!t@d%|LfAr}&MJH=BI@%wQa=R^2}1fP6wAHtKgI+sB%?jSMu zUAIm)C6>hpGbK=pXR?_n&-Mo0)jE-FJug24TcIks9~+04i)y7hNXYTT&hnQ?o->#5 zJIy`66r1o2yJE%Hse|x3683<@QD0v(noTB~`<_32XIFClg(iXTL_GPlsQid{En^=q zMsh-)oHt$lSqWE zzgjLP?xlcjhu+`bBwvoOyg`zE>0Bw=Hd=82-mtUbFdl`($951W(G!*nY2h|FryA&x zA#WWrDQhDWwlJBlA0|A$YrF_}#b#0Wyoh|8w^*Q}BN`45zZ!k!kJ$F}RLPcw4HL*p zrS(sxBz|j^B3bdnKszet)Kd z`G)=D7i1h7((ovf@IF~7(Tj_oh}fq{h#MzZju}_y^igxF5!)`D_j&4y4il@uqfd~| zS)WJ2YI;DpYV~N(lz>+p)s$J$U$m}~b`!V!qAfDw`?1$}jVd3vhT(8j1)JTtjYc?*wl^4EVs~7 zntvNzyX^M#!5445?-a%U#R}a|(NueA*lb%RU;I__-1l?vTt|8Q7rpXC^2z86GFqYo zk0gdGv&$VqrrkSrnJTV6|77P(?1ZWB=8~U06R-hSJaLFyB}h9zkIacbyXNEs6g)XX z!;&6h1XRc#QH{Y3+kt}GJ_d4?G^%8=4#3Va6jG)m{j=~%zZF7QU~7XLwV@dsCkrOh z6+UqZ4t1#HO+(jrc1eaIV#VA>OkBrPb$1D5(Ocvb zW2n<^uHw^m5-5{#G>56T6<$9d@+Iha&y)u**-{J}1#X~9OlEQa$2p7BRkxI(k^P5H zb)G(HIAjx*YSYNo`AnS&$g^rOQZ(K-SWwqZLze0I2Z27suEdj3y3FJ6ZO`t}KI2KFn42F55|Be(k0)V>+lng5-V>e{OAWG>_CH}n{ z?mUNL;ZCl!(2RHnye}m>&~wi0eHF(4#oAj3#SwPvz6tIUf;)uZ?(PJFyF&;NAm{`L z4hin=?(RBx7#xBJ2m~M8eQ<8`oqccBzO}2)JyrKFs*q;7r{A9SKI?gY3n+gFA*k-TP7aKa%jT2KOai%>{MtFO!}l%}X{Lf9@r+ z4vv?=mOiJS{DG(pYoQ+AWz<2$UR=53ip+cMO2VH=jNKmefY!LNgYW@K_%tYO_9cnH z2~Ycy{gWI28_fiK{eNWu|0|LC-{OJsgg<@Hhv|z1>$l~kr2{%nA?Tlpg0L*z_NI$o zd{Uz?=J8;4hE3Vr9MAnSy`R1SGN7LWjW{y&`L5`cpzgNv>*~#{*2KW)NIkSgc z2+WA<#Wbg{1C3*P7MpAzpYM!o(gdB0|IE+BGV$zjZj}9E+T~7q-F!pfu>^8=JRy~p zm4|}jk=*NrAEn zWgJKxoHTq9YSQag9Z{?f#dUkuvY}=XD?4YsBh8P*J!`7*84Dqf3K`Jv-SHfcNY+;_ zNM`T+U_{dElyAw*67V2*LsDaL`-Zh;3S7h#F(op+LnO+s{}j|6G$GR)4mnA$S+C39BiF`epgqLZLH&gX5IswaRcU;~>bSmfwh*m8h*5dPBTjI8`iK z@fJ2c{c?XFl=|%$oI6B@coJxux4( zM-jpi_&vRP3kB6yDiPlqA)Md)ypjAEYgqfJK%Zpp89EhDwd%yEF zd!!Lv60SVSRQ0v>p%*h)y^Rv;xf0PGVTRGK6ec|Utuqhlj^=0;KMNI%n>~`o+8vNK;Gm9eTF4l#`1&*h37VHRPM{>Mi9CAu`c>&kfS%Z7q9O1xiqef+TZ@x4q@tdU>GHnKDuPOIdK6NPs zx)>^Z;H5(X2A=L|UJ+&1b_H`xF#D>VvC} zW@~M8>Qp-k;jwn4BB4Z6`I|&5Lbs@mj!MdsOZBEp=RIp5308Mp*CZO^nDjU*^vwV* zn%SO*o`53l`gklPWl3^Ss22jpIcS%X0!-7(?4 z@_qt;W(7nlHIeW!s~a~Fd<^1>PePBz!#@65%K(}%WxWkTC%nFm+WBw;y3NP2vd3}% zPK3BPMt_nIN9j5dt7`^dFp<9VW=y<_8#EEvjeBY#r^3^fSrUb~8swRlJgW;NsV0UpAn268m z9S7qN3o=OQ&LE~pvFEErat!LoQa{cIRvA_vu1s*?Mm!TH^;?dnc*$P0nOK_^dXjGI zMeSGlHaev@Jdq@XOu|W=(UUtL+?hB)J3%^j^&QH=V%W;09xBktQX}{EAkmGi{Y8eU z;19jgc!01nSyS4V)UJhtG$2=Bk7*`0jS>_)(U%iWiEmx~;Wy5N7I!|*TavG8>oYF0 zJ{=%SKJD~^!GZ~@WtadCuRRrxi#<+(*fALVh2+EqhV6wwVwL^+O4?_fx{pr3hT)%3 zEM@=~cDjxRvZ#EifpR+PyVzumxMKVnTO2;tO$(AV!luJ~n1ZXa%Rc325<-(D>G@;L zR3s+dOUZB8eR8N(oa3sqze@2d)?*2nC_sOt3YYmY`7du7-wKhZ7H|yo(}e>)a=x}_ zYNJunMnb8FTCRA^M7Rm=%=KRG7!zst%n#D>EG$i0QU~GS()$o^o>^; zru!GP&tNRcnfnXUv;2D7wjuHJ1Y0owd@Ryy0# z=LA|EHaf^~3CF`ih2dIpCcZcC-oKThvpG5c@xlFl`g`9UZ+s#WrA|`;wGxj&uyYOg zTU?m7tbovVJj?SpVvA`JT8B!e$O@T3^nBQQ2j#;Wa%VQ4&18KMMCQqcC@_Yq{Kr9q zJTh$B3V-}*^6agQ<^|`!JBpMphOY?0a@eJH672NHU73R?>yHpn-p@~y^8w?<5jhjK zI11!S(4Nyh$AK?za=`bRu?6r1LZ^8FTo2W7IJ(14_ardG`h&X!zp^2|4xY{b6ww}=!Z{bR#e0gbCVnHve#9(Mp|nCcf|D@C!QAnH;HP&?tMl)et#46; z7X-ayoJ*|TI4@~S!VTM8EWMQd{_BW3TpIn%t6S6#Dj@1`Zj1CTt(~iqrK^;l=}??~ zN>Sa)9k9O2ZI@{=Mw`S5TO)dt@ChYMt(Tbak@%G3J2w2D8_##_n~vTEmY^T@9+od~ zhreIH|9`9Y{tE{2-wMHx<29aE?WRN)?bv4Zq63$+d#CvO7G5ou?K#FSs%@uBKn=1> zQrGt60IriD(z(2|HUXqV2Eh}BRJ(2t1bWkZoP7%Oz#bo$7|uWy*o3ClY}C&8bf#k|f7zlx%raZGu|qdIBBR zJX55)K*>5QG!HPsl)g3RCL9qa+hKRxT~k{uuQ>sCei_o+W z0iXisWBjGcbBKEDz>a57*M?1MPh#ib*#{TP{{x>bu@1;mva>(JrlPck3QP^}G zmj)U@u@uXd-1-!gR8yKLy;PlL%|bwM<;QDhkVOOVUsLTUAxhUov_=ozQ$Cl87WWI( zD}fW)uAbt{>j)6hy}#`ojmZm~r1KxzdPFw{JeEv-4u-v_fxCn{p#Iad#0h6HH{D-H z4*bVu=P@8M-3FyOaKlIKuVG@r@iReZ=l63**S@1EuJPm_3jv|1k{gRU{JDdZ}rV$uo|F*H(?#4!r0Hbmg?Y&|$5)w`0z-jBBs%{Snb0Rs)9}jo{aL%OL3h zoTUcp$$}PzVpiC2di6AA+q(s>YM$8)Xa zC1#4s{7}7<;n#>jpK&r{?A6<;`d*$U+0LTkEG2&z6jLHQ8ub=7n1CkmdonJ<)%(U$H<`{$OGjFY`d z+e>LM8ms^&f!J}}cCfi75r|*krI$dcQbb6D6y%!B>0zT6+!Cws+RY{6XD$L}d)o0=W ze{SZQKsh%`X=oTZDx#pUP^LZz4b+dXJ49@ix!!H+)Pwl#Zm(ptAVzG_IXe6ZfUK-_ zn@2qyT8SUrW}RrIR@8JEbUi-YhZ@KOj%Gc|OXXVz<_{ z&KsKc6r*PCt$>%LSH*nn24uGHpiWP>JNM7GS#s|>u-0W`fx28N2WfiXtd?`_FYmn3 z%#MkAMO25*LGQ#bFlsYSb4`Q|Ajg!*yJ1suerLShRe;=X*Yy~oF2wdAnehGfXG_%1Q)LK5U zPS3|rI3ZKr;#2reZX>BDk4+=F*z1H72lfg&lVxcH$rHMrE0JcLg1?^>u%QM82a3Eu zL6IiKglK>w&}eNWH;19MQ`4u7xM3^wA~9fN&%L6~aa3alGqK&(z5s!<$bvKN4Wt(Q z>LTiQ9oA31K+A9Qq-u*DAK*%*)fyrQMc01*B&q(hw9f#yb{7Ygg)kQ~p21(UL&AjF zZMIx$8qYEN2GSOOuoA4+YW4W=naM{$|dsk*;I6BjcLVJQikWucnv=Er^dLZ6s z(ohQm5R+mW&ptO6l++|c>66W?P+?5d#wnVp3Z1I+ExJXp3@3<>i>}0D^6@BJow_dn zEt;EvyL3;KbR%(NjH) z5~cb0={(NlG^AMIxYfnjpm`^ZvpKJ_34To&rqsuPK#skT2aVSoEnskolo!`s80|RM z;8BpHa7XgV)Wybm22Vw8h$T(q_Dmjk?8anvc3Ym5Q}0XaDIOJ!WPkRK7Vlen|LdFS z`YUP8*fJ$O4lR+sQ-CgX>`VbCo$>~>M#2>IeW5H=s6nF27*nymN{fUXg*FnrKuT>? z5g=tIkS5UqCJfLNs*lOZ>UPE9A=BFsPA1ylVhcqF5p&%Q6|G`Q=Fc#*in)TRIrxoiE<<=M?h5a*_HB!;2hFaejzM64_ z&{E3S@GGw~g$)|CqBMyz>*w2`n@QT~oey`8omX>_%VyhNFIRd?4uFgmRaGgEjEoeD zf4bWJVN$HdSzkA#ktMDsb3%;u;#PPeFN#8N-Ll>&6H56LeHsQ~cGF$p?vTKi6^cO$ zNsh5K9mB{dFF6%0Ev-x2AIn7go0|c}8Oi96xXD`hd~B7=)O=H3*X?|;T?E49WtkxIkE{@WTX)?!IXNqje)@{`IjUAv#(ihUKGfgU>6 z%m9b&C_r<-Vs&XX_!G>TsUCo2KCmAihboxz=D|AD+1a@PkO0Z{Ly5WM_%@9+cAJxu zlkfaP=yZ-EMav%bZCn8TIrPcwSUR>N4ciC}~==^jgA8tEAG;=3CKJR#P3QNEDns9vdx zsZilLyoFB*KTe-dVW*20tD4KgY!6DugegzEkNGxA_^@4%VLo~J?+!-ZQe3FQB)&%8 znnm0q{GRsZA~6H}+KU?at4i6b%@h2`Zup;gB`(bm?1@^rKEYL$5*=LY(faiM_P*V| zz*p(|YkWq0ct5bLifDki!19IG6ay?lPdolu#m%=mNNhDpFymB1|Ma%)$=-dTuV|7)(fp?N-wU=5pwN!pbN+7<&FA$MZZB%;*#PO&^9uoOJ%o}? z?%Q0oF*6{xRkIkkX^B1VsVe&TbYf`B!%t*dO@!Mg(5ohUb7h{7aMaW7*nHO-c@bF8 z^MA8Z0>+HQ!|vy&x_=^3E;yuoT9)H19xlILBV%~} zl%0jr%#+vTE~7YXbtAiFfd6i9`K)^-kd6Rcrq; z?H%d74MpG>}Iv8`3RQ!VWBw#mLqP@`z2k108ncqej z#i9ZSU6*1IzlD<8P#*$x**g)cCxh3m!2p66W&|)~uytjBoDQ*9Z~1MgEDjkSkNKcP zh|n&*R1BsuNyF81o0K4(x-F9NEK#p!@fdJ|X`jb%Jlzw8QE$`3ci;@K3bS~e$Zw@P zF8Mb+pi%tST7O@HreYL*in93m{-+l?&r3VVHeP_d{OC+Y>0Ycilun0b0MnPvMOsCejxCYueUoLSY_u^ViL&>OwU4{Q zQJ%=b$Yb7Wpi^G>?9a}K2e#PFrx;EtUrqML2WRq$;G4Maz@Cd~o_MRk5*Sx}0wE=j zT3M-*NFh5At$ZTF)?&5E1qhff{0Bh1x>B_#?~|F}YqPR@i}6fBQGW~+0D+6_3lv7z zTGjti2Oyefv?`wC^Ig|X*~uB<5}6wK1d!a%44H}|e?HSMhZ138fJARM6COR@njDV_ zer1fu8lRO55U{aCgUSa{8%2Y}Y_x~)n(WR-&qX7<2Xu4bJrM86OMj>(%~jTLPi57 z;YxMLC+k(xc^EAPMBHWjBSs|pb92>C8L0w`K3DBf$>gos_DA2bhb4U9lW4C4mEwni z%W!@ez`a$e+SOwYjmxL0Ha2F8A4q$)$%P#B3dCa}L>%0xh4FSRiq5*L)eSpWb!fdh zXFRn3q#jH&(wc4>_yPK+SP%`iL(F0XuAOk)q+d_S7Wh*nL1ab&@~i6ej9wAfHz||o zlhpfK6m(k(2UnO-k4KNQSWB(6=oL`=`wgEMXe1-t{ATGUYNr@3>QqNd>!!BXB>e7} z+JHSYU>m)gv$^1mwuU$6PZkdSh=s!uX>0pVFtspsO7sm6B0&9I;eq|J!!LL|N zJ@Tq62nOqtY78FoZ;Js*tD;0o!)eAo48O|ztpf!gB~zI}K%OkZesAHcKvsVI_m#Ou zs*-tc%1z_k=>nuk3?!!-X;79l+yC~7kJl92gi-!xJddyCoqegDBKEr!BHUrK0DmWj8+KAf%HzpnH`Sd4{1*ttn5x zL5km8ORX~d>7cbR;9gy8vlgcE~P))pcfL&V<1(lS))3Nx; zWb7Gy4kr|i>!vz_a+Y7MF(D-%A!bW@Iu@C^BY9xm4(Xji9)d?>g>P%wlUQn!qQ=m} zF^Ky^vO&fwvWQcx`F=GYb82klelN5Pt*_9GorjT49t0!6M~!gXIMc*xQcT)cydJVJw_j! zM7|PFb4KkxUKZG>>ayP`*PtS!YbFJNJ0?|^a!r_q{Om8AI(A<%n#FBf%rLe_6C3e# zn30sBZxUkWwn;@@0(8BL+}iQe$8yAB_zg3SGF);Q^t__A;I1VB1~Q?)ebN{u4rk&C zDiHrsQPc!%*tURKDZ?waR|c*dd18IMwsSYDwHALYajG)+#X=z-`!TcC71@gGnz|_6 zAy4kpsv?cKnxAg1&FJhOs`u2GO{?CZiFhdAHMXk)ylFM6+YIwQb!J9?h#Lag&q;xj z0B~%z1pzkZCn4L=`#5?}@hkN=luSGjSykpt^>~(=KeD*<_9ZO91Fpg{&P8rQTTzwu z3zcd@D_m$qc(|COJ&V?16N^l5o?FpvDW+MY2~LVur+}I`n}Aq0{$Xh?@(YMJPgr25YEh&lWpBEuZSOD{dY-6OSyN<4!TWZ6PxN7 zNqjOPl=YHKY}J~`6^9*6Gz{qqhSDlk)C-SB#92|g)FUtCAd}In?VpF*b~doq-ZHoh zAE#C47q`1Do!pkkwl~!G7v+h2#G%5+jT>d#bX60hnCWcnCxu-c)13qawo1%1>i^6= zh!6<>oQYO@eCF^6$+506sy#>FMh<@q0#0;a_Ob2amAqr}B^ZZ+el7lK;HFVqMAvLFldeGKA@Y)hJc;m?ZRgl_0#~*ed0a0t8xX_s!oq7yTztB*f3=yZ$YF z_*}vdUA%2lW2qH1Sa6%nV(%&1UFTxq?#qKk^1K@#JEuo7uomASp&90?AiK=0Lg=y% zW}6vWZF}zw2GBZ=Ooc2SLmDA%W$#yAZ9Ym^{y@aT z=YA1isL4ZB#L-38fgUWiTYIyY&alA4j%eUl!hCq0>3o;wI=(%Jv7)ja?8;l zQ{K&XUght}Hz|I9yBx#5G_MAO&Rj(*v^*6@r z({)DgXruzC?+BaFfsgnY0r%LHpk>04C^-M$t_-Wv@&Zltu8FNDi*e?3Ub47OIp3@O zMfHkgaLD}--M>>jfoEpZ+wkX%Qyjl2!=<--$O={AL+UB^73_FGuXSH+=YWTwJaVSid7(kY%2o!M6-qSZv$-Lk)Z7yd zFnu1a)S5d;l%6d!`%8pPor4ov3dwsdH8+ki)Ffxw!4&-FW= zmrao!FEG#J{~>(;PcCOmwQb1&WrAVsO@fjjaEpp@`|_@w^$%N35L^F3g!%0d|8>Wz( z3Y7~nX`RpKU^1yd{=h;HYEQI~K=_j{B{&ZC{d8~~Ibi>0$}+R?=iLOLor36%FWcT! ze0!p_IAB>X*sTo?5gfP@%XxnDRHsYZ0`Nxsqkyt|M<)Js1GNNDPoFP?9zIhJ0A81I z#|v#>Vn{DBtMD9{RPNii^e-X!f2O9UO5(G=FWP(?^zy{!JpiVNXe7*1Z-Awl)`} z`3NwIF9vVM$Jg$Bdi)We93h+h_;;u2T4rN8;@$HgQ3Ax#Y>sLDo4%0Rw+IBF*_#&@ z(v#Sf)5Zoep{aMBk>BGLm)G@SA#BdqmGLIFV6r{tuciiW>&~(hDEbbmEb%ZI^~!Bv3)*2iOT~@Fv534Gs=pcjMcO zuDJ>bzSY^MsM64}P88D_C8C!pE8Udy2ahiUNe*m=ZVYGKj+*ALAF9^l#8DjFF+r0T zmqyBNm;8`F-ZMb^(WzHJ7P#3WF?RO>#&mmnMn*e8I=k~82Y}FGgTTJ#y7~nhedYJO zW%^_}505P}dGT)`inKjiwNHZuw8 z24#v&dP6D93=;a2RK2{sbZu=b*gpiD^>JH|Mg@OTe!)_TuGXzNg_XJveIh2HF@ByT z|HbK=@TsocOP1A+<>OPfkn2~~|E0vfW*k?y#Zk-<2!>(zeEY-ZhoZxvQ{09tZ~KQ* zwS}@G1#Apx*P^gBKkv)#r>mMr!A(VXKi8=r#k$ZjH?hL33%1tH_-qrT+aKCqFKM&D z{>K6b229jfct9E`iFAwLe}31~`TyK*B?J z0V@-hfZ00JzAz$0BJ(CNz+*z}zS2TEbGG#C7bPjaL!WAus!Ren;e8*jEl;}6G{jM_ zh5BYqThA3ot#z+B!xQr~XwKDo*g1O~jhg+IlvCE?N+kQW*^KJY021*n z5S>TEuj+=gFO);{1WU#hfIj3N$pRfE6_qAV<5%f z)Y#bgp|I-T*FMQsHBfPfo*-xB7N)RTpwfFrDZdokD6BE0?@d1xF@o>e%SW* zEpXJ+*1%yJFOSCVE3$b1L4*tz>td=lg0@>P)`cfXQ-HVIabg+xtrNJaK&dKx-Iz39 z(GInB*}z+>q0ojWdjKl^X#NYqU`l%w=Zo=LcX!M0zM8DVOfYoH{7!V)=i8&G2=>NC z>~R~|ef!(0QdoNl*4^I52c|zjBx&FWx{G{s3sa*pza3%hpVT5dqFYNf#23ACi0mNb zKb_nE=KK7goB;pTzy06;C~@S~uf>VOQpo2=prhQ2yUdZH%=nknTH-jaX7&)JxV2TE z&tYkoaMvn>_Fv}$P>Z9bm$b{}xfXngNmehAQxF6Ct>&B!oVx(Q!t(HMorb>t0)Q<7 z3JE9K7EfC{yF@@g^XzqbxH*ew|3+X<^P#WVah2`r>dGY3-dPQp8G_bkt_3_7d3bo_ zm6fAf3NOrZx5?lfFuyy#mztfOeHr}~$#6=L>!mjV7Ce2oc0CjV6R`R@(D@pr@iqgP zUs3jn^M$xnH{diYs^^TR`3>P`@fOD@@M7bzXK zWxTKx>wOL|Mu4`WVp1AWMQ#QlEA@RhmXHHJ~>*Ba8-qv0cZDmoNq^N4r zGZh3%x~(7ZSh4x_Shr522lan^(idB>O92u*Cr7FTHXbk+W-|~^0(}5OpAH-WzE~xT=|!L2 zS_{BVuAU~)Z?%tOaSI3#{@0B0w-WG@AW`7$QmX)<`j%{L!A+bpQe)-=(v*>SW%iNn zV!%r)=+wZ6M6#X4{YrR=I*Oc}oR+3a?)ooFG&R=D{tJsPjn6)v=et8(5oXP3eU+nv z`9B@vj~ukcb#>~1_2!*ni^G+lu8z(K;9q?Vxn2JCXTbGfZut7>-+kau%Iw=!U^!lE zVr8VKKPbvfF~%xMZ_;Il;nCkAVWoyOe4S;YWSftn6gMfasQAygtU3TlE`Bp|8>pNL z@Dviy&%dQ{nE4axRqwO_wb0C9R*D-?cv%927oMJhRX&``XV1=8{u@GF z1!&D08X6lHKN=nWHIGGrA)+XhZUlQA!R+rRrQcQ+Qr`a^+yu(3lydd0diMj{dW+GD z`ZAj)7Z?2TjHt994Bdc^e?CC!I0W$Tyku;FSl~7L%I{3UnUWNKeoA0&(JgSXJM?H` z(W)uNMR#)p9-0C#HWO4wUKpPqo5ab2>yuD{qsAF;A|9;JHDD0n=1vp0cAUv@rGA5V z$BRM318C!KIX+)Ib`s$cz@DL$&$~gH&ba5u6z;zwo~^|1_0xE4;$z_Fy8#(pj15TV z=fqILjOqc};nkd>7#Rs7q_BtT7+em{Mp^?bA+TF1_#f8r>)+TWRuDYh&EZ64dV~rf zIj(d1T$Uqm7Z&Rb2poO&=fFREuBrJrLak|}fGRYXP_t4w5E&#rRBNItc5A^tr&k74 zUzvpbU9_oakdWE1RNVLT)YaZ!ey0L{0FJukTVMj;AUewqZSG4)g2k{|DH<4z!hRj7 zDt&hS&vDez_k#5HZod1N)deBz0@oU1xgrRsZ2qIjZ@;X>^EF~046yp2QC3So=+pe* zR|_LNlXdsVE=;(qnk5oY%0Q@ircbXNp=N*=grXsjLc=RPm_BH@6MXdQV0|57|x&F&FJoFf{Jbq8zx2~ z*t>Rvh*L0~+i;mHEi2`hFhk#-Nri%FsXhbF73+;BHpkZF0W@^t*V2Wzl(32afbr~J z2nUowr#J`w5rp@;Fp%V$j$W6yN6wWt*D#)s2jhd2Qq0Lx>kPlt#rD|6-ph2v&J47? z;wgQg4HJVM72wZdUPS4>_VYpKRs^4eU{Np|G2VLC%q_a zXz6{$L#%DGdXh#eY}higJ&;u2>6*~!*7U{IUR}LTEAh|J?nqcXt6nLX4`+SCdz<^) z0I}80rI~{Bp>FqGQpXG5uMw9W0Zp8fE%asnS%_r7hZP#guclCLe*plRO3CJgC1xq> zv#M7X*rO#|xr{CTFlo3(9hm08fo;mE!=2pLCV-Ly^**iZ25dEACYQeBV)u5Y6t#bF z_q|R!=OcJ92|%w&%q#C&opi@Wnje=?p(7%({VQLcTeLzwia~XU<6L528?mqz42YGo9Xk&DE|xI zmQZnAx)R5x(#Qx+ukF_w30w;>^60jEmTTZD7DE&nox%-qKHFnE&E)SHrnBi1A%+-S zHNFJVE%_NHBI)Y^*0cN7=as>q*>BE@UvKb3jO#uJ5&E%M$Pf~uZ^1>RB8B{vXR)cY zBca?V?Xs>eh?{pFCN+OqFOYS7r@1}7#&tvw`>T^j(okjcw0pjYtSymp@5n>$Yiq%; zF%9>YlICeNA}D!SfsDVs)lv|}bf0vdx!{12M4|)?@L?r6zHM&EYv|hobGBS=Z#D*9 zF)*t28|0z|w~5%hz=AkyvJnKgNbvJ;I>*ls6VL8-bRsOCMjSVZ_!~hP2nQ+m3GX5F z)i;H>&P|87r`Ddg83%t-#+!_!rGLyS!}kmBuk!t*c>2%KwbJD1_xjCO_8#^}Czdw7 zhSPt#SfQ@MZ#G0!uFJ)Zu(Djr5B1%0O?em%ab(+$P-?^9tiA?q2sF^**!IO?`-geG zV#a&z4Xn$Kpj&|N>yg8Kj02&G!gxnxx30yzCKedg6mHFx00rcQYaKQ-8VH!V*5zeB z+X?@`bV(eQ(MBN@?UyKU-(%limWUsDeSC=i1T~~5^QEscQf<2_%`qfgo)(el5KOTR z6_3J#VlKr%xBV!HUzUN^R~df?ez76DQ}m7YY7R>L8YAfRQde&c-sAP+;AZdG0&BU} zyM7IA17_|6>;!50ocG*=Wbe1=lBOwf4BPHPX&MBbKvV-L1Ug*C-jxPOufq8A`vt-8 zQsd=JzOl~nupvEkU{q2UZ}Jk*dl2AT`}S(cCgN%arg;pb@cKsuJpgu+yB3}^7I+s&oGbCi>|j(JDi-BREt!PI4XdYK%BQt{^c?2T!8iwY zCN1JRWQNX)8g`SU z(x`pC8CbC9*<4RjS)e> zQx-|6D}$#C2T_=(%-a^2H#dWlNC>!&b3(#~a0zsn{bSlUGo8oxJiKtwlQ_~cBDGbr zE4*I2lotjUaWmfpI$$5&I%PiN>O3sobf&dJmK-0ZP{c6N_r6f@&LHF3R`-ZPBDi=2 zeu;WSoZ{u&1fpJY3<77Pj-LK;f}XUrR4+hJ$7MkpcZd&5*r0hRo|S#n(3T=;_8*~T z6B(n}c3XJeN>kk`7+To%t$q{jb0}iODb*)1z7ystKg4H*vBW)YcGY!-1K8BZ6QYo^ zp;T)2saOR~mY#8;#)jxE8O3Dyp9KE=bUu}hx-n{p7HzgLEiZFHhE7~Tp_sD+5hYf7 z$Ex@Ht3K^-@R!;VTn~io6Tq66t%{y3#zwXQ`J-4ox2~a1$)m%SEGCLHjkXEDzU`F| zdbr)?RwQVWc=J{PhT%~l4lE<;JLZvaH+z@np^+o>En_Re1~MDInZ44lNk!w99NQ>@ zpGVT_KOA+%v*Ymfp~m&M_1(!n;Bb@66e9ZzBXDB*+z2USp3Sx#)`C&F8#z!zY@AUV z$5W}iS#*{N(O}c}yAf&RJw%d&R5^bqoNs}I)P=8q85h|G zQGo%|f-^*XE~H1W@5morY=@+vc<8SLB%a={-Y1U%-;QaCvHf^v%T(`UhxJTB9n0}1 z>1Fkhhw<{o3EuonY)Xn&`w9Vk*?aEC{%;O4Q*;%X{gDFfj_&^^{th9@eEmFzA!v6_ zT)(pmUsPH6@f`f0pOvYN63b>}QXJY1`|3Q$BkS|Qyf&9cC32ry+df#r ze*M(vOKhOpMtHJnn|o|3X^5o)gNnKIrlw;;3UAvJ&)v=f2pvv=CU&8Mdc+%gE9VIc~r;c_Hop$&< z)VIK^+-B zLPNjt{Cb~SKla(Cm*&4{2WD`^j;C=iqE`kE|8{<}orf%KuzKZKGF@KY8<09DI%Wc&jf7^onovQRwiwmR)sYR-ktL z5(0Uq>;)2rRtMZeKIQ=X=CaKAnhA+maQ>vA zp-TMCwL3w!dnGI$i+GTo$Sb@8V=u9wrLgSB=gRYJBNG6&NQX#>5#Rm>BCjtlfj^p< z+zPMuBg;hNU-GDYC3bUh+wrPCk|#S*x~5Uqon~KNf7}0*%#vIEZZPV%Jdc)rvl%G* zWiekWLzK=UUJF)SEn`j$hhRDm&23*T)1IdNw1t0OZ=7nd>;^e6mwIcDb1T$l^7F94 z#I%AuX2HtkA3xlBl@lCWFK-}o;T|Uk>CaotIym&~{)Oi#4p)<YvN*#Eq0 zT`2i?s%>Eh`F6vUiLp9)F&w0!sdIu1CP|-ny|=}Sk|;uV)VkI4^E26>LNa&RdN=Qs zG_1122g%wvIoQy8v!~xEXj+5Srz4c(wg-0@BYtDUmQ&u9KC;u+z|V4LMhK zYW$FJt%*PhXHs~6c!TNZoMOhCy5Cv&}W?-&lFS_72rzYUMe@*{o*q2HZOB# z?4ZiX&~am@PH&}?r^^=kntUkyJz9y3m)i=YbEXda;SU}o@+m#kZ|_b_I({?H>Y#=< z|ND-d(zDyi15~6`x}f-Fj&dJ5aLlP_+zT~*W@Ab^)1I-Ado<%}_M8xdt!zv`kKdJK zPFAPHZ@ek1$Yjtwz=~&dZ7A&e91kO{S+3L5aWGsX#X<0~o6WA?af;^=Jo5l;IeL=t zd!H3B(+|au)r>T6N3l6xpI<<5_hapkO)8z?3hnJ&SFgBrcvxbwjf9$;-z7^}8Z4%c zh+5>-4T3vLV~Y$|Vv`IB?}8C=WhG#h!oMaYcm6hv9-m8zcx?>cv1n}t&G6!=`rfP_ zE0!pgFaHyrc(nLD<}&~4PrKFR`-AT+3A6uJlaS~y@1rtkp|)Rckhsx&?<_GLheHfa zE+%Zl6(@l4TV5%I4)i49y#H1bc!gI}vZ^pm`hWm3jr(d`|PXrsjIl zOy=zTRt+nS^|c5PV$dccqkN3}Ss6zjR)&9x`il$SZAe8mOt(%v0g^`YJ9sC(KIBMo z$^E&Ql$K2p`?Q`fccuU(->nM_rnfprRX)aMFRSu!ki~H#ZdQG$?)9VP(qQpB(jKET zoX|+v1p$4B7r19UVe8XQa}S(FF?@dG$&GpDt4`{gYEKCrdoSGq!TE9Ago#9Z2eqpr zZCL9)9fIfcnRBPWk=^n(@@4VtShBQnX6>gsF4y+DDB%>39C4VyC&&j2Z2C&Q-)1MT zQ)a%+Gcfco-}>eX`(-MsdVrEnZtZML65JJr9-B|V=36&5InIOgf^JhjVpiBrd)ZuH z{ZfvDvrlah_IN)n%qPY;+XyONQ+OpNwsqvzF*35b-g|;t9K-O;~1-=^gHXj2Z!^enM3C1=8n!|b$#%e{&VFRW1{f; z$$(H`;xl9Z=-1-*Xu*~RmdR+>pzah`zTGw}^Whua^sJ!%eHZS1?6c9Z?Fewo2u{)Y zG}Fm6u!A99&814EAAjgL-05@b9p73xx9r5`qx;4BbN5K_j*7S)RF1a?^8pui;7n<6 z&U8BUQf8fYE<0lf;xgBa=(qA9H4KnL5ens3^zK7jrU!MEQ_M@Uj{?tR9F-j$mv>3< zjM$r29&raq^FH*2(&mT7;tR$ZG}-4hl$)Nhq5s{RZm6>f`dupA*I#8sV%R*?o{{am zLuaxeHv~AsY4XjU65pnH*n0ane1TCo7kby;@=_8E!d#*zR>u8n*eH*zlHQGI#rZK7 zF0?Y~8Cv$wxq0h>d96Ee_NCwZ{6-g!n(~iQZ8d>toaFxoJ+^xeKghGW@@8t<&F zTvt9BEoAl^Dva?OC62(Fm+icGK6aWTgJ_;SR71ZO3)S7$(ql}Ar&c*9^B%trT7lmq zGUXm?Cw0PSabk-}(S06|fbCDqj+b=Gs^nbpT9H$*9~gC6;=2*9x(X)`(a`_8am_36 zdX;!j9k16in)#P=Rvj8BPv1;@fQ~sYFi&;FyX~|Cr|{d5zH)E;bBvVUKSMrGPM`TO z7nu4g2eg5n(#B=g;6AmZ^;&)YmHqYSw$BINtGiV$QHth399AsL;7g5FsFZzm( zt?Oo^vSzDkU1_bVI%<5;!|HLS%PW&LlnVXyWUI0w{rvZF8fDvqOZ#x{kneV6R z1=}V|sD;t2R^~euEduw0xaw;J`uB?Are_y1uj_J2eTOzRvnF`YzEDQZezj_HuwPj- zZSIjO)ID2Ip6@K}8K2V;k8K-3opzy@3MKIMDn93QA3zrWUgm6G8&8?+{FhMTv}AT7 znPz8Ihp;zf{M;Byg0`fr_wTBDDns<_tramni50NvW(@o{H|u7MxiMh%?TBTe7nNFv z7e*zDDLm(iuGd4Sb&yRe=6uxy&8CXFgmcRH)M{=Ftv7o$(fxOWqy%#uUpk-^3ita~ z<@YaZSeKQF?>aEC@%l>VDtUWWtOgtnKAlG2TkDz`B-c?2dG^{roW%{cg&NCwve%8fnAIMJ-0;^e)ICJK>X*7-@s(gP#9dB-Ib_6L; zKu=u_1C$4S7M(C3nmN5Iy^K(MbFYAw_w=o=g#v$ezJ1-zbkC(i(iGD|rkKgWl{-YW ziL6q&pQT1!A2p8ov%i{SGC23hWxYJZEMs)A=^x>}_Wii%X-#J;=P&sh8tN~3|7baL z!-YfnuRgVtN)+ZHbek)|B8mDallgzU9Va%0y@rf;!HpfFBT0H#-sOhT-w%}6TO_u8 z53^;M+)TmlKK`^*t$-mn%}r(MyvTPSTxIpKz)ySWHda_@x~p+xw0cx=iCEac zpyS^ML{Uz|(*CUpEOCy|peWO}&Q7``ifFm7!0knhCL|@ShF;a;b>Pv;vTz;_+xsHy z*HZn>ALd-Yjgf#oAj1#nnY!yTRSvEx5b8 zB|wls@IZiIK^u31H}38Z!QI_m5-hkwkj7ok=KcS#>Rg<=^KnBp)kW>@Eo;uX#(2g) zmz(Ciu&TBzV2KqhaDP2h^rio^>eW9m~_q{*vK`0}SfRmk1QQ{`-Yot2HBSaJPX z?eq33s+XJPcghc@u{6^Ztx&y%lT!W2+lfvFSKl7AGI8Fu9+MC!3qsv-a1J$@mXUI7 z!rB>Kv}J$k>AfGA^U1mhJQeI-Yx}k7w&&CfS{LN~vOF=#Pw0DhK z>B6{;Y)dk;TAiF@Zbddd(AxvZxjd{>AR=ZZy0@8_qq~f&?xWI{`em>hO9N z53pqdWB-CSm6FOQymF12hRyEP%iP$xYLa_9xkxSUZL2Y`Xs`(rNg6rlhocdxp`R(Ga*mt#Zk?C{u(LB!d9X47w-8wVT{)Kb!CGR%B{P9QO(@e%m`AG3hKUL>T z!WJWF(TMJc9=lMu{Ho99FfbqEf83nU8?THZ!vqX}_P zC8FZHkdNDeB{bvV{2d2|nowT#JfyRt&gf6IY06&CtmrTFz`K^$!?ScJzz}SH)dRTY z)OhW+{_td_dF=DsK%%m~9If!4 zdVZRddBu)ImttaW>Yzbc5I^#s$0@swTZ$LkBZ1x0KU$ITiNyYTtAl+Sr!3x9(6KzV zvedz45O2qF;H?DmAJ?}rbAIPzi|Rj6$!TIM#FkSjW|d921l(N_In3ef34RSxEch~? z2d7t^wwF!q>5u$UT?P^Yqt^J)}E`y)IQz0dfUB1Q2f9otEn zL{0h#y-d?#ee=MUP6rJ7ZCRg(#ZlYjp+Pdm!rbo-1mscN2r2xx+N73|muTB<2LEIj zyi(sIgIHZ&FSxP z$!OdEi#$Oll(bAvji;ktId^}oU@I8IF&`w(!EF4|y?1CiQ9vzCsPVC(`q_!ET+cj{ zTi9QR4JUK#XQ2ibl}uDJXIk6B?T10VBXUO=yN0#7-WJ8DvcDuxsEL^Rq|M)-NG;5J zqQg>a!FGh}w(?W|d~9QyEL+-J%(AkHW=;vB9OfNd10)0HHY(j+x4Fd(2{YbD8+?8K zSr^O^NUEM>NsxsAgR6*`^Yt3n~9* z;D7GpT=bf_@Q5Lb2N`m$?FQ+S@=g{{NaSVL%%BC-gkFw%bS`K{DY7j7Vcj7$k>JX< z%Z-vz$_c?@=~rp$Qm;*aL^a6}*bZPLvR`+!ki=kRdhR}C3y%?;X{JvZ$f?q&H+Vi3 zO{^H6GGM&k4?fN8Z{ND;-eSFgN#Tj9@h3b!k-y7O$9FdApSnD7|E=AUWjx4Xr#I(5mrGyn1p zKi`*%W&ms6^k*FQ2j{O2VPdSUU0z1R#Ii75XZI_L_-Ru*(6)I%BkIeH25i~-Dd`*j5slCLqhg2yc|H}Z^7P0h7?Hrlf&Pj`%6xGI2Tg6gqP7 zk`rzgLu6O?gO6xvgSg)t^(5V5e~gr7?>L9nV(BO>8&)Z04#OD% zQ$ARQyM&snMN8l-LO>dJ>_cIe=ad!k#>eEqc|%ev+m1geTScy7x-8PELA4Ir7aKac zPc?Xi@fd4dusW7qwJSQQO$rag?j^x{-wCj>*w0PYq-vU4J%ff@M5*<5`mTDla9j9| z$!q?gnYey~7FGIie7Ew-_-SBuON*yFE%3{jmr)8WAno;b6%ULkuD_RW0ZRWV%+05-NgC!(3qM$*={nFjkUFsXD1uK z$FwBE$4;aAjO+OGkw#~;F8HCV)_}rRFQqQmV?I=xS6m*PQt#}vk zo*RP|b3pl9>viw&>iuwaD0VzoruDcDXh1&e>M{W*hRgY%Mrmnj>_j^M<7JB$Ac5BS z@?|8;^OVtKFyj1N9U!3z2yXm@X_vs!!n4pP2R!C+Xe4}hcaVk!13>Y1x~-H3n4i7d z%gV}3v%PQ5U(I_*6PZm{Tb;!W4k^U|UCWJo-@Ql09+V}uPqQf)Yh^_!>nQMzLBN8ydm^~Imgq_fQ? zMR#JPy-4pO-2lN+-%x-E${5d7mJ@aeATJq6IxJL7e(?OI7j-G%J6rHk)U>i|YW*M_ z$qAcb7}uVu=d0@~ZM67HbCtG4PoYGX+g9iWkc_FhH<@`9q=mwRw-d>~7GwBwk$lmQ zqjHBVN3|z1X=iJD>L?y~0q8tZ-vVww8yd3z7k#z+X!v?<2<*RC-8HL*ssMqe_rJxT z)!B>Qw#}Y^P1b8XXsB$!xry-#IB~C~D$b2!&ioL_&(4MRGaPq-%kA38amx2)-!}`TyEi(|3MddKY=Glu9@41qyVt>oIpirC9}^rOJ}F__>s zUEH^m;PLg+_a*v`3MMwe^Wyt@>&yNoTVW3uf7-;@rJ=Y76KnyAu6mVir$X+)2KSRA z?JFTJ8yj2F$#T;ekZin>E!bu9jsbDEv^eYE4nIb$bhF|Hres=aMaPvprOq)|64`;q@vVy&AoWRxj!Cx$Qy_qbg;|(j-04E zKu(3RE#-lEy#BPu{}$_O{(koU9hLMSDdy;_Rlp>C@wQ=o7l(032?0Lv>q7Y7)1T(x zVQO6-Ts1I-Wg$xiAT$81sa4lJBKLuELBS7=%eI$jI=G`(Cr#_8Bp6%vZ|Sjal!FP& zUH9o-=fVEHj#OV!rPQ@v&M98i-m*nFFGA3;>7cBP*4o_-t}unlsaTYmF!6acX{UGJ zqCLEN3ZbWM`k4k~e+s;5iwuStufWXe|Lk=N{7-3;gf)?pXh8QzT`yL4vRHIq#{rqv zNcQtm_WdJGmbROAaA4&1Bs~e{0U)UvyWh`dj~2a2>Dqrwi(PVE_wMM9>3oEAb!jb# z;8ZWRpx?q!ochtGA?-jVv7uq#-)6twXFL2+lfM_B!*1b33BYVb(YWB`T*NZdc z*G6YxP@?}75elj6pyA7|;X~JZ?-qntye+ig2wF6h9rpO!y0xN<LI;Z+dI2T~Zy!n)5T+LF0dOtdXl|VP?@O~E0f5NbS7lu{ z+hz<*7JXjCj3~$NTWu#83F7^U23Q@G`ndnnXwbc!j{O8M3ASWXi_GDg7dW`=`_2Tn zBeR{{zl5Z#b- zONn+vKT1vQGZIe{d~bwGw3|IENV48WIf9z5M445m>+5hQJ(Z~06c=cUU zoq9Ek?*_aZs?_YZ-dah1c%kPyk$+RI#VCK5vyz zk$9sFQ;5}#hQ80vI0que(3!Bv^j}4gS^Xn&K8Fg(EhKd1Q-7c;5-wA9bM8i{j>yj= zK-dZ?3F$O=nOEpp*Qm9}4?uQjQ$6opq5!xt%o+x>BHGj;yGpveU;85k;)dWQ`+qck5f~NCCwsYM*L09 z#2JH+2frDKL6PSM{QmbYgJLsEb-`gOR+nEOykC#`)ASCSX`-cb|2B}bbJihsp?IlY z3?FQo22V%y*J|@sidj(_59ffen)={IEhaTAP?baW)P&+O1+rz-!F3kcfT=qJBra!4 z5pZ2C{b*8a3zz$W*~sBL7m16^Wdbu3jC_Q9q{Au+5Dwn;)*=z*=IcG$81>=grzHB<)M3>yE4ijUq<)}Loxt18(NF}PYkcZ7kMRAkR zlKUbA$q7{(4UtF8{F@kqqbiXN0uzpu-*j*i^gQ{CS`gcNn)M%Qlq?#(PIUqiun)$e zorp3f^7+N;9S5NszEQ|LQwX`6UMufWy||jZIP?+K-1bm^%x)WRMAma8-^VGkom=K% z`TLQ3(UK$bz$~tWJB+?#5k<*#tYBjax`$IbFYGFk5Rn@i@*STk<4d0 z7tt|DCoR$I{i}9tGy$s{d2^;4N+hETD2Y=F{P@mqGFet$S}}i|d!ff5Q!pNtYm~iC`Oe|kTTIYb{Jsm8Y zTfZCR_j1Kvr=gIjKjfM{nRhRgbEx*RBs^aY&I=-(#=L0!&NW5|8q70EGhr)f3l|*U zL?z2a$sT!lf7fNHWS>ek9$|B)W})-}A&JEljpnD{0cL-U;Jpw#P|XdsZmIPKhjxKx zW|(tthrUs=@0_VI+$LDcqzwjOz?A=iGf3Dv(Jr?ibpaF8wKwOZ#l}*M`zu4^r8gD0 z5e424N^BMyUnm@5_?*E2z-4uhqV3Ifb*!GaZt7eq)o-Pw+LZ0+%0U}80yLuSL2q!5 zhifW(t&-^1DL_o<{Zi*5L)zL12cz54Tlf1g78z{_sN9ZUr@o5`Br#8sgG^75gX998 z87%I^uS-?#A2~e1O?U9dl&O9aD_A^yDOalTZ**)Mm(whNi^{dI~C$4fVc7v?g@lqVnUtgJViq;L{C!{sNn#T z$}y0=1X84uzi8#<*OpFUoKMf4ze9n`?fKF3i%O}S5!P=|q79<0DP*41Zf4J-AL75Q zZJ>R%B46R&-H>;?E#Tk7P2+v%c3mOeA8qC2(@8mUWNAxDT>`eu>q9JJjS(dYTyrPJz_?AaDDI|svS zu`(4>koqI*jX3}?D4dGHzaNeTYGdrXVNP5(QY!*QrXSW53RzSQz!;m3*sofuzOz<;8^5;1LGW2dF?WHekK`Ir8b1NVMG6a`B`gpNacEd zLQ*8@*Z#u7n@>2KMSLGe078Lc&HwwwIsX5%6AnSNuDO1LmRC_^9QP6T0PW-JPKPll_?F=uJ zS%RYd@^szj(X&}ec1+g`eZP|25Q!9Glc&vKu-#9G$RaT1G0^G(WhGH3PkzL8`Ioh= zwyrJmv~B3`%<+pi5Ws!4@(45zXI6air^|L-tL&pHVl~XjRtzEOziL^SgbVFgffO#5 zH|yh+T{)Wfn`IX0L{6J_6_PaP_04b)T(pg7mXt0+M4AEYz>~Mn(>BFp(1qaSHOq}1 zDus1Tfe|e9*d!av=~UjahW7jiqq4%T*T=3~>T$bPJp|*vt)t^lA@6F{QI|<-eBM!q zEK&hp)*h+bRtu4ZIx@noZvU5KbTV6Vju^^}w`Q;XYF5!F045SAPr*x@Bb&D%Ur$b! z%A19HDl2wVQ}h0(SI2G=5HC;@`jZbaIF=PK9$>mu2>^DG4mc!4=(eI2KvL}!pewTp z0B+({ytZ)GbYFn-mZFOrVc*E;NK+s23~)PaPnkAh1*WaaVCuo%r`ALA+-5_!!q!IUZZK=vQIA({T)O* z7LmE~otSk+KLS;bLtPUE+dC$)B-#b)B1GtAcdBVH|2#ePusb5(5Ec>3zc=SDikQCw zAsADS2t+RB`X+3*=MFk)0Cyqt=!w=yI|+SYj)X;nzWsjmeg&3?56lh9nh~pPrW)2;p=gCm>2+N-iM`ttnynae3l?G4=N!2) z;t8gwo9=^^fhxn~N5CU7l6YElROVNaCB^)vG2x8mT<@@@SHrhkE%{UkyxXliW>6o#D)GBn-UfC25q={Q1g6S3Ad^#uUT=oZ7sDC z`-W!xbU9OBq8ONkF~t?1IUL#B4eNpEFTq{suYy~y@3Lm52{li*<rwgJe^zrOO-XJuRsM?fnW*_3D7el7=LF6tEn4EP49XRDtj&nX;9 zt+4s!ahU`bKF7{AO(>yzO(1VlDL+l!2l5m8SP)aP7;F{P@nD*<=)=oGVf9Z)NaIVH z1X>|j6b$!qd>WBR0F_M-V^xOnT;{ytG!1;7FlACLBl}T&1vQUdyB@!;+yB>>vXy%E zW>}fs*i(?%eS3KX%pqUa88#>L_U#XHLmnh`ftjNDAC7lc1V>S7J{4|=M0nVWXnr}p z)W_P+Oa+LDcml}y(KxQv>$gG(1@QBWG z@NB^Xn*;k}EjuvW%*vwIf1r;3#Y5i48&mujFThmgl6`%{hZyx1`gTKb+m){3#}|{6 zeNWw7PW!jPdbNFOQIVrnX$~SQwW4bh1H1lFl8-_1a$&E6gQ9(S6D8UlgNh`FUE$C#Yv4w-QH_8ll#tol#6 zv+pCa!$k5`ZsF@I|a`awpG@vyG>?rvbhy18Zh=}0NXfqps~DXqEJ76 zxl(!6Fq=r*g-fjD%^Q@!deMW;veW{@1G^R#0p^HY3!A=syUA6)&qr(2reQ?*+<756 zG{cD8Ne2KO@D##LNa@y}+9O)NCr{!1XDIZpdLG_x1&bn3Sg1O5ci794xYF+|nWmEm zziG{*tZDBY>gZ?rWCq~}zdaui``Wa6H+v*=nBaK;ulee5W?m(!B5Hs-DkhpH99ij^ z1JdtJ%oz>JZ(yj^ADP4<*MWNe$tuKs>F|t|aJJv#gD60 zanLa5Ibm{9v45<9rlvV8`+B9MjWW(Hxl4ZiK0d>WcSRJ@6bfgh@&XfA6|j0a`tn~wo3YB&{*oYbJ+jPH2HeGEJow9|YaEZ&ep{})pYyuuY} zp8B&NDLgSB515Ge0{8%fH1~hM2>1TKVAjTU0;nc2)4WPelwPaNa`#?;xi@ZrFPR9g1-|-LqP+pg+>g1B1K?6X!DE@lG9_6& z1MPr{c(mTa0ph-69UIakzOg8`>=*}Nk2U#eq@#(iYTQJE?`-^~<*f+yiHE}vt{n)E z_zoP};JZErcb2p%Waqar?;9-%qwaw0JRuMSM}A4;^V+AqQk zYhx?vkI=;dAc#-o_j%eqA$;i}1>_!MV?A1*p{l#L$?`%6P=D|m>O=!x!LCcB{Th9` zBO+g5+#CyRINTD+%nH=ubG12Hv>y`J4UvZ*)jiRQsU*$3w-%+J3t{6Q)8le;1`>fD z-Ku%^*PmC{uXSD1Duw1L^b|m=0F95gOTruR{3X5Xo}?>^=U%q6X6!9L8RF_Qf;+F- zxf7?@&P@4bMQ1zZ845`_oxr5VdWqg9OKV^{p>d)*TASlM8Y_sjG8>#De(fjE6+ zdFJ!|ls3$XxFBIJCD_(oN)eJ^lik3P8(5M#~=y^4>da>sbiHK zHYC)E%hbpwh3TGI*ChfJbQjUDchQ{})H1D)2)7c1nBRzzCygSFTYEG5_*D86$%M6! zv~%;m6=IRs!7e_(Uyr!~%D$;8iV2}nwPAYLtVl~8#Z-aAhavE&@6(X)T~7_r=MC~( z-23z9BE_$kO^LsHbtO5qI#r+Ykl;N5qkt-ka+J$#-Xtud+50#2XLyE`v^N0JcJGl5 z#ANE-)}a(D$d(KGWRx1z1K~*lqvyE;F4nPl6|tqdO}1)HKI-91GaT5gOk1$t0j4=| zixP1pL;3zE_t}Q#$j%5i0t9L=06yx*9O<7YEMAu*BCPhU=d&N7cQJJ>Jm*$#)cZsH zsptTXk`nRP`>AIiP`Qaz69GzK&>WUlIl7N0P++ttM#3qW%3qOt9&>gn@+W2m?bg(v zTVacrdu&Y_pJ}^{!!`p9O3%Qb+dv9O3adR35i|K^N`|uPTZ}<-=h+XJcJB`r8 zMz zl9N>^F*K}~jaq{XnMGdSjz54r?%za;->mP-Duw@EM1W+^Z zx_Tgq8fRU7VplS>A;dw%6Z;jj489`z_kTIfsGW{MMfv7C(Jm;rnz2zXNLo&qP4N9t zz)zt>VORzEpPOI*I>slbCZ0@RPTl!0P4`6kFL%n;i>a9}P1kl;)@B%TELQi-Sr)eA5kQGqc&C+7G5U;^mSq39gYSL80L zGl>UFxU+T<#i}n`ZZ1>?qIeQ&Mlw#AJZTUn1AU55#>h0#Az!gz(=G~P!)&J!QsUTP z6OO1>5qS=C@bXni_t#jzEG|V`bw_FNu$W1!XN^XLMVaF{Kr9FB*K24t5wqs~OAK9C zotLi94p_*Uea)kf_bf zhS9M12Rfc>;4#595a5MK`OvczMxzGgCB;dZjy>Eo z+AyrR-6E!Y@QWNNPeohIw9}LJo?`}UGow#XQ&FG|w zwR^Yg8K-G*SdT&S#f)^}(h%}~@kf73*_pv$!Z>AJ=<@+HyA<^PHrcp0R+;^1onQ~c zm%}(Ex<~$5jj|ieTunCA6JA73J4Gq=AY4t6_!GI)W4K=5O&>o?kX*n(gxuZQFA6D7 z$$eAoGgK@+0!X#lZbyY&e_V80-lOFML0vhVM@o8>+eXl5h7o~wOd{BKRVpalWGwA4 z#yL}IG{0Bv`_PtP^ep}3bw<2oGrhX)G+=R!kwx)f)^PTBh1)vBA`+x}8WGv|2QC-3 zshr#@+QTLZd`@pOgRayCH$~&cq=W;FKcHC7nozDZ8u!!{B85{zt)*SpH@hIabX_j5 zS9f`Q1!rl3Mc`4E)uAXI`okZ|)G5kGy=65lKB{g497i~JzhqH-?dJj& z&n@&`Q!WLOVclY)8DWv_`9t&GHT3S$3W?q|w0OL^;Io%fS7obSDU_h2jfaNMh$lJj zmW=7_4QR?RtSIf~QZ^X`(Rz=7t24k$WmlRIX+H#?aT4jCMrkOAWgm-kOgTrsBD8@Z zb&oxWfRlPh66_ZxEdjeI*GGbj-P!k;r@E;Yqhm=&4U1dLu?YgaSKxP8QBK&BGC0P_W@!=-h#7zwNkJ9n{I;w9b7cXGFYNFYk*>Ed}P4ljQ{Q&wP?5 zqHd3#wUtuG6E(>O%Nep{0#e&XCQc)9K|Cm?_VfGt1PmeG((k1jC4?g=iq2_A(q4zr z8xJMZZ<=wI!B0N5`=sz~&ki_81#li26XeK3yKmYez^{~u#r=njN3J{ z?`1Paav(s_T&I+`9GGeO@80_?fMVQu;^%byh#)?+N--7&G`kwb zfcab(nIp^r>Wa+P zpPP@f-?_L5P546@XFXL){B10Md{)KeJJQ)w+Z4qKhZ7nlOp+_cTz0gbB$4VV$f5CY z`|ak~&W`8E3KNv2%!!xqh9K4nF+1onLYOt(u7G$$JnL$jZrZpgUHTW-ZyK9S&y6Bi zaW0>yL&OpW_KA9fGgFvW%bfkrV(E05R|wiIJ$=JAd>qzGKeTiqqDg(AEu|t2^y|9T zK9-jCY)4ojx8Sd}*A2Kr;&%m+60nMM+yX{aB zKTyJ#OaDD~IachUvMtRL&4(JzF-gIaXQB-LhQ~YQ7lXq0`9pfJ1g5$!9qKu?O*@Z^ z2$NgSV&Dvc#;+BE3hl>FPTiCBpWP1sIT!^=UuKSiowlfE(d38Ga|i8u2kc>;;#T(@%Kn!#t1tYc8#1o?Iec@Chw_; zzk?Ac-5>}nTEn~q%79F&-x-T~E3H`>Hp)qDiHa>hPfF4X#;9oPH;1Bl&&CT?Mnvz1 z0bl_5iABSJ=^_G3J1a;u+2oCjbNCNY(}nreK3(Ugykb`ge$(y#?QBjEc$>< z%$tNMuRy(mfy@pU0GdQBMrWj{i>ET-8Q@`&lBf1p$}Q;TItD|_J*B(KniE6!MukLx zrwiUk+Ib)8akIn5PIHbT3I>TBA5y?E(K5jaIX)m!z(u307y0;Zz)%dQ)d5@a?)d%^ zGR^4i^zD6sfaOHTe2qh8Z;!AZk6Q`qq^sLS)UKj5&!;W=KQQp*jI;o((~%G?9BeKkPY z$R4Q-zl_JIM(Vu=peCIh@Dq)JLl&u}`y=;fNj2<=g7*ZQe~bdYbUSmtWJT#LL#lBX z{gDGlv%7%xbSPY~%!nhUDeqRs1%PJkpYb)?nqj2iZcTwU> zjs?_H|I|mg&01t)KQ774+<_A@SzAJw`Vz8sPIe>Tycq0R!U~Iq#c84;>_^lhAuB=D z!&g7ue7mx4u${fsn2a{uRFLR+SxJ^wvuS{>+1taARz8QpgvP`)Ut4MnJ1ao6FdTc} z3d+dSA7~j~bQ2L$LaGYeD84g7u4Jd?(QAXL({7iR`!vYOc;?|lDW=eRaJH2q zbe+aSDZwHZNUwM&YZA4HfssBBvmgp)W$afXrUHO8Oq|eRu8LzlQD_i^8!FaOlYI=p7~1 zM%fbGj_vvOYiv%_S<7 zChcFB%Vp|uq;k%nNoNw-P>a@SqbEjI|N0qb`DP zLT09wsC5E;DiCFwU_bEr5shiynn1BY5yeTzh+Iy;*gGk2Tc9KK(4Fmzk7uS8Ar|?S zfGL;{UFdr$>>#EMf!dIcn8uf^aGCmrmgB|%w}t0Gp+RHSLbx=jrJE7*d}O<-b-5Nx zwiQ6M!u5-gz=q^yO(i1yCY)-zFgnNT3?0XsVz0>v1airsNlu~qt=0g`s{iBbg zxWr=f^7dD+>>?;bt;A!cmRx+^JrB8lTObN2`p~_=Z(CpzD;NcMt(?~^Asn^+KJ0(# zg^cg7rfq?_8c(B;;|fUJGfLa8y-C;joOz)dfhEuD$9$>^-=(4X*29OdH-$@;9i#R) zzK?d#`Vi}4tE#4(1@G&MOYcUzjt(1EfM6*S$&y*2{%4uq*4wtQ$@xXsQ|~#UW4T`8 z_DJ_psBqrmRU0SCsL}ICITPZnUQ@>6x?pQYw$ICbWO|uaQR{x9>HhQ(zk4^KlJs#C z`a~dnHz{e@x@o zr=Wjw+Shffoy^0LUT{4SuVv-po!L0?$~@}jH4*yuCHIqP!3Ok_x$)bEl^I9zkNI`( ztjm>j%s-gx7Fxfg??jkn(W8tmU7YoPb#U8MRUh8t z=9JFSgI>noX|GnG{3+Vsa^mdTX(f(UN)9eYw(VeTT!J`Xk1vzk$2Pm(R1s+6-sqDh zjx(EGUx^r2u+GLIIjR3L-3=p3)u~a4GVpEJciZZUt)uXbji3!>n~sXdcZ`(Zy^&sz z3E78O2Xms2NXKE~VX^VsVbz1UD*sg7Tby2^qNmKS;4Yjo-JA_l+u;r@cK zjTd@Z9ricv#{7bGQtgm0y}ZT3A@k{*s7O-KvTIg%zg&$6Hp^~(JdQmmr!@-(e3BY} zHg(uDpIvMEFH^-spR?ygyweIoc0r4+Y-m4>v?8Z}eW-8J`1h$zLRgvlIOR3;X>a;= zSM~WP3lBQK;bk0#5ia;weaB}sl0N}4{)4e6o{z4Fw8z+pmZFG;PEm9Dafp+@>!=Ce z;T_fHiH^R=J}%x}jfc(Edh8On9PIFq)+xJ1YWTTg3n@ddgbPr}W!#Q=sb`$0v~4Z? zr6UN#WNw{3yt1;P7fQ+(#>}e}cZp6!3Hh+G`>!RyH%?e3TOl8(D=BuMC0_Z`c81;@ z!=YWRzr#LTx5*hKQ0M)%^5w+5F8ddzB?ZEX0L~r;3O~=lJ%S+URKc2GbNQg(db!uC z7wy5dqa$;$U@m_ma<;@(RwrU8V`lhc4c0f#D!J)YZOZNw9?No_i)(2^4L8r{3RLEs zjwo)_8?P1mUe%BzM~4Z~?08@X-$cs?oON!=1I+fzGgmH6o`YWNd2jn-`h^S|hrnVem6D(0C8P+!g)*FfVfnQm*+}_4Ed+^Q$PbmKpZb1; zLejcMt2c{HI3c>i}y#4!9xeNl{`?WmAoqDmg9ycav-1MVmXAGc@;UA?KA1$ z7=JB;6i=k1YJU>-WBJ1LJvo5OVk?;ygf3#t zh}qM69XAk|*S0>loUI4Fl6j&9Ih;sS4czfX=_6@0j>&izV!VQ9O{;~4%Yoh#dFU+t zlGaM?{Y=rxhOmFDh^n7MW)3Z)-=%)TDq;~lJBQN02>uzmf3ZGtltp`_CB}yMslHf= z-wFET!sRJx?#wf@aEM3WwHKV4A@1pLxRYzIl0iycSnk@hUdVGImi%f{dG}xm><4Kz zp+A%T`L|?giH4$X4gKA~Ek)N2*{`zlm348RQ*OAbR^c$H(U(mT09oIP;j1 z$~^cXcz>bq`g!-wwor@9AGMas2%o zYt44mmiVH{{?ayyTzTJ*K*a6Z9gbRD``9C^&4}WD6?sIPAiIx+q39g^J6+`;c3(DR zFtzt{$>6*k?)`dFWWO3nrG%izudsqYG4F#x`qVH!`KsJFPRj0j+@WBGv2NbqNYbeN zMUS4o(zjLQaj|K*k=J~b7vre|>-A>7MK-R#J-mG*&~>;peKOflKHwmLoHOkF^Iq4d&yr=hkFd;35l(JyJk}a zRkL~3TiVW-qgX z#&(65J5W`EXb5=%3HghH)(r`;q};FHFB{OSh&|k2v@E~oi@0qxRW$#oqh4ycWov=d z7>*XI+;=%_g6v`_o=+WX-LD(<(@r?|_ioLqSgo4&D>EVJY{$&FWBCg<$)Btm$13+) z7L}2rvB)vzC#_?aS~A0Z%ndvDT@5;-axLek0;YxWzfQ?K_;qys&u5uVv2oXFjIWFh zmvZWZjdUSx=~(S~5W9borbxQve-#$|v0J0VKyxgk9{ohnR+W&iNk*fxdO_Xde#>uK z$r#aiS?zdi%Q}s_zduq%e(xvJ{K`*OrMJ{@d&<&(PQPqOweY-2u^adM^|SJdlkz67 zf%jDLZqe8E*jM`(0*BsE#I=`cm7OwIuM(QTW&RAdD$h~hF<6bDi@)n%8P_`>FOF{& zr=HhEWz)9DCr?Hj@7t`_V}uvNm3`YXd{@eLAuso64z}EX&Wh;`b=@M;U3}zUO5I7L zKqi-$7_MGI`(zl~r6x;wOP*hErvB#?rrM2vwABd2Qoz$XeA1X2D1nN7*#we9Jj#jT zYsmagwlM?5Otxify`PsHrm~J4jmxRgP$Pvqi3S(zJ<3)droXIKD{g=wZdXM`2+ww= zM-RVu#+shBblURp@_n`iUlmLl1lhjSUIz5KeK7SkgYx8Lacs_qH zOhLMvIm(Jb+7{=BBQmnKsT0LHPR_p1PKSQtzc@@^Tm86S==;><@E9PTWaaB?x-X)# zcvo=4>pYOK$i9`K7Qc66Xo(E6s)!)q3rZh-2Qtqt-$K^@0jt11bLwLl?;S$^e@}7^ z4MQt5!>YYBLn}2MEOq9|fLEiHos;lC;@bVQfTdfjA4ddLzsqM%8rBrqwi21FV|UGpQl8hfl-tPmoGnb{&v2e?xZQ*c)Yhen{d(U&r<>UKQE$>}DK|AL zulnQAq-f_p5(~Daas*KDMr7V_r7ro(mB_YAts;3kby|df7rpEBE{JMYJZ&&4;vKiL zHL|PZikWO_J#yhlKtI4e7NMUmD!jKlQ5rLu3>^Cb*p&t{oR8~F6@RPm-Ny4}rz2gE zVZ6S7JlSF0AB|c{Pon}8I8$8xg~wWV`D5wsSJ{xI@#TZ(zE;My)+dbTp$W&QdfMrp z8`;0Vw)3WhZhBch{nWO)GqL|c=e_&oFYxFe9M@f9dHn9$Hq^yhmT514>zJ>0<<%9n zo_^Ua+uFPKkHs1ZLX@7B{(KYS-9&6Bd=;UW?aI47>6Tn5j~A)O#YSWTHQi)BjA21_~7{H6&HG(j{t+wsK!!_3^Hqf zR9U?{Et<|+5KYPbu+e}$8ltPanev#97Z$9Ml=o=Atb5ryDvmz(-=PL4F4xWw5RtKe z!4DDryX@+Nql1gnsKPhm*+#7*zBl*Duk(Y?%QRjlx|Ha*d=i>NugIZ?@UMo6#de-8 zD;FEL-y2WVj_xs+%tg)7`7_4-OH}k|6~(<}BU(N$o8YtPlFP#Josw;K zM6T{-gL28vzoI6O!xmrWDWR9S)Z1S}UeD?;o-X6;YZnXQx2GVsz}J7CVhsYeB0mvU zm;P9nWxbrj2tQh{4}0%z);8SG)HISihb0XB_XXDgX^5*06dx;Qbdl*HtjjU-G+@~# zxaOrz*U3Gt?^62xJr6$aZl~n;laQC*8?9M}R z=O|9F`NUa=mG5hGxNiyCK`MV!ex5)T5yq4h=Sh^R?z?cl6W%Zwkim>c_3?Q+u-$hj zZ33+8)qf76Z=WbqMV-1x4FsmM>Sqy+CnIHRwpI?pStiGeJ=nxpBl8Mn` zbhE-cEx3qG*(B$~Bdob(X8)tMmT|I7t1|wYJAHRu{Bpb2%&a4!=f4un=CO;;mEz7) zz2wFT|I@!ysW5HXh|31^s5-iQV?~YZI#ZFF^Y>Gi2+W z77-q#N4A0G7Qy_QmD;pc>3DyCXWi{zm;;QQ(XFvap-I@q&Ib{l24gg_WJ-w>wzdrV z^l;H5A!4A|W&eNLJI}ACp6J~x3etP;A_AdEM+oIhfY7@TAP5*DB@lX3dPx97Xadra z-a{uMMI}@L>C#1t(orA+f}%J6*8L0ax^M1U_q>}o=giERS!>Up{X8G!Z|K3F&SbvR z^j|$w$w5X@prQh0x0=I9?xWvV_@o}+sNk`B<{B3=^_lKQv&i3I<{SUw^J{t&1!6-D zz#hP~XTC>^)&XPJcw7_Dg$0+hnhTZMcEP;;{m;_OTV#IYPrqKi!mKzLwg1gRe~stM<%1pj`2%xk*3(DH@j0ArcA`*haqw^0 z`)3V_r=4DU#m5~3l-#ZTs*$I=gXb(o5i!s8_r(Tf3EjU% zEppTG2VnnYVURE`&3ZbIwEsh!OU{>50B+w;Lj~VmFbSxnE``sZOeU#+5AC^gW$EG$ zw=5!xNoLK>RVTBV_&I)J-EQ~qeby+^qyP4Q-Z-4Q?#~c?joaSW%Az0HM60J7JeU|%sw;|-d#JrbYp=2ZQR}VAKzyBoTX@h*> z<`tQt=KX=H#rrFT9iUGBdUZQT$M8V0Dw*W#k|&*o`Y~&U%{D7RZN%HDriX%?Y(0)v zh4D>fJ2tm>Bte6!Zm?w6Cmzd}5Ars`?d041usUY;chIV9$|++X1+rcq{>eNj>asZ# zSd}2s+;S;-GZ}gk(o-bh@7Bk38o#T6Obzh<3t`w87vDM+6p@1b6PpE2_+r+^pc zgXnVYUIX*fPJWh|KDSZ7=*db92!@clZjjJ-s&etMh~$rb{>PY}ck9?Zz$9H`menC5 z9@b<2Bp_DOS)^+=?!APF!gMtU3OJI~YRU|dw|l%xeq1*YI>qhj{dByp<#?Yq^>@am z;~ZAyt=j&7)slSw@)rDW|MM+d!EcM_sy}(ltJdvAKQ4frP<}Yv-ziU&5nTXbbE8i2 zj7dL^x|44;$TKVx3vmiNa(Ra@JHLZ>;+3o(1viizWo*sG(0{CUeIe)-_;-A|a>$3Z ze2Tw&=iwI6W9hv(-JLP<5h<8AU739$U4^RaC%==}nZH^^9kS!L+mWO&+?25L>aXr= z&xzD8>#zCztGP~;)&3JDo?e*ll(}PqISKAx2%Hx=0X=V&+e*lW&fCZP$e}O$Layk3 zgxy`SLFkwH=9-2T6#Z&v0}>}`rl%y5*PkY()V*~JAX_e>ji1C-%c}Zj6|`NXemTHR zWXY%YXbz%D@rm*ERQ@Hv`NWkWznX8hn*UMAqK6NSNeMpb=e(+C$ePkT&@oVh^|?R^ z(>G~8>Gr8(Tl?jp8G=pFlxTI^iuwNQ;I}nF;%Ml+i5HFYpPVz{ITas$pQj$S-{+s4 zwx5BxKg9*kR5%9wYW1RhJme{GEj4%G1>Rd3obovk&--e(zH%r$9{WE_RO@VFLdmJC z;tnEN1~_TUdVl!JPCj3O-D@g;FnT%5d2QB;Ox7iS-1_73eOl7L+f;tGv02PFT;41^6Uiw#vhwz)T1K>P~*X`vZ+*^Lw*WUIzOmh=oGqd_CX=~|6P&W&F6!AEbL2QWpy zk~5xBwS~SckLdDv+S`jiaP@bESApx9Owg`dFe09NqAwtO)Tg zR?b(DXem)VDKR-HG>PA0=;I7eXnyTW{V3OXo+c&r_;vGML}ezEwtbqeoC6zP@Xq*$ z4?!p(*w6BK4SZeF9&`%SvqgYBF0|0OAtyR^vU@@NCnyM1f(41Fk<#DnXww?i+p$h< z6{>q!oa9_}sXn+Badml`#i@!Sdv@$K{CFD0#UN|hT+Mt?ylp%XFdeSd$tZ-h2l<>rE-7O;fv&#i7|!K(%~tK$0Q*X^;YQsSm_aRoPP1!@rJLnN+q%u0L` ztbQo2ug4cOyFgO{hMPjQQ+SpGD;P~Jc|{#yHS@-iwy(TD>5yNycQ+2U#IHFTmlEh_ znnS*?KC`y1L6Bbv(f+L##YNeG?vj1-)Xxd_e{{r}XO>4b^aXr7zQ{JHw2S_U3O&>Y6;TSy?Iz#rFB3>&($m8%~63i9zNA%~|c zSCJpxGm-<$N-vgZs0Gh;RrPBtt1t4X12xk{kg_Ri*P#{_LgSjNvnRFdRkgVyxF(C3 zS|rQWo)@97#PZ=Ik1~qcqhKT=%l!erpDEomT8a_lm#9FN$S9OpBWs!tnc!Nk5*lZx z>$N`YU-0_?c-HC+2J(s{MOVP;RXW1F+qA&P;$T0>?9tv`E7*?AR)IKhwZkwSUlf4Z zs83UZvRj9y0!flvn}1CWsZr}m8J1Q{R<{8UG@HxvXZF)@=5$}qLZ#)vSkOqCh8)Fi zvey?GVnvE6s+s_ADGRk^cO!?z)*?Y5(eAjO2fBTH<*zU=Dj`cVrEJP}wQLaLbGDt* z$#{AJBXuI+=HEI-kq_YuLZ@R@)iMK;*cpfgfK`_#1RIm=V5$u!-|H8gmbIgYT3A=# zsnuNWzz#mIyh{X>-**iFlMF*|R8gS-t_wq<*cnTUnDK{60AmlDywMp{igO~{Suxk{2F2E**s2$GF2y!OaL*K>4Adgf8>)o}b_Kkb;8qfix ziaYwAnMd}2$+9SXo96jR(F6V(8Oq0+BHoz*>>gmCg*^5*$sR&I>~k9;qkv=$@|udD zLG38|_eu8KOg`1%VNa)DOUCu1&NOg4dn*-BBFRu?7#X)S(0P`|$@VJfQRP$^1UaDY z@wMk+o0f$4K{0`sbay%-+@|gGLta-;v$Ak;agmg$et!KB*~`i0yFFfb^2{t;=-2P( z+1)xtCz(~O-scPO)b|{3e-0cF?N?7;h_PsPu&1bc7)4(J#(?+^YK>ou6C)%ajJ!|s zC+kK|mzFiLEi)TIwx3Ak!YXKS@4b2j5|9Jj&fBi##RSKMvob8rad$c%`d^EydnNBd zf&GZRA`P;z$0>BTqJ_l%DOyfnbo#x);U<(^{gNb{vSfGQ98}tj2f_WVztZSrq>Ym- zQF5*#NJ1}t>*{S~L#!X~syvPo%A#~|8q3iwXsAI6ie}uks02!f;3oGaRPpK zCbUx5%34HnP;$fnBo%`3SQmS(^9-`ff}c@iJj-Yq34$cXU9Q_b4-@azZWWfzx`s~i z)@70?w4jHQZg59OH?z7vzJwb0j^9eB?5OCxThtKR)?!JZ>=VOEPIAMWn_twbyUPhV z-uN&|q5;_!9b?_}Kl-ZoNphpq1Apb>iBAeX_f|`}dDtR&cTq5*1eBvP> zo#9ap#_&~1pF%J%B*BXA#_|xQPZ|f~RC=##rV`xU!}TQPwjgCCnN|(IKhvJ#17-NKN2aT~f-D#f+`2EpeU3S* zdo7lR`tX?e@~>K0qjPPmoO=d-BwQAu+f!+a*L=d{aS}_d;25;9t;v6TOndl7Oyyk= z4R-uAr!cS&V|k!vQJHbnGI}q=w*O6o82lx&F&H@{$w&EQ9jG7vi}PSP&+Z$ z9{Hn8;DZiSbwn)i^X1&D7J97>jJ1_(U*HRt<&ao2w zYdTCTR7r^^L#_}d3)mBs)CR=xC%EZ6D5TY;dkuoI zn@`sW;uvhTJ7&_E!RYK{lUcKR)`NjrD-1D;bh`sVgDRLiw41bs))U@0kf7gbTR1cU z;u6zZs&J52o3o}u-};VzdAdLKeKomkyc8qs^7bmph-jO@sx1Fx@L%1XQXHcXH-qef zq^m011t&Z@A(sz9G+~3v8W7Z&HZKjsCSe85;yzR$kr%qRZfTk5V%5>FC@G2(%=EA!-`9%e(>IM7J>>YgaS<^)uwbL0{@z8@xtk2 zh2bb6!ll%d37afJtE-{;WS92f?mJ%5Igf-mXQCMrmlG%ot7hxV%yQH@E>=9 z)o{*iW`dMAj5v&tpzEC8?^)#Nq2|s*c@!d-@Mr2G6t!+dNE1fQN z8Hm_YN5b~{_!hDc-bw`rHV-DWAY_mvq+D+p-w&q4DJe2qZeTXo}q zxZ4Dw48Xxjah-T@di-$_TV=$|lIGedb(`sx0NzQ9)L%+s!~tAj^qW-h`s(w_(ge22 zjoB&lFD$6Mg&?eNPQ;Vm;`0t_oPJ4$`FxbX9RHOV-$oN!$(7@soWSP-j^L8|N?nMxv+BNM-GV@KUREXq8A>_fy)lHpS>8Yq_O!ro|O!Ht(e z@WZ0m-J~-ROu`a|{gzCs-5zRs;zB5@>w07DR07Mb(_ui2avg^Q_+kzC`j2$f#b{x- zrh8c}V=e{jB>PwFeDXy8SIwlLAtg=g;?yX>87IBbO zt52ITRh8;8>sG#Xkzm7S*0%0vQ~VXauy5xLEnxsds;ozixJuO&*zfEE>1Kt0oAlP~ zy=U5t_FVJRNZhYx82G};s;idYf=(aT(BcPXCYoxao-xKZ`0M4|NQJtkOd*)zCiHRw z^CfsribKJE_J!z#3dnV%X2+*rvvQ*$D!B%mOJy3G*%(7@#u-WDhqv&8X0*$B<}b=1 zJ3%`{_R)ABLz*^BOE9}-TDy!XaVB(>UFSecWNy6K7M)JdpNH#bHz=dVhb9@D3l@OH z1a+%;=c75sd+rjGJ!n2~%sk|LzikC6gDe%((*-A6_?cm@ew~LDc{^^EG>;lcC^)$f zhs4{cjWkS%`(#?wGLvJs#)C9)lN7V)$wwG8c=tg=eNT;=Ow7 z#%6j&sqmAY=5(`f;mVJvZbBWxuIzpIO-c}2Gj+XxG8V(90qWEN(;@odADiZfPbiMve-jU4y1^1Cmx%Wb7&CP;_G$^zFn7V(^C+WBp~85&6lMiFuG!g|&j z_Tnr7Lirs(%Xkd6^Rw1cXs>J)SYnt126hpx?H9_+>f7p;!iHDAE~s5M$kxymA6yt< zY$wlU^fR@~VKi0!qv{H}`Qc7CV?}0ud-;cWC1-ZEWO$uSx~Q|1xHUOt6|UO3bg2ZN zLxC&iwZ~}^#R1aHOkU%}>0CulhcLGX3f*j^m|A!s9@vq)mt206ti*5ILe!ZyR$aqn zixmtV$PI&JNnua`aJp_mkl}fChUE(aP*#QxT5@ip*JNG7H$@JW=iRxiuE7MR_tr7G zHQ}cq@pJtEO*A(q;3Iz0uZ$9AD8z>eKsF9L7jm;9PIRf$?pqhsF$*RQmVMNINr78) zgjLm^80<^+$Ey}h8csQ3DY}2Oz$C?bIlWo3#Ltem{w=`+Xw=^HEv{HnvU}M znZ~lnL5F#IQ6Rda^`;`;)+Mou1L_*+dT&>=V6c#09O+mR@?S%E$x|)9Tmw&XZdX2) z!o(^Tt6E9n!MYIkQ0j-Ag8~W4i(1M6P|FTM13h1dK* z;RQDz2oAw$a7|vfw#uOjOP5ymzW<5wZ07jsU%X@QWX@;XHekg35N_8(FE;Etv@2`7 zkl_}BINP2T=cduL?^iqj7SEGY+B6xF*g-EPwADz}GK-F*8IPx3gsib5T+S94YGHh_ zCWQ2j@^=u+3})ecC0vt&nWi;P@&LzTe$es73R&XP2b8n+L~8_Cwrg!}K!yg_SFG<% zKH{L?aFEYE&HEv%1vT0ek}NCr22^Kh#;yk-P&@;!v={%8eqW|qi#+PJ&mBL_1w1$>@~kswXaHpf&mhZ3tLCM~{bOetLU=<-jU+tEr+X z7%Lh20a9#LaPafNVew8DX!gY%`=csol{XFLfWhH4k6VYTV%*tvcq>)g+k08kmfC$N z7`eA-T#eM_)4##*=Vij3B>-JfwJzmiPW{u=_8Rq4f%cxHrR0Vr!&Uns^%8>xm!Q+! zPBfJfs{+zjpGehA9!IkS!_H{vVTp8D&t*fdSh!5xoBbfqN~oQG^GiRLrFTmu*-{E` zZS8-Ivdm;kV@CAcX~Il;kW5RkypdZA-NmMbf4pANwU<_hqf(NV^dy4z6;r!}1iCci z4k?=_t{!aK!V|uOH{+8~i%K?Cq(S1}q2~qI4ezpkofHYqM+p58?jtNnI4yYMpE~D> zSErS#nOh<3Fa;c*G@o3#sfehct;v4NJ;_*EUJoZsJQFt#m=gdBQiL z08G!)+h26?pdy zeL!%O(Q$tF4hi$^=l#313_R%0_s*));_s@)i4LH@e6$c#6nposHX7;4_|w}HL6X`a zH3xH$o3WGGJ1Hv*JL9a{B-3~AF4APbh^ha0f82?XL9CH_`+BvOspNKpQup4kCcqmZ zd^k^3^b^*ny-eVHN%J-QFM&W!T+mbZAyU}ZzCaxxqln|3d%>`zgcMN-dc zS(;9k*Gr+yJ*PHRwkPHMgofs3H}Jcu)n^}7Dk`cM zo>!DU);PHmJ=T~s4d&+voG5WgB=b#MJgMo>nbNANDs4pu?q}-BTvoy$V`M5hdHLtp zm-*H_qy~g~W4yk=uX_)DW_p}{+{WCIVPMc6_;v1+lp_+V@=3`-q;QCcEYBm&dc@;%pyX92P^ya?MJ}azt-wb#=1UOwouK z95Lk(z_;U1I?sdyM-Xmnhr4#1ecO~@TIGlg4*bRSf)PvennyVT;5jILNoXSX0dlYDSV0I|!ct{$PSE{3ABRd5ADrHsH~DwnT;9I7=)?7q890e) z6ZtD$Kv);yk$lI@{rcP8Y_=X)b%FF^N4$;{L?^k?5Ry&K=2GUDc8mqCt;LF_>A90_z z>x?4Ly>S-NP%tki$*KEh=TTKVCBXIgFBzKfT@GM&fUR#8a#R(tHx{Lk%=utz@ z6DqZ0rRyPcISSm#Fz0bTX#zq*vzMoPr$Ky+VbPp4{jBe|ur!~2uJQryenAdCm+5P9 zyLsP4y8Y(w!i}EtswbhJMw?`5N+oXGPc)Ce08cq0?qnG)PIePJYFtp0s?8I&6< zzzJg_Vvqe?$PSAyU$trLP)$nqkIm3o?$hQ8uU!sd;Z6$-_vwEmdjhx2L72Zcitz)B`>dmkoL8DJh=#kjV$oTAlx8q z-QO4R?)>ru*&Ht>*f%D*Nl$RX=kKdAKafr0jS&+Qs|rKcgRgWOfjOB74JD&{!ndsn zo)jKaj&Xd(+RFzk0HR+%2!mn?SAy^1Id1_Tzy28`I9CWGP^=tAO&06-IvY`JUI}bi z4{z`0NYr#cL=NkjnH4rPHs0S2MG-T&xVTKOQ#QrN#20j#=za~1FRzL&@ul-pKC4$h5+_%fCED)? z8dTWm6W!x||1cnG83Zt=K?t7bT#Eg@h5K(BzL_oT*AN-8Pca3TrJuWcxcC`kcA3PpX;B${8t^s9r*F)K>l86#>-(r|w8~@en2Yup|=9M$S3n!!9 z54XHqNssw{WJ*sHce%IA4k99|1>F}cWt5Bl!jNH#P5?dsoq_lCMqmMPa6<=TUO5cF zM?JztB&pA_2Zxrp!}0XtL#LZ7F5Xu>IsOh*8{q|9Lvg&G9vM_nZVD`}6hN~BRTB>$ zsQKAW?DB^M&HGFQi)`7+g(MzHRhZEJJwYRnLn7+~-#{Wg!jNw7(ji@vzZ2OYyexRM>D8 zSeOSr?>ASnVNiha#0MXxHlB-?^Nf))8B6~n?~cS_iR7<-L$}PobBxb)U9xH_lj}9M zB#yr(gnsW(bt8-s=EsTMR@iccxhO%vQ z6Y=7$d-Z(6z2h-fOhFlt0^(U2pKd&!b+5D3_pcDcH;+*n5TSn$_%WWr_cG_{**+7} z_i+hY+jCRU-X3~VM4`%o5)0E3TA>3>VC?XMV!wVC0yG%o4LS}o{ybEximW#{ zkLk6o1D9tqIp8N$t~}XB8l&nAi~@_WPbWYuUyf*#TbvNGky1 zHwk68%y7Xh5`^1cNOtc@uvLwj^v@;p5A$?-9hFZuoV=`e-ilcLEnkBQAcT*8O)5lh z8w3CQvj2atH#;c|F>%>{D#}9iBY$!(E%he!*iPAqa0>p@NvJ|=QDa8PtNzv1eO>7= zk|!Bn7evTqo$v%n?#6=NupZI8k8RbYdf<)+iZw8JYtJ-LB`f9?|3% zU+;!QaNdrECD6t~YGW~J`_==K%I939kj6>p>g(IJ)n&KL-FiK*XLhkUuvTV%@VFH% z(xsIGNAg3o$$s@v(om<-I#KX?R_!H)Rd5*rfD4!xTAsm(WMIyI3U2YLJ9|@Z3x=L! zufqE|zr0$`t;h^W@~qUjv%Z8lAI_GtJFIp5Ek^BC+2!qhKm^Cg8%UGsr*s7gT>jxG z?CM%`m~sBBm~K~)N@vg~!!L=k?=^50N|O~M@_Ikv^l(sIjBQEVq=5=OL#5Z_^7_qs zE6}0+g!}dR>2f0ZO>vYGzNW7~6;&8^^1IAXeB8@)%UX9GB6cg-Y(Fe3-s23vD`xjKQ;o} zTS7ww6qL!TK+J_-Df`+`L+7tu77UWPyP&c|mAUI~({Q6mIs5bzZWko6`pz!d$fxx+ z@~07KO0xFC`y$-v>VRPIoAGb&N&0cX(?7T!sJ&8KJ@H0C3bDbNewnfCk1LDm)4*L@W54oI4QliIagP1M)sK z-!*Dv&*Y6BROMFwO6#Z5xSUP?4nRSO!G)B3qxxWs!3invl{Lh$oR(h*AJ4Rq;S zaqxXSX?Ek=J+7a)d0cbf%QQ5;f2q%Y{^KjMm*H%()xMYI>0w9X6G`*5;&nMzdp~-e z@4nJtr8el8#xnM69_}^Y7~uN^>^=*ji27S-=<{-!{pekg&IB;_4(xVl-AOVyG|%?F zxpeoFCPAySan-J>GR#?$Uab8T^_f+Rxjm?14#qF4e%gXwYVbL4^ww zi?aBXSIK(1S3EAGb>pAQQo_E!t5}Satsxdh1AGg2&SC<&En?jdbJayCxSf6)ztR1^ z{@&zod_ck;wrqpPjy}mn5)WiD+9bdZQ1o8T6{Uze=*Q=L2AvWrGNdVw=6xNv%w#xx zG4|y|aruP7V~V~8H~?!P3X`OdkMUgyhtaH zgU@qixAKA)r!{=`d$6ACuE=LW=d742VYy8)jan>pW+P5>_^9yQf@n7LLwuceXN;4a z91GIYrcyi0uYR6t!~b(~Q{b($@dzyJ=oh;`SV8ta5wwf3@Vd>tR=iV&wn-*ji2iMeD8oqlkXVFtmyNgI3^mF>1{>n@FWQQz;*p%aZf#G{>3b=f&EqJdrbo#Cwu^gFgw@CU2I%h!g zI=n`PSqSO3!neY`=1+yZnRjt;VQcY+t#2tO2H4y$pP@bckU|nh0f2;uP<#!b5JZ8$ zpSzekkP;0r>vJkns$ng~3{V;Ra%sS1Q=!2`n6Jr>F^_T)(_LfFD}2}m?>))iM5KP4 zKk4YC)H{WL1?Na)&v?CXnJ##qDTvHe;*EV^g4(!M^u@B({h(l)ZE|I0 zFt$OZEhGW&<15cZro|D(9DZ11yfz& z01%i@@vv!gHqkbcWZpoO;E)6Ph8Os?L8J2$TNT@iMEPKnUb6#Q%OnEx#s*@mLpD!K z%E}jk&he8ZG}rort)lQo55fdd+rGx$C;{In0kZOxk-AFk zxK;^QM<^6$NTEGL%9_J$ne%LVZSjIIl)J|VFtArA%jUhQ|3FW5fxI8^Og#wQYMnWY zr^1JBc$@xC?jQ*J8{c!9tKG+sLQ$F`dK+6qF&kiVi*XXe9g!Q*%KIRyrIq~ZkXQ4F zFf@MT&K8mDuQTcX6aJizsnM0m>Tbbg)xCCb22UDBV69Q{hMzV+x)K|_C;n_Hf+m5qL6&*)DUcditf1-ieht5jo|%LR?~bXyl1W{s+9 znhr3vgerbb&fk!^!}tMLUjxzwlrjjHdCagaEKgQ8dhHvAj#oq4_>oOn*$Y0VNs3pu zpYnHmaFnZ6>o&?g$hD;tfLrU^4V(gNh~h){t>+I~ZkBAG5$9WjCTNrnnE<_WgIl!b zBuE2ZQ-j~khIwUinRF>}4M4FO?z^c@PZvXAs63|9GV*R*@p(L9w_D;INp6YisXC2n zNV*IQ(t3Wy&qrG{10;dWtQr%NH3vvMC&l1oxuGJ0o@d4J7nEy|Hj2A4Ps&{6qUK%y zz7cu3i0+DlNNy=eGn*06{^>ME)*S7+A9L{03wj55-k09l3};CKvvjY7_jR~m7IbwP zc0t$5hm&wzmLzBsRP-?%O?+W#>F_n0fU8W)>u?R;;j}2Ka-94$MDaC?N+j-DU@i6o zO%_&rcR_&y{WLr$lxR%tnLa;U3y%q$b*O1p8#2|Kk3k+^kGfyLdoH~J2tGXq5cxYx z-av?f@AGwO3*BQlOV|F<7jPJMhjAY)fMz*FYirw=_IJN@*YF4T0%5)&R^SGgK_G0r zDd!n_(rqBF;rV0!&buZ|+}HB*a&Mj97Ot#)KIBkmEqtjse0Je|J%>(>H`NfxyX}v} z98;=R>;e3D*}ncf-Y!y8aX*d{EhF@NHPaa-&(px1X_KF8mKjl%MHw%3npszn-{8h2 z&p%7-`1*Y7snuteY_L01q<`okN?MzTVfrt0qvLY?a*(P3I)pxsZM1)xM1cN9pk-4Sbv z^jH2TgF0{29NJh=^`yq|Dv%Ly;b7uVV+qQY1`yFL^+`jp3!HHS917_UD)vOGTO?64 zz0v@UJ-56(!Ki&;*v;E=qvugyk*x@h4&RiZU>g6y!9n#dj5dMO77DXQ61Np#m#wWt z1#Pu%XNxyFTR_?t#!Cw?-%E1$lNr6zq59TGMs=6ql7EKIV_YvhK=dTe5~EMXRK#|I zjS99iKS(_G$<||jL(!Sqo*daY0IGMroizNiqzNbNk-38cK8=lKDp@X8@%XlxZr$uz z0~qdP(Me^*iI0poLwn16qKC z0z^#@jLD=1kjW(AXLZ4epd-p8ei5ex9vc@$zDL8Qb*;=c7OWiag9d!$3 zon4=h_&r_p!^(``yTMR5Vd6OSg};(pA(vXWG~86BY})vrVJex!O8_{&bkX3{{&yml zAYQ`^&kyu+OCSAIF%2j_tDp3 z18H{ZpMcz)oL6N?n}23oN*xH%4OZ|EnN{w*p`5hP#|Dncee_Gy;Fn9;7T#_b84HWz z(0VpneD=QMuFK4`J3{POSbP0`z9k@DpfqG3owGBwwH6FsuO|PPM&^uo8W}zIk{01a z93ba%FVoE=r>K*Oh3VBD@wLZfz=?X|F8X~lEX+-*vNt`IVSuRsjtf5zoQq7plmR-; z(9<@Jh-^9>!N-e#ebn8QR}>9G)hl@k14XZ1=MJA@3SI% z!a5I$e<^7#PEBnDy96e2N}Pztjt7?2#j@vh7(RSx`_bZ3Rd)UW0Sm=lx`k%R)B|AnKji!;#CxiE*TsGfYp%RN1| zR_^TY#mc`c^E5oE!ZN)T+Zu(t4T9bQJT@f$587k!oK;avOS(`hEZ}+^Gde2AG8x47 zx8^{qK1Y)?dPtBy9h;kXGD>Vb-36K87e3}b%R zS(OGI%3&iAkIy9+Cib2WU?onXsFlc5FJIg%NU1a4#vro2-hX3DpR+}#vLylmRFD)a z_r7M#AT%g-CD=pmY?qydx^DHN7YV~b7m~MbmGp$*2!E`J7$p@>8DSP~oB6Ms~*jt+y$ zgpq!|N$Tmh4Kc1(!M2_^)&aZoNALGH-(gPICYHzPNcYHP5*|cywL8#|xs4@zq<|8S z0#h>YOkws!%ewd=yahjZvUlq|koiKa=wb5tU^6V7V%<6Zs1+RCm65GqJ)&R+zFygN zJ~M0A{ErZHqi!%++1MPJ6FHCtU=!Mhn+vbj8pA%O+qy?0VPc2rZ$>PyCvR~WGysiV zjJhOVAS22tK5Za~A_w!c{!w|#4ud9ttKn;FoN^XNpsBp`}98XM2lB=bGG9l);u+NILZw62w%9k|dTG}vCOiAbx0=0{f z-D>inf~WuwOY(3m5qdACB-n%yK0W3<#-$G0>6z_}VnZHm!oROBHL9wpkR{H|v0H6Y zrm`C6{aJezEiJE3e)(5goE2xc+%y8!1nfcWZ{%XB!RkMO;^_YXg%xwm%hHhqiH+mP zef#efXU)nHbHDkGYh)}hEpJ~h;DRF;UKCDSk9-UA+BD_B^ac6(21~kWtImE%GgEZe z6w-3CR-qZ7X*#Eib$xoM9`23+Er$)*HLvc9Ea*E&X869`*BYbmRr_3*J3-kSvVhn3$$pyx|ICtt}*ZY^`FZOr^ja%Hzoc;f6`wcPqF%DXl}`mwL1q3@(ZSZGG?S zxi#_#Ou`!!3-rxTNH|wZL1xb*%08-9P_5Vc1OX4QM*P9*yVk?PmF8b_>V4YPlmC7h zgyM9fTpbsA#3N&678&6r-fpLt4{~#nX|B)7>|tzdY^>W$kcI5l?M$!D@AkK7HrcLF z-mbi?vrn}O6A(6oed=!#>C|pw#8WveqMU0hBCylTtJ>tC>WP?PC1iGUAiOhtJLeZ_ znD@5D`t$Aj*_P;j6tun@RH!gs(WTUT`ezH? zSa?6Bp>P%L1^$_k3H&mphF-hVeza)Qc8pI;!w1SGY!AwYZiq zO!M%QX22d1an4$5mwyrhztYs@|_96sBliD%AJO>J{)(>`+db~e}5nNyz zZczi?z?F#RmY8GLO=I;4wwC@zA1TTD!+di`h!s(Ra>q7;rR|&NbpK<7;^KVR1>ZZ^J{vH?0a3J^fUu`=uIxDZx^>7mCwv>l{l1+h?$zBs;kVE9bAY`XoUli!kuv_w#lu$1Svws zJqh)LjT>#3<{8JsDU=1hx`~{&YuQb!z0Jm!ZoR;qHrd{V=v{XMEFONlyI(~82-DKh z*-$>E5hmE>N(QH7K>K-NB3!m^4B(do8j*WhdLsXyb2!&-6t)3@)m}RcbYLuWi)pXB zjbOEl7#`t}N<=I1@D}(P?E`;L`6PBy7-Pnbj)=WBG)>XY_oi_2wHE zY>ulp^(cfpb5t31udQS1tNrFW2fSVY>b{SB=G%^uP&FnbAn^Kyi*1+hOWP(Y0x5>e zC zXr^+wWUSowBSHQ$RD)ZlT#Sy^M8+MfQ$6L4HpI7s zq$|`J8!lPL+xia?$&j=EgSk?_(FZ5s6Fob|J= zF@(}5zY$AIhPTLSIsBuACnhg)A%Kg-CeMyWONYemo#TxTyXV#BDm4gOev|;x5M5U* zi)i;vIg$VCC%zFV(W8j4p_N#lFnXRdx?U<$CWChx9^+X*HUNN=Stjsk@}fUQHI6l2 zLJ6WrGrS3)O(`ThYR~0p{(c?mYR5o1o{Cg7$%*glg733d^^e7>N8rf$Mhev3=`EJX zsy)8G>rqnK+x%hP?b0gy2Cy_Q`3N8gp#p|86vQ1GWvQ*DijLt1O({!%Hn z4^2ql{KPFsA&uQYO7XA6U{pG#=R^wKp3lDa{qLSfxzccR1-nF$D`+Gy8E5!Ls=u<| zmzzJ<=d9DM5FOpT9~ns=5Ihrk{MK3TKsj10bTM4l^U$8i^;KO3Eb7CBh*QtL662!5 zNbn=#Qo1jo^+MaHe-P21oD)wI1BmKifrs1A`W58MBQ`CxTFDbu% z1cv>l^AQSzOe;Z^A08&Y4Ly_NrZ>(+_Y*^W^)&WSrM9 z6tT_w@oMKC;e|~`JMU5_yas*IvRxgcNn4J$)+m+XMW9^*l=gIs-1VS6z@`rd@#dq* z3zOcgKd#+Ay?Qlcr{^JD%~ztF7L4EGe12G2TB2tWeh#?hadUO$V`%HUPZTI_ZEX5a6k%}T=!K6`4ijNllVx8%|KDD;H-6G#)ySDl9 zH84xzlE2V7xI(9S{=SB=5WS{9%je-B;fxQpVhPHRm)Be_1_>SR!jr>k?P+znq3!$r zcZ#aZ&nmNMxO_aYRwdQRQWBScUb}PySH6dcxL{*51Vq>!97YRn3G9j37kd3m;RVjx zE%pl=@Q%}=NL?Yo(K3kla*2JA7BWBlLnKFP>$dLQd@Gg>JuRJ|RKS|Y5fe+mqUcW> zYwM00>mkxE>n{&#*$)Z0>Q{cRAWoCxf9$zy7`|QQA;C35hnLhO6}}Kz{r>1-iWP53 z!gtTv6HO*+oPIA*h;h)LdOMjJxV%cmkkmzI2RxT>^6(T_s4;#QR&mriZg=nkV8DRc`f~wN z?g4?ahhD?DCnvhM{sXV(9o2V)hWc(rD;)0!FSa6bS-MwIuiOpY$g^LIEg;V76^WK6!incd$5YiYgyHrh0J;_PkT=&(GMI3w#^v8;70zjAgzk^CVJ`ZQtQ4BYZ)y?K59S|&X!_sKq7m2tHYBEs`3 zr>iSqCau>TL85ZHLP*69Ze`jfaV=>OxF%LnqZ$GLV-&Kv)yh_CBT>?~Q}>LL3K`bk zLN~(!Q`btfnUmG}RIg{J#ZM?4tzG(2DV`Nx2R7?T7>$iWr&x3s(bsSQ&SFarnZggo zyZQN)b%Eh+Vh{cgnU4g@`i6Bn6S7ol&olVg+@yi?%Z@O9ef+|A|9-hGCZB$aSAape zs|`(l4q*q9CQWU4AzSqS?p=@M#l)$d8%$B+?K0*2@HplF7N;^?vFgC^*xcG7&}TcQ zLFvy>A>HOUJ|>bG1tZn_AvNV_F&pg~pcJmX>hBsU=yYxpTRD@jOs_F%U{kHNN#&re zd8XL{nbv{^aZ-h=*6vG_M@yFI@r@djZ5JEFtVi3-^yJekmTDvqZx~{QsH0+o2JKW; zPd8nv;>MN*wi_j@WiF$nL`2{;Ie~6`erpZx@d_ENDi87c4tFMq5>11ogg|%vio8VS zP8?l_K7;_q)%-R@Q>>?%R72IC-Z^8(pWqL%yH*ShWe2kombGc`*-!@(yaKyU_gRHD zH?7dhQyczDn^sz(`>^UwenPs6qY8I*g(UvyId;r+cj&%vYiPVx$WxE{A#mGo=&9st zANg6Qy;FWPqtKvvuS->DjxI7%;CnC0cnAwHGjPX6RaHPvYBn-Cc}<^;;}(y_QvvU6 zow1_ah3UEIWO{a%9=xW@h)Jy&%br}7%{BVWGJEzNuMc|#Ay=LZ*YVcuL+;M6cb7pX z{5I()2RA#@@1-f?n4=V`%h6yFarP_qnveAl3un&fyLh=B@F(b`P9Zc1!e)jm{aYS|fVkBrv`- z3GH$-*GRh_POIUztIqA3wFnXkaoAdbYbX~NS16lTuEbo0xoL??ji|$NQ=ILi@6zBwQ@LdtP0nB9lZ_r z_4*?e)Ed7sPrJjsRyCe^`PH;c05^=O)eLWh64y<}Xg}P>yhi0boL3YLCi2ybW9dGHdfbnA1biCocXRGCQ(L=ObDGWN^d>MvRsH!|vC);LyZj7lDRVmM z$+-1U=M;x{O~2dMq{I|)!XUN=TJ0Ptrh*Ad}b9$Bg5q-V3GgH}gfQHhCX96{_<7v(g_+fe2@$id( zaoX9$u$c}H&ku6dWrjv%{NyK2+Ogr04aS_+TmWkCG%@M5d~xllmz2^{zl6z4(9)3E z3vo*I8s@|o@M!?GL@sB(x{n2osjAFhmi^F>Of{k|H=e=SdtBS7xYnIoKww}{gi#7YVRg}plcF5?e&D{GV!j2>!B`a`6vo-?;g z5`#)a6f?Igdgf#NU#Z)F+^krHMWnJ0KGy3Q(EKxqW;yTL4-0cDtz>p1*QaJu=-6hw zaw*rce9gHPUs$+Z|1ZPS{>%T9$2ghv4e0YG#ah=~bd}}bj*-Vgy(RvFj)p(oOxhxO zsy@&EIO@E1=&jajCFC+6O%69^ByXw`qJ%O+0Bkx^V;TRpY+Z$Sn=>39ZltqfAC|03 z9p^9L_a>?s8Qg~EJi^_tA%%47JblO3om@~<#|DDl;PP^t@6kf$Km693T*5i+)=xh* z6cjAq=e8I0>C9bIlzsoM(V8uI5Q=LUw~)*TOmYmLjliRezfGf>K^0bzQvNG3DhD?6 zG|h*4LhSCIJBX!@nZAwVy3Ee6LyBZJpR-w7i{rGu55=UuopH8thBz7%u) z`Lw3JJx1#t*eF73Z)k9GRIs(pruXuo>I#L4NqK+Zp8evLZp9bpr>WByI`{O^DV|H3 z5f@^E9e#XqDRfp#7`baBCF+|9v5*rQUM3Gq`17gj zWhcqxMvKN!N5ld2fcWNo5O?(p`Fhcp2al+(1@k22&A z5!tgGgRSvYb^Oo8vpY_DTigz{u6%y>R;DCTh$3?bevbfBZ^`6Ezey(1E&s2Z=3hZ& zUq1eH%zgA*ClDTI>QOLI=$0XXr>HJrUxZp-K^qtp!f8^LxxrQe0r#jDXkb@;?VFm2 zgHf@r;pny>cLmNp=t0NEUVQGugOdwr~Jd7wP+{cMH;MUON2JRM(Lc-Dm zo6mQtR?O8071M&wd<{c`t29Pmht4Bb+v~j3b&_LO;@C>Xadwtu70jYxD+_P^BE@uO z?@!@(g~^7H`fqQk1v-oY@18Q&W8bsR+wC_bmN#G#eDseJS@XOFxb?)Q;5yz>{TA%E z7S=10_|%VYJVZ{7+^euhjd^0)6Ni&GCY&@cUh{Y2%XYuAu%lLta_@OIX9_Vg8QNu} zd;kc;&>-G!qc_kH{(b`Z=TuVAc=0{PcNp(}(AHq2kGSvVy7Pq4^9wX%Gu4_(-=X)t z-P6PU`Fi1brCplDeVf^N?d9dR`}U${1#3rWGlb&FNzxXnIF6DT0^nI^y;7jli_^Vi zTFvN6$cEIF^qi*MF0gKXBX1R_4GWjJ2P3^Ub8^`w7Xy6t4>JYw`>ot$t(pP!!8J*V zAopybvrW2!E00lX`vya~jrShFoIQ!d*}Z|2=W%>s6vDpP_MsWp0nc?5o+j-0$l4)3 zKZ?%~Rpd#AjylAoB?`bJ#3Mrb-8%Eo8ucz5BgYZOssE$cb9?urfI}hqAwLiE1sQ1w z>rppG(7nA5YPc0P2JoX$27l}ohMXqXJfD5)Hj%NG7EQg`h4$Y&)fZU#^9Q4+Y0FCzZd`Bi zP8cuRVkx}#^0G0i3nerw*BMWkBFA0GogRjSsc?-R(53+aJbXSTGPktR-`Lc&_UZrq z2qGre-%u5NlCDAL=q>qrDPmxe-v$pVH2uVexXKtXlNdXb7$`{MGOMz77%5KSk4^aC zF+$^xWI$o8W5s!wRb{Wu*`PhoxC4#kkmt7d^)KQbV$Jz$R^9t9fN2-r-`t%!#PIJK zt?K&B!$wRVEI#V8l1^fV`*@&9JR=F8=dMaN7pUj_ zDOql%7uGf$Q>`%}(NYJlPC_YLcXm~5Q86PjSE(DGQ~%z#Dy}_RP~XRQOWEw@5-Afg zv3*>8VPj#A$rR6JBcXYvm3I`(kP+SXM{mw-JbCeS1?s?Xu`h*66l0#&HkwUOu29um zC?q+Hykg(?LfsKrKNY+wCFTtwzc zsT1z&&T4Amwrh2gqw?U@NIvnh4Bluwz9kp*sB;^FBtChkfMvr2ePWHB#PR)85V6_T zjswf9#r;Vi3yoaHdoT(Q96;1@|4v-tpubNt52kFU&YG8aH3p#{$?wa`9661!Pw-Jy zA%&ol_rDgpJXRx?3+sHbm-E>8JrMB^6<+QcFdHY#U7-sIZsX#14=GQfvpy*^v_AH` zTo`Mgc@GYVRuHI=(oqb(w7$$n4-k=IFw!pA#U9r^ARnd>boqnM9&U05_$lmRz}I2LCMs@J^G(5sF>5kXazlpW1uc0F%Pl9Uk0;MXBKK4y40lf zDXVOqa$|ErT}w(y-??R|PfLsXe`H_&-+EGl6CF&n(9K`wWmJJ z&sq!=RF6Q%V))pgIX5M&0e>H8gsQNuZ3&4z8`><6D)OvSdVf-R=|S`Pw?);3#M~kZ zy%0f!lC?R;&}@&g&L8aw_~WHU8#4$r>Hj&4&)K~C90dhsdU|^EHrVmcFEnA=WPPU* zW*puPK4uT(WzjxNIAd%(-eI_*>6CtA++8w3;fP<}57}FE$s~Ye5ftULg6i{hM}UHwa=et=@KIj4iM(3dUh@$)AJW8uEDskZqiOy7pAh+O%_ zW@1%R?Y1EjPuuGBXJ{}g2Aa{;X>wR+?uJ@7Pq#5|vp7l221`eI!NCBZzeXu5SpD)T z&_L8f%Uk$NS@^!d;hi|ikALr9jaXL7tGkw7_h8AQE}+7}TjYL3dAlS(3IdFkZiM9L zIYaF*Xh@5}3vW}q=9?J(3Ut_s6guz&d2~DeyFnNafjDJLLx!ZmR}e4@n5lVXb7nh; zsxvAI6+kl-Q#@C$1vYS7O>D~zjc(f%*mwiL;lWNZFT=4Eo{7nVP%>QE_0q_!9#SH) zS@dL^f2v+UN3pDd)qB|^Y=*Yh%*C9===5!AGC``N z{{EnOYph-%M<#UM?FCk18~qN<-2UfGOFppWdN*Wi#d+fTwY3GBL`n~Svsvk;S}(^1 zJWnW$ocG4B*Y79B@a#B;p(&`O*NI61v5 zxU)Gi(U`>{)@F=Pt(dlbM5&|?FM+=|mcHlvdehu}a^3$MXsm;7OOUVZ`!Mrzo5E(Q zI^=X}*?=zJTN8bRz-y$hJlndfa+C!^7yYDye5sr@47cD4ZxyhY+JO-yrFMzB!6hr) zKq3xKJ2NI}dFgvPy4YU-;;|0}^Sl1Y0AdXP^H^O;C6)(J&1(e5xQv09{5T8G-a1#}CG-P87GF0;Hyftj4naEh%WduLsmnA*InH32xB&Nj^Yz^yA7u zvfM{ld8J#^#K0YKbz025U(SSfKl6Z6glvKAB}fur47fdUz}CHp*(laxotb z`;crKE>7CnIBq|Z2Q0;$Iq7oJtd)Nrrf+WS?Q5-VULMA08u1OqUd2Kj(&%Ymk_|P3 z0TTfu#8wl;ziH1uJzM;7bIb)xzU`@Orx?eCcD^;o1*bE#PYN?vHMW=k?DSMAP)%i* z$RyO_vn2#@x={S?@co4627qE)AbOq+MWVY44YY8uDZRN`k1P>JR@a~&h z=c003c63e+QRO-f|({CQfJg1j#z4NCCkFF;5jcJVx0ra>+X2PT2Y#dV`tewD26 zSQ?jbR_DzU!_J_L8|o%RdevHoH>&RZFFDc1>1RiHa(UacB)?bt*ZFY1}}Ppx)F6Ctx|%7ybVluS4ALoqEU##zOR>ARN_ zUF>u3-H|S_{cWHVPN;Fv(%Yg%V7u4S!a0m81uWX=Et%>9eU@DyFA?&%Y6+p6#bzAXqfiC(AhBW zEZHri*J~s1v;t+X)I%m_wDauO`|Qp`#mgcq%T;1vKgQ~KcQ#_5L)3=Ib@4UW;gGAs z^d?^V@nn>=O}TY z_+GHhiQ`ZvrbHB-hsWcG0+#*nNo;h*U%Wuv^L>4I_$qEn#60o*&)DP;(X<5vH-n|S zSz^B&I#7!$jq!_%UIUO!u{Rbj(9!r=#dZEf?SIks)k(VldH(0d)yD7h`V!$FSp;-SRV_y+im5UX^%d06_ z?)I696cPF0={jHJrjHRK+-KpPWh&b8$rl#_H)=VxIBuj8B!N$uC#$_VIWEWm%IbRX z9q$aglBT8)BlQ7C11e?>yFquTG>mVk95s&mPWj7Yxhdc= zEL_t{1ZlLd9wVB44a39|HuA=)GsPzChLKD8NKvEJ1H$`WGi*e(z+d+@qhBshnn52y zk0X<8fNdu%gvZ%ey%Y-TtdQ8|v^=qIv_Snh;aH?Z*5FYklt$QlYWxQ-*}zTmlM@z& z^nt&x7Z{Vx_M?!Z=MAoH72t@N(QSZOGwdc!LU!S@cs}(RUF2dbhVK#FN(I0gjY;X5 z%lC`ytb5`tf0*`dlEmqbR|1-scFrh_hetbZxYV1WO{NSoPTgNvyBovpS(I^F`+1FoXf16pk{>7ug~3!pdbk4B!3B-RrF)4#_jBC33@ z8Axh4fiAn*IoI#ADNd7RaULB0rytJa?V z{GRM_)z`^_9n%iiu~S7PBwj{FcOUey%>z3zb5-9LU$ zCW*)kIKyMvXBA!EL4I6Mw6GZ=D`d}`CqEy|4adSuAk9ReK-}tD3If&=JSI0nbAry% zB_GgC8Y-4nX|{JqT;A=y&l8DIvP^!+i3;7vtA4vg>TF9OftwQg%0$UL=0;iECqMs- z_tAydup%C0cWt^IWJHj(U?U8;r2%Nl?&hm}_o;q}vl*`LJp(ti-oH4eB-bVpLUbs2%#rc&@u{7fnwmqIL1Z7Uc1N&ZU*-3&HJWZ4 zUtV&Tc_Y5|j^6M5Bx-7E)UR84Yl0udD4N-`angxrNlvdG)s?o#kM5JW5{Y9}{2<}# zJPx!E*oZv}MPr;9I%Ky&OrG{7ta0kYRe?8y$Bq+RZ+!_@vx?*TX1vP!_F#5QwafQ8 zv-xM3m$I0C1sOG<571j2S-Vf$Enin1{21&ShjhvZ>Mi-9{r(Evw2ZGtZ+TYTB*KMm zwK$>`I#|Os4cvPSVFAl$cq;gEfX@qYh~xDx%z6Q;<`^j`V})6Ev(|0(sBQnu@hEbg ziP6J~$*)Wy&rkXxOVl9g!>8pjyGzvJg_5akOLt6Mef)?uL@Z_2aMN6T;f+c!+A@Re z{mynHlMHvM)PdqzFFg_v@UF$bxEEI2pIYaMJp=c?gQK7(O7e-BZwwfY-+_V)Bg!m! zhPR+g-qCSNWD<}xNxX%91SGT}&Wu%Gu;8OP5cgRlU-d^Tz>1&VbQNI2%RTt?aMhfa z=wt}MM^;1t^oiOMKC9k5lb(|gXZYIFE|2hUOm7*Hb!KF8kr%#GV2^P$8i=j(qQdJk zTcW+9*zj~m9nPDj`TJqi`_{rBYX|fz_EAxIGB>wGt1?SdoAcDk`MqX2rL|dm?+86> zd6_R1>SuCu4{o?y_4Ilus6J1XPh`*3Y}DWSU4)N@UrKzKw3VeCZw^*zAgi}tc;9@M z=DK=tlVVTg0_-VQMn*>dWiQ>2a+J6K^C;)#LVbCC=lYv7?8jU4ZJp0I&u2dEe*tyX zac!F0g7*m5oRiE@pYY)O5tIi=JhdR5P9Xb>k(c@M#vQv*smzvF$Vcty=6e%zjA~Ns zAYmdImfrIVLrv{q&#$IjcqKHodFPIwd@+}_IB4`3;y7o^4bMu&I^VM$RKruv635Kt zSHowkIURmf5MAYE9sabY?HY+&?R;~*fAM%9P8&=th7Um_Uy|tm6wh)26SI-;_$jwo z6RtSTOG{H!*cqw3p+$PAysuhby{((&t0fG~B)!MAmV|jfL(W+03QrSZTHR^q z0{l%Z(9Y{fw{T7GtU<($YWuVKU@YS$Q1t)Jmp~H%gu!cTm+O8Q9-3rI&<4B;%K`eo zm5WGSwF5qzf0}Y50zLho8`@==41bLMKG~vZ1vJl(Hr;^IQ}1QF_?yMnEl`gJt|DD~5$0iz7t6;#rlnA{8v1nb(95PEMAeev4ogHW z6bLR%bU;PJuqVApkrusDT0j!8n9TWV;+ui3(KWH2dlW%53ViB9Eg|>DPNV@>`RiAT zjL!u%1W|lGxZvCKW&)~a`KT$WxPGdJm~{i=MM5i|m# z4xuq_;aF{Amcgtw=pExCcwD6ejT|A=w=5iLU$7JQ%^yaAK*zGyA8S`lk&ib2K08h6 zfGn=7#wqu#fL5t1lQm|4aIuLsgVi{+Ai%g_O@d>?lhdb%#!^UTqcFfh@~Y@Nwx~We z2YE%J#9c`ECZeVbg3zAPJHqJlBe=JNQn8=V7^Nb`-=f#|k>)R56FAE-OsrvskM_qK z`eQL^z~NO6J2C$yG?MbRSK9xJ(w)hgDxX#uOV8XMAK{RJ-7RC{OEHCs84vEBS+F-# zZaFM1)(k4vrgl-O6g_uRw_6tKAqV4;~%Y(86a{lK00o*q! z{T)KC(!KJY<()WWTry&$X513deMDwh{ZE$d``?oD`4VvM(GcuCr@kPH(dl4s2eF`w zfIUGRGtyO=EzG?s&5#`rF~R9*sc(}vnQ!pEo0qWbAVsNW>Q{Xaj(9h(sKxx1*+!~V z9t~gW?rMN;++R#)&>e3FhoMf!8CI{5*M&>!IRM zAcGots?w#TPLACv)D5UTjxd|VH$Yq@Wr4gCQGG=ds61WtLj$HeW+i!;{y&LvUElEJ zgpl&MaQkj)k*WqV_%q3wh)H{uAv!skg2rVWO3=bnxUAyW6v2#*fVM07@rp=|=|?5a@`DmHz4z7J*omre1!8lOP7wEvC>!aKog8VSy zJ0xnRspv=!D4Mp@rCSNMDyDkG9?VJXB?_HKyoOzgFh)XkdYUlanxzZlD*tG6^sYG; zov%3F_Vb!1-)L0iYhz2x=<)@25G{aH0_9R{?+AIoG|uvdZ?DO%@UaFf030zQO?iPU zz~+bRg=OxF?JTwZUigFXVu!RuEMpsZ>H|E)F;%%YE<4gBY?*QX*DU%^@J3>r9=LJ2 zAfOD^Kt4J)q2tT@ZoIl~<6DfylKAr9$NKtPh&&N4Uq9<+mehFAvg}psZ!qm5kchM zH$7EXN>}sED0kueVs{ev?I?p(?IeFV^(1TIru8CVYp0xNj>pL)LDACmCYN;$eb}YX zmDx<=eB9J&b9|>%t652NY`wkgxWsDdph{DIwfyLP6?9-F`)KW;>a(S9HPIJD=$niE zUpXKUN1;f2m-8ji7U>lQAp^P3+Gnq+*@vF_9OrC9yC_?~_MMo(X^@lJ-%Z##gV1t&Hw6ox_dSF(a2N zHG{e6q0*rIT9Nut5ozgUh&ao`WJO&8DQaTFffb%I$7KGFmVaR2vS8{BXQdBXnnmVB zHKAZA68&_W6fP?5xPGXN`J=?_7K;uWk(p|s0PSR1A`)u=0MU)=4na8onXCj2QCm6} zLu7hzCPuf#Gkw2pBgNNnBX(!bel#8Uz5$?~goP7e*QF2Jz610EEjePt6j z{X8RQ-~^TyeE#ri{*zv-M0zbn{@cbt)#-ugL_fc|W?(?^JgMoGS__sE8ks8IPbT&bb3Wv}rQfDv1z$kJlM^FVi<&`kC$M8hh&yAp6*M?0V zrnr5W@`Z13C%wJWA{^d%aNm;fo7jp|*~gsn+&*R)&D0k@lgi0aaDX{WCzt?)AOJ#lYrxKBqTtjE0o(w-Qv{S94^=_5v z6=9Iu(jr(3<-I5878Ml243x62q?wT^@2g0IXV$yW+cGBZvvh;XO-*k}hm#!Ksmx6@ zaIxi(Du^tT?WQzv+b$=Dh%^xiY;ds|d60B*kNmyA*m@SOt9$|8Qmym|`(=hXOlj6H z*{@%}%4%yT;cquO?s~!UThF}4f=rT_DGc<7B5BLC$gF_Dg}2C(Yz(+B znDc^advW}m!WyWLR8>=R?@kD4KzfsRI(4D(^aHXSu)aO25}~Mxv{z+?Z<8;kfMmE0 z=a-||Qn}LT(Y7VK_Lb1z$c(n{CQU^CB4(>KuL7-4ZyVWJUm6nUPVY@RRM7gW80P@} zL8J(5Y%d1Lj2Oz|zNytYfi=vLmX_9*>VdjJ?tO2Rj=q;}I>u{o^p^K-*20>gQ4I$l z0T1_Afujg@Jmj7IJ0>mlM!`*EI1vC{<&A42D*FKCf)<>o)xtPG6ap_=Kd1T?v7}4@ zk^);fciy1KYoK|C-ZA(OD2&qi(O+DboBSXLIiF)xO~oPm1nL`-unWB(_Wro&s|22J ziv<8?M-kW#_1EDfn+u{%8AU(DlOUZ;>DjRjbEaa#qmR=*aIxnx62M?T8JVD{X=>Xo;D9SWi z*X#DR3hsTkLHF|1=P{?mowXAwtDXH z+~_26g4xDY)?l1)av$~zUU^9$qZhsij$PV3d-->!mge&gP6+{#Jf0qp=|Q>$lM(iV z9s_=qYC7*C7o_x~gl)cy4t&Q`~A_c{CgP4;!Z95~z8ewZpXq+w3I=UW8_SaH@gdtbyj4roW-cY`O za02)E{-s_~ZtxW?{UIeFCUGG(jQJfl>bWue?HIjvS$7X1_wU9|j)@KbR81lVqGI#Z z4PLj`flEOQ?OPt|%`gVXYH2(0N_kf+G9iAmKo6lfD9{=vHbV3!D6yw!AtAikoEoQI zL>G`mf6w2C88H#zVTf2f2vo1c2t|?eENE{K)eiC#Rgne*N)DWeEELXj2(b%Mp5N%7 zOvOyw)D9RJ8@5aWY0v@wD|#?cg|{v%~>kz8>u^L{)}@?ij@!MEp~^1ah=c+Je7X?qRkP zk%;6Y*?IYYvq6$q)cpZ;s>rHbOX9hR9!0!q?q+-)71=DKr0l)-c9cxsq^U*8If1Q5Cl$O5 zsdFrb-+9yvroTPFJQfyQL+aw_E_J8zL1g&bb>CUjS4YJTa(@odL+8W{z`8S+=spIDg+Ys-7f$mERq<0!=En8bERAZ>9W3qJy{+q7A zM&dvbXu}+h1eVuM-Mo@is9nr`WiLccifNA02eB8RK(w^u6src{yiMhIw*2tY7@lJv zvGY&lArlo+5+eK;f|5zaLVH^1cg;Y5Bd?9ik{-`@RC9>d1h zXc;(4qm*!C#H$3P5|vA(BzwLBCPd7SdN9-2Xehs=glEvi)6PjVX}vnlAE!BPGVvHd z6tOx%DwJcmmw9QB95KD_u0~`QojR;Q@T$|4!ar~%of5wFToit6gyUG{G;Uhdp(@o_ zrsn{Am|I8_U8auF!|7Dtb;EPgt!WlpA0;y<=WBu00osvhYU;S0mS#dlA^Ht2)QVAp zjp{|xlrr?!@mfz>Mom_1>oaSDN9~%&)#Y@dhkVjtGsf2$Z%!!~f|27Pi3yttC5Dwt zX`wz;5_zr>1U7=k1ikCMupab?X~NzZb&5sjJ@1zpeJ=2Qj7V()IbhlU3pv7_@`@+< zZv#lI6~w8T>gY0!j>)VQI>mmLel{oQ!q$yZ2EN18jTvW;_5*%o^?otgKQQWR6H50i zO$`^4je>aBJ~?nK@Q7I&PC$-e_5Sp~euYMDF`w)&Q2AdEk|nC6GkSeetM^3G(G^@s z@BZr`_Gtgof-2y3#@WMij9^;-@2~!=9r6ENGD-v8HwV&$;R&CMeL7U{xE zI)Gy!0cJ$TIc6t|wU@xv+W#s~1k_w{6WKCD-vU0`kMiBIu&}%WGZ^V43d>Nb4Zk#z zs=ir{ebwl-FaT(^FJu6QGfBv^4&d)Ag{@L>V+fxAjE#-G=U?=Bc}8em7rdP}Y11n$ zEp-^>+rudpl&E}t8e}~4^&hH3NOFgHDYntCYO)vUKb1d=045qi>i}<{7cy{Xc|KON z((5YD#midi4aqK0pO{CaeTK(sG*FYP_@E2fo(HJ7eRs64^B! z>38`r-L&-NVy*OnbPzV2v07ci+y>iDB4G&m9KIh4;I9BA{#L1x&kZ~Ax;c4y(!jTS zrB<-9F%JKyAn^(A4^kS?FkA*0sF$bBXM@qSaxGHQZizrIsebaIoSrZNd82{7A&Ke3 z2QU#Z@;kR+)2WgD4Zi&Rl6G&`dZY1@7P`C73&FhvVv)^FmZ zz1IqHU2#r$9j~>8b@zdC<^T@Xm9#d*6CkO#q4&41{v?q|LX=AexOul1MTnT>H$9b4 z^k=cqCR&?GO4h?Lw+Q}21|LC<-NTt;ujeQ;T-|WW<5WIJFz=gO+8~#XX*c1W&cWfpiw^H%CB?SxjCxm>Egxdhlv1`By4Okwqe8>tAMj7#{ zW7n>K(w3lQ~R=uHx%ph^B() z#~SI_KyzYjO9 zumxe^r_HIFuxp$i1hnO^%krr?V_v6@-o*4@SuECJwv71zdfn5R1cs1P0!k1H$`BGn zZiOBYJ}Mx6q!`!3Nj(S3GYV(N=XC^;ecbdAa`#DgpqcZzXlGZNLMe$AZ*#p@8BtDn z+Bkn1LV$+qE(ECM!Mv;nlXPJ^A+dfHi{_E^tx27N4qcdRONdI^xQCJ~x=&S4=vUq~gq7Jd3U>RMw5`UctRqOhHrgvAf$n`}ilt z+nvm1qn6m1tKvP_2J}L<%?KuhETRA_)P9VcKR1eGoI<7e-Td+qoK9j<&$G+&Om+f2jcB zFz{tsy8uPnBZO{T?;OnAn2Ol?W~S(!&g|zHI@7Qq?D7IP&?kEn`%KV=qc3JcNNu1P zM7(2;Sm3aoM(I%&;gNtiNGA%Cg8a6C_D@eC5C1H(aZUl`D4UfhdN=8XQ+eaUh>Q{8 zR}To>5X{y7=vMTw-kUdiv%3SI@w+o0jd@U65~=t`3e3rBl$0GQytfWyfvlO5-+X?G zrAK#W#FWvJ$tmZl44k;0nu$Y}B6?ke4o3Tue2NBb_FkQsD(V9QhFFhB9!9aPSj^VWS7;3Pp4thk9(9Yq}$~SnM!1I z9R)};IWao4W$)LP*(PHShR={#`bDK>A=PvSuV-!3fH+QozF#46G)g_7e%!j4NQnqd zi5Uq>`C8gBP6cygb819GGwCo999R&^7>j)YMb@3iG_$PW0?aEyWn&B*wZF~}?QHBV3V>2G z`nHY2P_I72``d_N-Vp_j^)ly*-gB$Y3uq3-Ttr$gS&w=<)HCicvwzioV;%b1GJ_jQ z&21f1s-Tc>YR34-^$TudAWlLV@g1K3s;ng%mNXlg4dS$2P;F*kF$1Q?RRPbB`OH}K zn*bRWOv$v5mS*9rqK~kd1#sez#}fVGQ5&vq*!~*CrWgVSS!sMmyq5z|xrK*uw@L-# zPtL>z>VrPF0l!9Fp8d^*v(d7CnV-w19PG}4l{FEQb+jkYGRbD=PqdcD5_^qR< z$CPQRL~s}a4iXQ8E6X>d&S;Gf`Y7QjS4d!lLA060~4LN@vB6C%#Rltn|ck*}L730y+Lt+LL zp!*a$h%ETF`$JH_Pziw)-r$XKmVcl2XajbtL{^+~{WJ+ui+F8o7LFl1X=3${xqc#ItKM>13zOoY9jtxT0J!$<`4#*wj1{ zAo<-3y)3o!VzODiWHICqQ8{gUuW7h&iCtQ(cW?w!xn_h|u}<;r%XxV5;rBG5Zz2vA z9giOMFjQgiuLK_tA%$ZzIJe(hnGQEk5ADPW2*ulU^xzPD3WZbJoVDf=eA%-Tcn zZzBIkRPqtOT@ilT9Ip64jtXF)w%pC1n^lIJkKI(EpKr0QeMy?-NF9u-;P>TIqi{%7!`NeN42#DFNGP!Eehl?H)4&QZX1wzXD@XM?UjxG+s zy|KD?7F+pO`q=UA9$f*LIBh}2lYniS9q5)|C9nOvt@rM9N-H7mK%_sNr7d>S|AaW# zVUou$q&Vk}LSDI5m#fRhuIEnW-w;fVqY_UfX*T<3IzVA&dQ zqu}@1>!`^obB(N+cZuIQm2GmwRUMG7g-ED)jo)jzlk^>S-i7c=&IL*Ee$w{vH!b~$ z>!FYSL2pf|tEUvd0MF9A@X&;RLt6r!LkjF%T3c{LLpmV?9?Wx}bQ5=)Pzay8fz?)0 zBrcQR%-@0E>`DL47y&c}n{Mu%pyK*rT!)vkK`b=i2%00_CRMbTA0Kzv(nj8oaW)xOK=*ZxFp{<$e$t1~?Bd|d+JsF&MzPHv zkqgDZS8nVdT?B$O9s^7_DS^ePuW4xbKoR#U3pcJ_08rrnkBF21p@<@k1dadshP9e= zba;6A(q+RRDOrCcEY;=zH+y5V)4x62qWd{~34cU}^K_pg(a9(aWJV=Or*E*?xf^ZE zx>TK;#Q5Cc_#JqE`Ia27=3V}ES8v2YYxup#C4m z;T&d7+X1gQ&kX=6Yc31k%b>o2i#~F;-ZEvwlCFC|@cv-hc6fATT97pdg&zLbA?Qqy z(T;ru0Hc>b;0h3b4VEy;8eaL5Zs~xKen7MB5|M#C{+;A@d3 z2EgoMcuq}yUt!^`_`U<0`YMl`L*RHDW*JEf0MzMC+^$Wi=fh^uGVepLcw0Cg)b~Ba zY9dRjweF~nLF=|VYNV51q&t_Q0#dyDnk{m7Ah{JhM6L&r6fd{PU$lTciWqJdp?F@2 z3p$%ysVS5ptP%2dt{2b^wh&!%LW7r)$Hb$8W_siB70_Kw6HZ|ZxKD2!sH{qVWsAWD zzj*`G=Ynzwk=}HBf++$c{Y^g?>2|!_%u*4@bGAWMVVF*&Z!uy_G6;jp~ z5H(ThR{_V<7`c)Mz-P-W$JnGH7d1fa;%Xn0MwF)0D#k-izv66CYue4oes)7K@cc{(EgW;;enF-~Pj-r%8i zO!)8hhxXHmAx$mYPAoPH^MA6TXGFgN@81j<^tPz6=#LX@=~6Lfn@fT`@?Sdz5l@s_nOaGQ(itTxK7tX?TCLkBKpKovZif%} z`juS?COD*(H`M3M*qH%erC^xSFXIF4jA=Fao1f~Q|A~g7dM+UTvNdyQvDi(HAATPk z)4=JoeE{&-`v)RcZSZQ0zJISrbRyX(i1;)nI28&bp5LZT*3o!S-g5cng;>SyyaPe4 zj{^O;i}sf+6-9SpS~OxTvJO9{BoQ1m{XE$KQFs;@O0$)1Gr=0svTgfa&)g9sa~F|5X4)oa^)++{b3oBu9FU-bI+HDP|upzl*9&jY1LESud8d-Vk^ITDLkFe17@Ag z2e1`o0+bWLGV)m3XnlMXwnRw6h;$akqK;vwQ}pix9K{zwO8A`C^=sbEcKe-=5#lca z&~;$dxL)`*%jZq_qtCt&ynaC()paO=i78=w$N=F?Q(WFB@ly|}p!^8&3&&Ho(%e!_ zfYHcvA$u>gybr|;p9wEz|81Vw&_ZRt9l=kDI!iA;gkY4D9VtjX3Q0hw6fgYSPv2LG zHZT3J*1AD*x>II(pg4r4osrx)By<}PMlaI(Oy@VzUXxHv9#fAsqWjXYL40tCs4k;M zS#Ty>9Z7(x(gCA6NzKtd*4zd)E-vmQeg({fBukAvh3Y}4j6Tvr=N$sbef%V8@QW}X ztKe%UPSv-LUp0M2x&@J-DK9>R0CDPFe#G3Oq7P@iE9`;TaP0-a)kzf>7iWw^j=P@; zpFjfjbat+71-g@j4D$$3IDfA1JUSO0XdKh){2PVEEiKDsgus>E!Bq4OiE_MwZ#dul zyWbGdHyhC%+g*KKc}ofaj^QU@NniLw+k0aSBz-Ob<6(FC9Z+0EBY&8ay?z0&V<|we zPRqKdv9}pl=~tLvUSb?HDoLO;NdAMa`UpWfd z>$8`P0w<6|{<>mkX3E@+#;x$3f$v8iq!SoRv0aqyx%ge()&5M`9 ztRDS<_*g*Oqtd%!8L0)L?_K)>K*GqEyV09HCt5QFR<$Y>tl71VTd=>*)F6&9E7aaI z&*b9{pZ>kxRa#+-mrcoJ4_xE4%C+m)oS8TyAnqez;tZzLAI2P2K|T^Ky8-n-xn%?o zMnXJ*e&v4`Uj08epG~qAyMBE6#8kwt-Ttc9lEfeWp@KZSc$~l)!j(cgQPDlo3nhN; zeqwf%+_gde0vNWb%*mt~$ZKq012rAC0icEymO1keJouF+=i)F@f!T720_^(N4T-u_ zArAnis5A-Ukq0_>Y&}`ueCZs&msD2%2V>fkWD2Z~?1Aq#j28f#x2mr05zB!wK>=Lf zPu=Xs#sxF;ZV1+Eswygz6N_Sr*)oaSdwWluE>FD*(XG`tu!~P4!0$9G5?`ImS|$yL zFbi-!jBvk1ryLS@tbsT;1nSzdvQZSy(=~D6oZ{HRdi5(vfJI1H!zH!Gzs>$9VkIoN z*F(|&H5(3)4@DWU{TCzr!~gs*_P=0+|NnW=mqr4wAHcc^Y%VOd+r3+zoSbA;33zN% zf%~NJYp^LJ3rn23F20<}(hneTrCl&SHdfaCbMCaJLM)?mbvJuhCx;A#Yk7YlKfTEHFI6R}dS+}XFDW|nnUq@Hh)K$&UkgeKmEFNe#ewCh`8=S2} zyL{}WH+7t9o?KkmzFeYxhJ#s|m^oc$NCP&-pbEuK%5K1Kzy#daQvahzSDj!yvv&U+ z->l>)W6~Z1{9~W}kghQ^>*_QVc{gC$#<_0dsw|g`&pdl;jWkM)P!;7ff)M``P&RK8 z5jPM+KNKDgt@^$-b!o7bGP$}y1)N#0k9h;+qQ(IlW+`<3eToBCySSO9`2H_*d=1%N za_vyyq{)8a@Fm*@yut2A4?wFr{!zubs?DO2d8tN}o2Q*AP5+t4GP~VKkB_uMf^=|x zVS$f%&~iHhx=FCjUUJ%vtrQF7{eD)P!_!_pk1m;iEaI%Si|c@;Hcn1X{yvqbQ0082 z@zUDVq|+NtdL$Bd1|P^>rdzKFa4zY`JMY6qBTJ3%DeJUo9BAXyR=gn|8Xf`B>i z8jXbg{T?v2y}59B0yI>nz_m09Bs^@*R~Y%7foTOn*n7Z*om*958dNe>PUd9BWm2Ax@(;Gmn978l1h;;^hrv}}) zlN8>|+Ob^(O^Koys@HTvz-)e}q69{b4ud z)txZpdDfcnz7*(CFSWaUa@>_SG+12*0|8sxuX{P;V9^f^9*Canz6g&d!F!c`WHC~q zcn|i|gzG?eM`CJ>z>*c)c ziM%YJ@EKuU0=vh)&=)|bf|SH*5k2;