From 205d11df0db39ccec83e741259fc6b2115953997 Mon Sep 17 00:00:00 2001 From: ivan2282 Date: Sat, 15 Nov 2025 20:06:40 +0300 Subject: [PATCH] Initial Commit --- .gitignore | 45 + .metadata | 45 + LICENSE | 21 + README.md | 18 + analysis_options.yaml | 28 + android/.gitignore | 14 + android/app/build.gradle.kts | 87 + android/app/proguard-rules.pro | 11 + android/app/src/debug/AndroidManifest.xml | 11 + android/app/src/main/AndroidManifest.xml | 59 + .../kotlin/com/gwid/app/gwid/MainActivity.kt | 5 + .../drawable-hdpi/ic_launcher_background.png | Bin 0 -> 12731 bytes .../drawable-hdpi/ic_launcher_foreground.png | Bin 0 -> 11447 bytes .../drawable-mdpi/ic_launcher_background.png | Bin 0 -> 6784 bytes .../drawable-mdpi/ic_launcher_foreground.png | Bin 0 -> 6439 bytes .../res/drawable-v21/launch_background.xml | 12 + .../drawable-xhdpi/ic_launcher_background.png | Bin 0 -> 19026 bytes .../drawable-xhdpi/ic_launcher_foreground.png | Bin 0 -> 18197 bytes .../ic_launcher_background.png | Bin 0 -> 33020 bytes .../ic_launcher_foreground.png | Bin 0 -> 36292 bytes .../ic_launcher_background.png | Bin 0 -> 49058 bytes .../ic_launcher_foreground.png | Bin 0 -> 59519 bytes .../res/drawable/ic_launcher_background.xml | 74 + .../main/res/drawable/launch_background.xml | 12 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 9 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3981 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2098 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 6509 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 13236 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 22433 bytes .../app/src/main/res/values-night/styles.xml | 18 + android/app/src/main/res/values/styles.xml | 18 + android/app/src/profile/AndroidManifest.xml | 7 + android/build.gradle.kts | 24 + .../reports/problems/problems-report.html | 663 +++ android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 + android/settings.gradle.kts | 26 + assets/icon/bg.png | Bin 0 -> 174258 bytes assets/icon/icon1.jpg | Bin 0 -> 77815 bytes assets/icon/komet.png | Bin 0 -> 179772 bytes assets/icon/komet_512.ico | Bin 0 -> 4286 bytes assets/icon/komet_512.png | Bin 0 -> 80682 bytes assets/images/komet_512.png | Bin 0 -> 80682 bytes assets/images/meteor.png | Bin 0 -> 69540 bytes assets/images/spermum.webp | Bin 0 -> 153195 bytes ios/.gitignore | 34 + ios/Flutter/AppFrameworkInfo.plist | 26 + ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + ios/Runner.xcodeproj/project.pbxproj | 616 +++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 101 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + ios/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 1 + .../Icon-App-1024x1024@1x.png | Bin 0 -> 544354 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 596 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1559 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 2985 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 964 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 2833 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 5517 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1559 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 4757 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 9594 bytes .../AppIcon.appiconset/Icon-App-50x50@1x.png | Bin 0 -> 2232 bytes .../AppIcon.appiconset/Icon-App-50x50@2x.png | Bin 0 -> 6907 bytes .../AppIcon.appiconset/Icon-App-57x57@1x.png | Bin 0 -> 2745 bytes .../AppIcon.appiconset/Icon-App-57x57@2x.png | Bin 0 -> 8644 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 9594 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 20264 bytes .../AppIcon.appiconset/Icon-App-72x72@1x.png | Bin 0 -> 3981 bytes .../AppIcon.appiconset/Icon-App-72x72@2x.png | Bin 0 -> 13236 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 4364 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 14574 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 17486 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + ios/Runner/Base.lproj/LaunchScreen.storyboard | 37 + ios/Runner/Base.lproj/Main.storyboard | 26 + ios/Runner/Info.plist | 49 + ios/Runner/Runner-Bridging-Header.h | 1 + ios/RunnerTests/RunnerTests.swift | 12 + lib/api_service.dart | 2860 +++++++++++ lib/api_service_simple.dart | 774 +++ lib/api_service_v2.dart | 1131 +++++ lib/cache_management_screen.dart | 431 ++ lib/channels_list_screen.dart | 342 ++ lib/chat_screen.dart | 4302 +++++++++++++++++ lib/chats_screen.dart | 3324 +++++++++++++ lib/connection/connection_logger.dart | 317 ++ lib/connection/connection_manager.dart | 652 +++ lib/connection/connection_manager_simple.dart | 684 +++ lib/connection/connection_state.dart | 283 ++ lib/connection/health_monitor.dart | 331 ++ lib/connection/retry_strategy.dart | 339 ++ lib/connection_lifecycle_manager.dart | 138 + lib/custom_request_screen.dart | 317 ++ lib/debug_screen.dart | 740 +++ lib/device_presets.dart | 678 +++ lib/downloads_screen.dart | 348 ++ lib/example_usage.dart | 264 + lib/full_screen_video_player.dart | 116 + lib/home_screen.dart | 849 ++++ lib/image_cache_service.dart | 266 + lib/join_group_screen.dart | 341 ++ lib/main.dart | 243 + lib/manage_account_screen.dart | 398 ++ lib/models/attach.dart | 116 + lib/models/channel.dart | 37 + lib/models/chat.dart | 99 + lib/models/chat_folder.dart | 83 + lib/models/contact.dart | 68 + lib/models/message.dart | 133 + lib/models/profile.dart | 82 + lib/otp_screen.dart | 198 + lib/packet_framer.dart | 104 + lib/password_auth_screen.dart | 298 ++ lib/password_management_screen.dart | 426 ++ lib/phone_entry_screen.dart | 666 +++ lib/profile_menu_dialog.dart | 304 ++ lib/proxy_service.dart | 117 + lib/proxy_settings.dart | 91 + lib/screens/group_settings_screen.dart | 1206 +++++ lib/screens/settings/about_screen.dart | 440 ++ lib/screens/settings/animations_screen.dart | 370 ++ .../settings/appearance_settings_screen.dart | 325 ++ lib/screens/settings/bypass_screen.dart | 331 ++ .../settings/customization_screen.dart | 1503 ++++++ .../settings/export_session_screen.dart | 278 ++ lib/screens/settings/komet_misc_screen.dart | 521 ++ lib/screens/settings/network_screen.dart | 868 ++++ .../settings/network_settings_screen.dart | 262 + .../notification_settings_screen.dart | 591 +++ .../settings/privacy_security_screen.dart | 216 + .../settings/privacy_settings_screen.dart | 383 ++ .../settings/proxy_settings_screen.dart | 263 + lib/screens/settings/qr_login_screen.dart | 301 ++ lib/screens/settings/qr_scanner_screen.dart | 64 + lib/screens/settings/reconnection_screen.dart | 298 ++ .../settings/security_settings_screen.dart | 91 + .../settings/session_spoofing_screen.dart | 754 +++ lib/screens/settings/sessions_screen.dart | 251 + lib/screens/settings/settings_screen.dart | 610 +++ lib/screens/settings/socket_log_screen.dart | 513 ++ lib/screens/settings/storage_screen.dart | 805 +++ lib/search_channels_screen.dart | 931 ++++ lib/search_contact_screen.dart | 458 ++ lib/services/avatar_cache_service.dart | 339 ++ lib/services/cache_service.dart | 332 ++ lib/services/chat_cache_service.dart | 334 ++ lib/services/version_checker.dart | 121 + lib/spoofing_service.dart | 28 + lib/theme_provider.dart | 1250 +++++ lib/token_auth_screen.dart | 437 ++ lib/tos_screen.dart | 176 + lib/universal_io.dart | 6 + lib/user_id_lookup_screen.dart | 263 + lib/widgets/chat_message_bubble.dart | 4048 ++++++++++++++++ lib/widgets/connection_debug_panel.dart | 676 +++ lib/widgets/connection_status_widget.dart | 440 ++ lib/widgets/group_avatars.dart | 189 + lib/widgets/group_header.dart | 124 + lib/widgets/group_management_panel.dart | 358 ++ lib/widgets/reconnection_overlay.dart | 116 + lib/widgets/user_profile_panel.dart | 396 ++ linux/.gitignore | 1 + linux/CMakeLists.txt | 141 + linux/flutter/CMakeLists.txt | 88 + linux/flutter/generated_plugin_registrant.cc | 47 + linux/flutter/generated_plugin_registrant.h | 15 + linux/flutter/generated_plugins.cmake | 32 + linux/readme.md | 3 + linux/runner/CMakeLists.txt | 27 + linux/runner/main.cc | 8 + linux/runner/my_application.cc | 143 + linux/runner/my_application.h | 10 + macos/.gitignore | 7 + macos/Flutter/Flutter-Debug.xcconfig | 1 + macos/Flutter/Flutter-Release.xcconfig | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 50 + macos/Runner.xcodeproj/project.pbxproj | 705 +++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 99 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + macos/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 68 + .../AppIcon.appiconset/app_icon_1024.png | Bin 0 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 2218 bytes macos/Runner/Base.lproj/MainMenu.xib | 343 ++ macos/Runner/Configs/AppInfo.xcconfig | 14 + macos/Runner/Configs/Debug.xcconfig | 2 + macos/Runner/Configs/Release.xcconfig | 2 + macos/Runner/Configs/Warnings.xcconfig | 13 + macos/Runner/DebugProfile.entitlements | 12 + macos/Runner/Info.plist | 32 + macos/Runner/MainFlutterWindow.swift | 15 + macos/Runner/Release.entitlements | 8 + macos/RunnerTests/RunnerTests.swift | 12 + pubspec.lock | 1543 ++++++ pubspec.yaml | 188 + windows/.gitignore | 17 + windows/CMakeLists.txt | 111 + windows/flutter/CMakeLists.txt | 110 + .../flutter/generated_plugin_registrant.cc | 44 + windows/flutter/generated_plugin_registrant.h | 15 + windows/flutter/generated_plugins.cmake | 34 + windows/runner/CMakeLists.txt | 40 + windows/runner/Runner.rc | 121 + windows/runner/flutter_window.cpp | 71 + windows/runner/flutter_window.h | 33 + windows/runner/main.cpp | 43 + windows/runner/resource.h | 16 + windows/runner/resources/app_icon.ico | Bin 0 -> 23137 bytes windows/runner/runner.exe.manifest | 14 + windows/runner/utils.cpp | 65 + windows/runner/utils.h | 19 + windows/runner/win32_window.cpp | 288 ++ windows/runner/win32_window.h | 102 + 233 files changed, 52572 insertions(+) create mode 100644 .gitignore create mode 100644 .metadata create mode 100644 LICENSE create mode 100644 README.md create mode 100644 analysis_options.yaml create mode 100644 android/.gitignore create mode 100644 android/app/build.gradle.kts create mode 100644 android/app/proguard-rules.pro create mode 100644 android/app/src/debug/AndroidManifest.xml create mode 100644 android/app/src/main/AndroidManifest.xml create mode 100644 android/app/src/main/kotlin/com/gwid/app/gwid/MainActivity.kt create mode 100644 android/app/src/main/res/drawable-hdpi/ic_launcher_background.png create mode 100644 android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_launcher_background.png create mode 100644 android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png create mode 100644 android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_launcher_background.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png create mode 100644 android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 android/app/src/main/res/drawable/launch_background.xml create mode 100644 android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 android/app/src/main/res/values-night/styles.xml create mode 100644 android/app/src/main/res/values/styles.xml create mode 100644 android/app/src/profile/AndroidManifest.xml create mode 100644 android/build.gradle.kts create mode 100644 android/build/reports/problems/problems-report.html create mode 100644 android/gradle.properties create mode 100644 android/gradle/wrapper/gradle-wrapper.properties create mode 100644 android/settings.gradle.kts create mode 100644 assets/icon/bg.png create mode 100644 assets/icon/icon1.jpg create mode 100644 assets/icon/komet.png create mode 100644 assets/icon/komet_512.ico create mode 100644 assets/icon/komet_512.png create mode 100644 assets/images/komet_512.png create mode 100644 assets/images/meteor.png create mode 100644 assets/images/spermum.webp create mode 100644 ios/.gitignore create mode 100644 ios/Flutter/AppFrameworkInfo.plist create mode 100644 ios/Flutter/Debug.xcconfig create mode 100644 ios/Flutter/Release.xcconfig create mode 100644 ios/Runner.xcodeproj/project.pbxproj create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 ios/Runner/AppDelegate.swift create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 ios/Runner/Base.lproj/Main.storyboard create mode 100644 ios/Runner/Info.plist create mode 100644 ios/Runner/Runner-Bridging-Header.h create mode 100644 ios/RunnerTests/RunnerTests.swift create mode 100644 lib/api_service.dart create mode 100644 lib/api_service_simple.dart create mode 100644 lib/api_service_v2.dart create mode 100644 lib/cache_management_screen.dart create mode 100644 lib/channels_list_screen.dart create mode 100644 lib/chat_screen.dart create mode 100644 lib/chats_screen.dart create mode 100644 lib/connection/connection_logger.dart create mode 100644 lib/connection/connection_manager.dart create mode 100644 lib/connection/connection_manager_simple.dart create mode 100644 lib/connection/connection_state.dart create mode 100644 lib/connection/health_monitor.dart create mode 100644 lib/connection/retry_strategy.dart create mode 100644 lib/connection_lifecycle_manager.dart create mode 100644 lib/custom_request_screen.dart create mode 100644 lib/debug_screen.dart create mode 100644 lib/device_presets.dart create mode 100644 lib/downloads_screen.dart create mode 100644 lib/example_usage.dart create mode 100644 lib/full_screen_video_player.dart create mode 100644 lib/home_screen.dart create mode 100644 lib/image_cache_service.dart create mode 100644 lib/join_group_screen.dart create mode 100644 lib/main.dart create mode 100644 lib/manage_account_screen.dart create mode 100644 lib/models/attach.dart create mode 100644 lib/models/channel.dart create mode 100644 lib/models/chat.dart create mode 100644 lib/models/chat_folder.dart create mode 100644 lib/models/contact.dart create mode 100644 lib/models/message.dart create mode 100644 lib/models/profile.dart create mode 100644 lib/otp_screen.dart create mode 100644 lib/packet_framer.dart create mode 100644 lib/password_auth_screen.dart create mode 100644 lib/password_management_screen.dart create mode 100644 lib/phone_entry_screen.dart create mode 100644 lib/profile_menu_dialog.dart create mode 100644 lib/proxy_service.dart create mode 100644 lib/proxy_settings.dart create mode 100644 lib/screens/group_settings_screen.dart create mode 100644 lib/screens/settings/about_screen.dart create mode 100644 lib/screens/settings/animations_screen.dart create mode 100644 lib/screens/settings/appearance_settings_screen.dart create mode 100644 lib/screens/settings/bypass_screen.dart create mode 100644 lib/screens/settings/customization_screen.dart create mode 100644 lib/screens/settings/export_session_screen.dart create mode 100644 lib/screens/settings/komet_misc_screen.dart create mode 100644 lib/screens/settings/network_screen.dart create mode 100644 lib/screens/settings/network_settings_screen.dart create mode 100644 lib/screens/settings/notification_settings_screen.dart create mode 100644 lib/screens/settings/privacy_security_screen.dart create mode 100644 lib/screens/settings/privacy_settings_screen.dart create mode 100644 lib/screens/settings/proxy_settings_screen.dart create mode 100644 lib/screens/settings/qr_login_screen.dart create mode 100644 lib/screens/settings/qr_scanner_screen.dart create mode 100644 lib/screens/settings/reconnection_screen.dart create mode 100644 lib/screens/settings/security_settings_screen.dart create mode 100644 lib/screens/settings/session_spoofing_screen.dart create mode 100644 lib/screens/settings/sessions_screen.dart create mode 100644 lib/screens/settings/settings_screen.dart create mode 100644 lib/screens/settings/socket_log_screen.dart create mode 100644 lib/screens/settings/storage_screen.dart create mode 100644 lib/search_channels_screen.dart create mode 100644 lib/search_contact_screen.dart create mode 100644 lib/services/avatar_cache_service.dart create mode 100644 lib/services/cache_service.dart create mode 100644 lib/services/chat_cache_service.dart create mode 100644 lib/services/version_checker.dart create mode 100644 lib/spoofing_service.dart create mode 100644 lib/theme_provider.dart create mode 100644 lib/token_auth_screen.dart create mode 100644 lib/tos_screen.dart create mode 100644 lib/universal_io.dart create mode 100644 lib/user_id_lookup_screen.dart create mode 100644 lib/widgets/chat_message_bubble.dart create mode 100644 lib/widgets/connection_debug_panel.dart create mode 100644 lib/widgets/connection_status_widget.dart create mode 100644 lib/widgets/group_avatars.dart create mode 100644 lib/widgets/group_header.dart create mode 100644 lib/widgets/group_management_panel.dart create mode 100644 lib/widgets/reconnection_overlay.dart create mode 100644 lib/widgets/user_profile_panel.dart create mode 100644 linux/.gitignore create mode 100644 linux/CMakeLists.txt create mode 100644 linux/flutter/CMakeLists.txt create mode 100644 linux/flutter/generated_plugin_registrant.cc create mode 100644 linux/flutter/generated_plugin_registrant.h create mode 100644 linux/flutter/generated_plugins.cmake create mode 100644 linux/readme.md create mode 100644 linux/runner/CMakeLists.txt create mode 100644 linux/runner/main.cc create mode 100644 linux/runner/my_application.cc create mode 100644 linux/runner/my_application.h create mode 100644 macos/.gitignore create mode 100644 macos/Flutter/Flutter-Debug.xcconfig create mode 100644 macos/Flutter/Flutter-Release.xcconfig create mode 100644 macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 macos/Runner.xcodeproj/project.pbxproj create mode 100644 macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 macos/Runner/AppDelegate.swift create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 macos/Runner/Base.lproj/MainMenu.xib create mode 100644 macos/Runner/Configs/AppInfo.xcconfig create mode 100644 macos/Runner/Configs/Debug.xcconfig create mode 100644 macos/Runner/Configs/Release.xcconfig create mode 100644 macos/Runner/Configs/Warnings.xcconfig create mode 100644 macos/Runner/DebugProfile.entitlements create mode 100644 macos/Runner/Info.plist create mode 100644 macos/Runner/MainFlutterWindow.swift create mode 100644 macos/Runner/Release.entitlements create mode 100644 macos/RunnerTests/RunnerTests.swift create mode 100644 pubspec.lock create mode 100644 pubspec.yaml create mode 100644 windows/.gitignore create mode 100644 windows/CMakeLists.txt create mode 100644 windows/flutter/CMakeLists.txt create mode 100644 windows/flutter/generated_plugin_registrant.cc create mode 100644 windows/flutter/generated_plugin_registrant.h create mode 100644 windows/flutter/generated_plugins.cmake create mode 100644 windows/runner/CMakeLists.txt create mode 100644 windows/runner/Runner.rc create mode 100644 windows/runner/flutter_window.cpp create mode 100644 windows/runner/flutter_window.h create mode 100644 windows/runner/main.cpp create mode 100644 windows/runner/resource.h create mode 100644 windows/runner/resources/app_icon.ico create mode 100644 windows/runner/runner.exe.manifest create mode 100644 windows/runner/utils.cpp create mode 100644 windows/runner/utils.h create mode 100644 windows/runner/win32_window.cpp create mode 100644 windows/runner/win32_window.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..3268d00 --- /dev/null +++ b/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "a402d9a4376add5bc2d6b1e33e53edaae58c07f8" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: android + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: ios + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: linux + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: macos + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: web + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + - platform: windows + create_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + base_revision: a402d9a4376add5bc2d6b1e33e53edaae58c07f8 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a5f7549 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 needle10 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5d689db --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +
+

Komet Messenger

+

An Open Source alternative unnoficial client for MAX

+
Telegram Group
+ +## How to install? +### Download file from releases tab or our telegram group and install it +## How to build? +### This is app built on flutter, use flutter guide +## How to countibute? +### Create a fork, do everything +### And create pull requeste +### Make sure your commits looks like: +fix: something went worng when user... +add: search by id +edit: refactored something +Other actions should marked as "other:" and discribes what you did + diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..be3943c --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +.cxx/ + +# Remember to never publicly share your keystore. +# See https://flutter.dev/to/reference-keystore +key.properties +**/*.keystore +**/*.jks diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..808eeea --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,87 @@ +import java.util.Properties +import java.io.FileInputStream + +plugins { + id("com.android.application") + id("kotlin-android") + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.gwid.app.gwid" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.toString() + } + + sourceSets { + getByName("main") { + jniLibs.srcDirs("src/main/jniLibs") + } + } + + defaultConfig { + applicationId = "com.gwid.app.gwid" + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + ndk { + abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64") + } + } + + val keyPropertiesFile = rootProject.file("key.properties") + val keyProperties = Properties() + + signingConfigs { + create("release") { + val envStoreFile = System.getenv("RELEASE_STORE_FILE") + val envStorePassword = System.getenv("RELEASE_STORE_PASSWORD") + val envKeyAlias = System.getenv("RELEASE_KEY_ALIAS") + val envKeyPassword = System.getenv("RELEASE_KEY_PASSWORD") + + if (envStoreFile != null && envStorePassword != null && + envKeyAlias != null && envKeyPassword != null) { + storeFile = file(envStoreFile) + storePassword = envStorePassword + keyAlias = envKeyAlias + keyPassword = envKeyPassword + } else if (keyPropertiesFile.exists()) { + keyProperties.load(FileInputStream(keyPropertiesFile)) + storeFile = file(keyProperties["storeFile"] as String? ?: "") + storePassword = keyProperties["storePassword"] as String? ?: "" + keyAlias = keyProperties["keyAlias"] as String? ?: "" + keyPassword = keyProperties["keyPassword"] as String? ?: "" + } + + } + } + + buildTypes { + getByName("release") { + // Only use release signing if keys are available + if (file(keyPropertiesFile).exists() || + System.getenv("RELEASE_STORE_FILE") != null) { + signingConfig = signingConfigs.getByName("release") + } + isMinifyEnabled = true + isShrinkResources = true + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } +} + +flutter { + source = "../.." +} diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 0000000..d866756 --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,11 @@ +# Flutter-специфичные правила (у вас уже должны быть) +-keep class io.flutter.app.** { *; } +-keep class io.flutter.plugin.** { *; } +-keep class io.flutter.util.** { *; } +-keep class io.flutter.view.** { *; } +-keep class io.flutter.embedding.** { *; } + +# Игнорировать предупреждения о недостающих классах Play Core +-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication +-dontwarn com.google.android.play.core.splitinstall.** +-dontwarn com.google.android.play.core.tasks.** diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..572e202 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..1ee3273 --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/gwid/app/gwid/MainActivity.kt b/android/app/src/main/kotlin/com/gwid/app/gwid/MainActivity.kt new file mode 100644 index 0000000..515bf2f --- /dev/null +++ b/android/app/src/main/kotlin/com/gwid/app/gwid/MainActivity.kt @@ -0,0 +1,5 @@ +package com.gwid.app.gwid + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity : FlutterActivity() diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_background.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..a33b40cb6f548a02cc95460bea74a4d778d8e177 GIT binary patch literal 12731 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 Bu(|*M literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..f7979264d206ed8dcc11808a498c61065a1f4b65 GIT binary patch literal 11447 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 + + + + + + + diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..516c6672d293993091715335c5158b7ec9f83538 GIT binary patch literal 19026 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 JPDHLkV1hJU5$FH_ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..f86283ae2db1e060b4ed6d78992d658d4aa22f79 GIT binary patch literal 18197 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

~3T0UBaPPh1&_!DnKGmQ=B-|7E@=6k)V4f@&1 zDZD)qFMom%fkaQ;qS$}>bOrQjLlzr zyB{yVK=bGQH;f<%NQq}ZH{e-$z}9F?QgZ+3BI(k_2q^SSy4%ZU4-ZM*Dn7cHb=S)snz$$2XKqp>Lm6~Y}MVI zkt}KU1L*hY$T`*QU=<`IbCWRRJxC2QVZIf4JwMFr{5WrNTcK|P_AQ~45w)Sx$S-4) z$^nitZ%@17e4g8T0!}l;S+Hd& zVPj9G=!Ao&fBcn)NH>vSz(NxoU(Ori=KnQQ0N_UQd+}6P=)CSon4X^p*Z;ZT-M~gp zmC#&@nH{3M7LFHWB2LABp&m-GJmJl)MjQhHogtqzV`MgwZH=+5bDNKqb0bPbf0YPdM2MDUEe}a zFA9U&TtQydbBdw==k;HYds$Ig<*!t*bPVS@vEsuN9!pri`EFFWN2hWOP{a7g1YuaS z0$lIBj&7N)-%!ztOk2t<+q4(JlabVAs6aI}NQSo|*x%7mq|BgiwWNucBlimj%_HM8 zhYyv}#X`*tq|5#eFw|Cu>TSCuO|kULA4tt9{Ei(bQ+doKC?F_iy3S#HlBX0}3Nc~?0>4)P1~vmP1gy4%goWRH##_knZSJlmw=>O1y)pLM zMNv0p3WQ4MtR$lAAh4)qWYn!9qlP~`9eE#HJ$Rb=w6x3XCh(Co=wX~geQbVgGBC=B z0MLq@5lH6B!Zc{oei&YyZ6HpG+@j=qeb7-QO-!J8)Xc~hjU_hf1B=3Ls!>_m{FJiXkJ$3m*@dgzz>SBpqVk;akd-CE^ZFs>t$ay z-MU^Pw)ZavuUw%mYXMkFgzJUiblgg5jrNDLE>J_!an3^X&m|k(BVGBBWIIBNF#XtQ zoD(wQJHAw?B&xY%q4EL!gq`w03D{6`Y}W*QY?ZCV-HaSLfOCtf4O}<5CIci{Q*d|83ZL`xI#91f?~<)69Xj5nc1JI`6iluK9IM*P11{*==;w+ zx1y4f{g?@tawUoFgEXGZ=Bd8O&(C_j=zQG#^qF#tN?OAfNa!VI87oGH5WU*K4iFqB z3B^d_z^S_QIjA*g@5V%n3T$v4ydg%F+L9I=vJU^_+p-g4*B(MMXoX5F6piOFM+McN zO|eKr9(Y8l>*PD5w~12ejzl+1cSInZ`frke?8{AqgfMRsMTm?|YO(74@iQwwLkwhP zv)y%H(l16v(b;L8pzdA%B|M~OOm|TM!#~m2tVqEwemgSf_`THVA}A?#zn1AD z-XEWx9;dh6TDZr*tF@Th;SFM+1U3Bw8N3wAu|5wsE`5hTT>_qqMFRW+iDM$a|JK~r zft<4n+5=(-5DmkEM+SXWJe*i%u|iEQT!_Ns>A!ENs8I|KT+{YTLXb{_ERM{qFbp_DyX;&tX{9zoTZ%dEZvafb{LU zd8y}f(;qv9=qHvTj0+1~z`LKxZF>2|`-^t>jm-Dd4_3^$nbZB*+j|Bi`r`TdH86b= z$j`}nqdDw`PM$&UvI^Bb*o+;3^}l1It|tsl(XCZ&tMj_-deyqS)1O~ozRFpd_(R8p z#iG^9@eRdhFFGt-{J8m4ji!8*vfd*OG{;XC9d~s3HtAGYREhXk=u%iWT9k)JK7lZv zzkkMAwK}b>Emtlovkn@-daeY&g^m!O>&+f}7oafu1vR5I!S1hq)Aa<`)Z5tn-rl3b z@N@j`GFPg5ycpv*@lD)gq_#WKj6RjX8*E#u&bH*WsA#-MP_|&(>0dulw_}S810DeZ zU|~yHqyo$nZTJ-QB$x0~jQn=sulA_^l+H9`m1;fSGsXDE)|JGfM$v`sYT~3fc_x{3%g~_R0NYPL0F-OG7E7wc|c%8(3Zt2?Pq9%yuuA zFr=a+iG09lEG@i0m!TfM4gFyz%!`ah`3{7DJp=rHe$!WXliF~cWAD~w#t}O=>lEjg zMd*Nlq3nt*)W9?Lba%fS&sYCEHJ7;~oAS(No+`6MT7cT8_*sU=?OA@j`jf$R50kvs zJb}q2bJBeKuTT*5=~6*NekeO9r{r$9H}kN}Mv2O=r~q??(Tze#sqm0qs#JJhednK0 zCuE~-k}SuRVJjweRb90Qb3bt_RhAYOH=8}y9+(uz$4G^y`nG{4Qu`Agr^cUMft)?6 zM&i{YGn+wZkcNL)EP9#XcaPX)n0TaWi(U=dfeKfWzeO4DsSdaCc zgk`wJX$|iE^`){aT2NN8n^YKW5uXEgaG_EWBSEa6n@|odMbH@wPTgw`ZM`o*zkC~x z%!fO;V&sn>+}uq1L1gRVqQ<0o zSYY%P++~J+YG~_eI_M1zr!`2kZ$?*&8PA`F?gBMj3yoJiKD>`p^DW-r{lqN&HnB}{ z%X?-p!o5Sq`y6GiU4iSUYhD*^Chx1wIi{lnt@FvCd4?m5gveeG`B5y}7)B@M zALSNRE;?plWPWtPx15{6>;G1yWz8Ttz40=7NIZsyM|;!z-0a-qQF41*@N@$bIx%Ji zCztg-kP0Owqm!ZvPrbiB_Bma)KQ>(keQJ8d;r%g6Qz$#~NsClR13htHOVPpvU#Ap# zBs4cC;i0}C0BBykYIn&nAWI;kC}?!gbD=a)`fJV|X9&d(AV@(%Jkh?t~-x zOqEns%lNs`qTXW|E!Nnm!t={qmqTS+lh;)9y$9-~s5zT;jZ>(hGV+TyTAc7f_w4E6_@(8fPlMD3a(a_YE6xF6E zCn+oo^9pZQ7GO5)4sXmRNxL$p=l7m49;2C-JSePo+YxJNZ4EH@H~se-5D;M0#4Pk` zYlxntKZvUXwD-X{4*3k_ns)bFiuibc4QjKuIfUI+-&IWk%zhBpD7o74Fw0zx=%PmS zxShYip8tktw6hgmYxi5iA7I6Yl!&IstS>4qYC?TVdLZY&vIfj;Hv6y48pS6ig)wtM zYie0(jN8RBhaw;3AM(TiV)M^?*qmN*|M2qmu5EsJ-Z16nWl_FUr6PEhLe`p?&k*2y z+?u(>amH$V=i{5!)!pX0MN;}noI`XXHaEL|H;gWNH?sEfc(G9yLG90RHXbO_Rs_2! z^dHkRYukm9zXiGv0tvQv*&j7cHliN|D<4K25>r9l0ZhY(DWuk%qdnKcu^T>H3roxn zo)25!t&|wvVz}RDrAH4VuOFW-)5|Pl(;eTARf?+HiPKs1&<0H*nRDqaOTyoD-nvu|#z*8~jSbgE zO4L8R$-dUbNE@{7_ucY2DwU@4iCoWfZ9NKqLjF+bN?i)g4=e5|OCa897$z&n`HY|v z(6?ZB-tKt>frLIOGo~aux4yM(8+^r-hX}bVT40ORK_IIwG8!_T3=mlkcO5 zwULNGm4=CNyQeF_`RIzW?XJ-)M2#5^6YDFJkNb!=F^O7>_4;)7vIs&1#2@!FyTz@vxi!>9*J=&t9vt`gaE_o>I-rq`_YzR~dZ%b1=xI zfj6wre3_j5`(bQue-`6j^^dK@yB9n0Lh`t?ACQXZX4!bMo3^|lY$@<$G7eb zU8B=Q;tTSNUUx?0pLUsgWlc|m6T@3e){a&1c^RE^RL_5qOBzz^!+{Ryg)%#b{Wo#b!HhbXzlOjr_S=s4SwQT%6Dl8 z2ZxwHGqST8Awzf~2dI?_NZwdwZPLd+_a0+_Cp0^K4>+tWqmR6j%SVsUZ%`=x^N zqX$K&*Jpi~z$D_w@MFiCp{qj*Z1_C80-g0R3esE>Z@WyY-$`Y;=!&XQKm*mY!PDAK z3V2y;;R?tjiEa6{*yqmS+d&+3(v+>cz~A|&>zfPBPuPiJr-agfyg}j^|4tFO4XD)K zndaJ?9@A#5_w){(gkQUgdV6J-<9o+RSsId;y&aOYN*jaBViUT;IK@oKm;g97!3UpdO=ExUd?b)})cAQhjrp3vX%hJUZVXOd2e{ z{ND63@yMTl8*bOG{n{0DRZ2J8u`}0I4=qbZ3K#L)nqhc-J@@DMe*W(ofG4b@I1)-y zLQm)eEDq`J^Ui7Tc=yrU#xomw6%!*?W(zFp{laIB%?Z|AsYjQm71J|Vtiy^@r}LVjp~v0+)nz7AyMvXpV{?*^`%Bn3V}|K|kI zX*5T~L4wr{9<+<#Bt9&8UGe+GXuO?2;@0Nh=-y$8M;8TM54l6AnI#B0pLR2+g0L<{*&tRO?4;%WHFn3DM~0 zCLLOPnCc(BB$WbdBRJwQGL28Oi2ryk%0=#fo5NPYi+bxjb;~*Y^c#nN6r4OBD74Ef zoPoyMJ(`CO%g!ndI&X_3Bi77h$UlkTOS7yO2@ljrQ}JbDcARbKITu%3z(j+J*e$dE zbJt^v$@%=eMkV%SiIQzsy`z&)to~*x>lVp~y3M?r>D}tgCe%(nR1_L{q>ivwrS~R2 zm|MAukQV;fAzjP=RHnhRfO(7>nTg`D)9OY2yyeQw%PXx&FKKCMxttPxg3SDNt1Z7S zD#(izhsRpX+8LoPe)e`91V}}Cmhlb2gag>8>xWuPw{vGHThX;U?YK9 z3b*OdN&rp*X`nE-;I-m^S)}TJ=qklFpw@om5+vOvkjx`~g`V`1eAPB0n4*X&|MoAV zwQrX8Yf*bU{0-3l3(wG6dKxLcRxmX&=M$Gg7O*}ig%-ONJ+xDNW+u1Y@t_ z%{kaM!n~rNMWr94r&`ez%%OSOLbrA4QTc9G#70s%dm9^VSY&j)x4y!o1x$NvOb)*W z;PP{T!2nVZJyhYJ*2htLvTo&+oj5zKx{ro3g+o7K%}qmouYLhlb#>$w`xctxomCkcqAu~TrYRIMg_()pV2CHwUgMc${Gh2^NLZd(5R)qLnQ&B zA|xs44YH6DM+J8Qp#-F8sHhTpe#Dp!(g_tkhN$}@1U$3;d`!sG#q4V|Qi&D+*v^j) z-+tMw8r>RPs+-pD&xcVAs3Qg%qn6>{yn3FmHWvYb&!;>K3qcM90?xTTFLC9Q5*j$} z`92C0pE)_dO*>KXB{qUSp{F-jk%*_ZV5s}4=cB)+BDQHLh-_Z?JQE!duYL z(9`X1=t_k&Sl6IaP#xV24;$i>h2+CVyJvswPp00x(BILbLannL`#r)~^7FrzSlTqG z+Vq5K0$k5mdHmu)ADv4_dAQyQ;Pk=?pE?LcClh_Uw&(TpGLz~Tv(0YJS7{ah?mHfX zSi-O=Lzkx8^{$*+*j0-*L{Gny?{^W>Y_|k!<0Kjs{zxJ3H((&8+=n>C-_hD4=z;NoeQI6Z#KX`16 zJJ(}TH#0N8_h1?}Yl8Vb7n`O2NV`-i%I4_uGAjSVQ6UFNf=I0x6*GSQ)MA(RwUrI_ zc9yr(65^|`;Aa4y|?P~Wp)G%}?hKgEpoH9R*y87JXz8mmWi`D3b6ng^w z`7BhnosEV=Idne-|FY`_Xz@#69*ZjF{cMQXW@iDMUB>1#M{KIv`1m3mh$ym}s&u_Y zqxk8eP}OW8W~6+wo>U@;1#w0Ajprmv`n`kTuMEqQIFVtJi>nR=NT_s3?_ zWYDet5?Ztn|D!3T%ByWvHDjF{X_~o0NLY)JZpJppEkb-?LBNFo*c2n+osSH%2`j5G zHftq(G~Nv;?NMA}M~x1r?#-mye%5X9)_B!tz^T0xzBJ?aV!3(&Hxue4nSrJ!LZUqH zCgU!b_BGY7HRsD#rn1(Y|4J?xscAP+db?MARj6Rnl*--jnL`fq{m3FCqfE}Tn`tK1 zRzOht9*ozc1YeG@&D@U~|E!wv2oAd>PP2d8rNWA&`b#cXJl*Wg!6TLobQUs>PVp2b zg6wBD?WbY3nbj5%xJ%Jteo=H#nzS5mk?Sj}pIe^R*_d6uaarQklh=wKZ}zXF8KS#6 zyx@z4s?0M2KY`FNZeT`&%4Cg-Q@6pC_UwG? zYvPXo$sjvQ?1lHE?%e!?qGg$Z=1(tetp#xpO<3yhQ6AG_m84yPA=vL7#|{`g|5i0= zo*oiCr{iR1saCB=m`1lbhx3w&s7|@x_hGkbcmU)a>_hK1ZTGSd?gGl1&q}1KD&B_XfHcp8Mdf01?H?YAtLZ9Q${^1xrzh+ zqUZOTnGGiyUlxkNYD3|>I>;nYlbO!@9n1*DKrNk`j8%>OAwbfROXs6agpa1N_Zw(9 zPf9>jc{{wZ`1)aEYkPwQAr^}718f7Cqx4dNZo0p=rdUwP%s=Ec2Z~@4dRn|UzPc1M z$s{mq9vIlN?(fVHt887XxVdq0b8}A%-<+M1_z3@V07GC*3cVrCRhh|we{YW+q9;FM zM!$j-Jkc7ge+)f8Jlsp@=@DnC7kUdVU(>3+*W>WKhS(`zW%g#kosi~apLCn9Y|3o+ zNBNJE^Rqe?_P9h)3@j0dQX}38p;(oTmOI(|W1-B2e0&7pJfraPN~ueU;CSRcgpt^( zIwT3>c790KUXcy|tc4nWx0yCTI|<0G8I!N#cImSp^ge6@Rb|u3ICfkIZFgPx_!C?ifiE*G98Qr z6`DU9+#EZ;q(pzrH*e>feGDOzcp*p%CnCV~5#esrw(OuG-@&7kMzW}gK|f1|fHK;0 zyv@yP=C21Y*cXczYYdQiSwp{h$0F{z2QY`&0l2bOh}FT`K?_Zga#}7CS&@7yp8a;( z;Uv2E%Y?d?vOA#6;~v%dvGcJf!l|QPI@WdN1=29iT}L}74POlH#{%A$6GrTi(+Dc= zc|LKflyE6{^x3Je*`u7)ajx`awXMvTg>G}mqNQQZSGmII#S=5-RC$p*JD4ZFwcP}Oxrhw-aqc5ex$i`998M`R(4nPpcXwInL8+ zJI10kxSc+i+GO3Zg}729h7ZbKDA<6g($G!q?2zM=68b0ZxNXRQ)#yQa-t%LV^xhge zo7P{pi2F<2@^yD_dmRNAr612$q+V-j%j8hvZL$PvPp5BtA2SleN)e2pRBkBsGWFE6 zYFDY`XEjB8y0qWv{&!3JBOH+Ei8v=rwycSmkWb!M^@PV!FZNV)P3Y1NN)1s)~Y z#7-eU7ZMDxULR9vgA|3QDFa}O`NA!m6talL*9A8q%Etv{C5jV6=<*MNpZ=^8Lx38_ z1-mOD0IUo{GF!sA*#sm+;dw%SJJY>V&QDhqD+)Vza2a7&fMf3x;cTduY@8gN*N5}4 z<71mxGSm`?+lOg3at5}nNpsI66tYeC&7r0s+oJR8TDc_AG(t6Yq!U(7=@Zya0_Ct(4hF_NgRyRS2Siy+oo97~S=)Yj&MroC%5m=+0u zP_;s+`C$W=#rKl6GI81gTP^1abx&&w+dLr@1Ds1D9qdmL$y4~o?)FeG4`)RebiCrz z+dsURIdFx)_nev%G&5T}h1q*1%5FN727jH!Jhmu5nMYKi-JYI4g72Rh@aD#PVZz-o zx4!9z9YpV9AG33pD{p_=dNzfe{i*5vT6bCaJ`K>vtKO0zY|yJolv8V|VYmBycHyTI zKYJR(%Cw&h8JJz9_=em+n@`5?4MuUmBRIpZ%Lr^XdY2C&M{_k%O9HA#7Y3PXz&!UU zDUyU@x{0eT5%XF|*^unZzk%Cc4Wgv5ee9){qg-p=Rp{i=Bn~e_vw(BzC^RDSD+z$B zvR3XvI01jI@vjVpf$gha$mQmCbTo9-ery$oqBsO%;ttUW{Mk_yLv*RH;EysLkfzy( zudEyZ?Cp!IYnp9seso_L&UTV=-*=Z}R|&8pUFD`qp=_=6sUN12is38!kLErxn$JhOtP; z9o%JpKf;!v)Q^hu#p=u?UcCyI-{y1tXM9D!xaeYyA0buwT2P$pG^}Jk#JwHFk8RX{WhH<#aKoSGIa)19wsU?QJ z>i;aP9OKL%N+)p|n>8{FW7-;s0`*soDJ*wba53voOZ;5`8#76Wn#|yu0PAhgGTBa| zD~eyEQ*^e!AJq?=l>~LktxC9;O3d~?VtAzJtVy-zOxQ<`#HaD%+h?e3Tpbe_I_;6# z`Rms@4HW$R>hbgo4FoaycQVCKS+@x!8^5xdbO)@a7>RqvL+E`(+b7 z=!w4eRPnj%CN|rF4Ss*96N)WSy#OPC!Y$aES<*o2jc%*mi#$F)vCrKSO)^^-B!1P0 z5|J20desa?o&}9Znm|GjVlJ$#M8Wf`b1yD=L|HAlC(to#af+6Ztgfz#KT1wT6)*2b znT=j%vuE4jz?=~g+~@tt-VQ}(4ZptTU{_4DO~_0fuaPA@GxJpV!dwRln(z-98A6AX z)h~!^2zW85&7}8hNN>Tb0BBF|x=3zIYj^1u2@irZm`vsdaBaOoOTR2FEaSMgyE~W6 zMld})i$JMFX?h?%P8NOl@I0trlrk(hp(Pz26wSZOB-KW>lf|*F5c58y3IJ69E8;b5|ZB7M~a8ZWC zwc%s?1&i$Z+4*RDTS&_F)M~DBzQCue?gkE?zW3%w7ILGHJKZZM&;>tEaNTpQZsZrw zPXL^Ugk@Q3)*Yd*6F3BpC>5HmB*(AN!J~OA{ zHzb9tWtBP8)2g4FY(dX#Nnc$3+(NIgGVFz&$wuS zz#qlfG$RnQ6`{eIk`R2}#-5fHx>H1{v${d5b6)ba9I*3R(&Y-~x-Sg;UN&282OFc< z1JE*#U%ZEb>&78+DIL}0)U^!_E=Q-AVXa;Jrml^>iEaR}(2UR>y&_I_1on29IUZri zer06?R5yq!=)p8&;3V{9!38-1d1d0gA=a9WXNqNLR0O@RjE|f8ztZ`WGW{r>64pFa zqu^EdHb@bp|L`BT>J}J9Lq)@s@Va-GVAO<+FzwQC`bmo}LblcHdrx>7;5(k4Gfur^ zh8Q8!4i!XD$0Rv`KuMG^9fgQ|qt_ygEaZ6>E?2NDsU|+1f)YlPx4yBRhRLYco5cd- z)_x?F869E7o{a{YMKm zN#ucmS-&m1%=t!|L>yDB-bJpXY{ny!hShrd8QKR|ZL zqm~pzN#BSP@~l<(6u!J)RtLF$!6jOwQ?K1?wac*ZVjOxqWe)7ok(Ptqa*AKLn1 zs1DCEhJ(KOc7WWyI5+2Z6yyYY{-VB=Wb-51NW*UFH?194h**4DK1SFNd0H3lG6{5% zI|Sj|H?3^to)?V2N&gO`@E>6f1w#K|Q((nSo6FOrP_dLTcRD*D%j|S^b|x(?EErA$ z>&@&qvuXyP?HJ-3lL@S!f7X(7P-$mV^uk5qglaG%`aN7k^@mZ{Uw7OZ^M(oil5kFK2WFkx4|nduDOu&P*{TPtmqGgC1vLoR8Amu|J#xY zjV>l<$n?wNd;Icvp1Z<$_1F;Xaf|(W@>V2Z{&BR)#oir7upLxbOa(irk7qv)J2lzj z;mNvQQ>puSwYR-_lAUdqzFB~fl4jj{;5FpUxZ$9+SrSC_JE5*vzYKT=X=8n_ryZ-=VJ?#gCgAnD9@W_D&a z!+(5}V%H39tya*U-FjSq)H~Acz_7KQwKpX0(GIOZQdgznoqt!;IB>zd^Cv}9w@On= z`C*wWuUL!K8%b?Kbu@OO5ItwH` z%^HY^N{}`*+VgeMWwWnT4H|t6dk3U;WA?x|@hbzOTd5W|0~|x>iAg0X5EbgRHvt&O zL6w%n>#nYWMq@G(}K{|bTW-{=2-_zt~EEj&9NaDg*F?= z8)h&wFY&0*+KQ6)M(d;Pe@|GweO1&?yMmg807QgQ>Hmr*c=vBYW&R3e^GrZdSHh?e zJz=f36P)s;s|>di>5RAk;e4&AtBVy-g8a-S_7EiYQcC{*L?2{!B3n=Xf@^B-Odxta znk2+M58paxpqk{19`$;qVUsJ{2j@` z)<}u0q1|4%%7viCBz}gF4^ywG-4E!ZJUs^w)cHjo|C4ylYEQApGdD5Uv9lRNv`|`o zO51-rWmjhYmHfvD4eQKz?$EMy#C(pq$Ptpq;OKTHIV2r4Ril&3$R+}JdqV-_iI=Y` zU~#LnxLES??93kl!ZW;oN0OW9{Fc@xed*F$13Wd>pL@nWKTahCe=-Z~wAG&C92|TU zV8-bOSYNSoFY^5$V*GWM~dfb8OBNpQzYlZ;7^8D+=xE zTZChQbzM(~oLbOl88!ZUQ2*qJ%;tQM-a0uvj2O;ngh0#F6Wo51c9sfw1~TXKX2=D1 zh_$o_BOwIpu#X`Z{|Ht+Ij2?Wl7pnyXIGkJT4 zu8Bu@>gT2@5qNOdX&lsjmFoT9j9j~ClL!#i_}M5cD}OYqGQ53Ty5FzVI7t{azhQaS zzc5{M!O>LHkWb|m{J{yOQOd-cmz5uC%@30ohxgaAtZZmaNbn|c_srVfp4mFPMF1;i z;!A9!dg?EiJ%f0_y!I}-7Mx&gmG}(z7ufri)xVNO>~rhu)?szl>Rjro2Acf?v&JMW1|6v0Z==ISS~)eUQJp;s1@}zB zqWL%D6mAtC3)utn?NiuCZJwWrAxTMgTKKH`;+{@K)Z)rr`!oEuhBM;Y>4%4{K0g4} z)C3&9T{0k@F(@6R#QO<~?E4i!k(8<1(*4dTJ#YExi7j89PQ%-}h~G=(6^Y?r6v3{p z`{rijqoL}+Bo%t_Q9}j@T1>DzS%@oZLK)&I(&h+%NlW{)3B5jkkLHg!X$~@jiNtYi zNQ&&L%f_GL@S;NerNXAB(`E8w{f_8#S{8e!E#&P>#qw`rjm)oK)*k5<-2T+DC;#~6 zlj3C%Ai|$GsBbs_ zntU1cRgLRstj>2xnSFxmi;dRq&W55LHx*IfKA2Tcr6nK9fY|~IfMs)nyS}vl`Fz4u zRIqZ&2m4jRsidZ)p)|pk>tC{kJZw zDk{7)EY{{C4@s42($+}V$ROo?=}6GXQ)!MNo{}kJP*o(1Bxz!ju#*PGXBdrbO-a5j z;BGWl0nBNNYzsr-=CV+@=ND#V#DWHVSPE=bdMCIUS_uOTL9o z)j4~d9Yx=4XW60GdiXd91nyQ=H8KJaRZ)}WEzMgx#(5o5_qKQSK=NIw4x|pwN7Kgg zrn?!^OCig|qbQ?Qci#L0W-w;)`coqk;lnhN;!KFly7J=GAuXs4&f#RlG3_AEgsH>T z$L`On-+HZ%?^EEP>1U~X{Pl7ip67N4x5o^up&(d+SH_tCZQfcz{CK|E^w@QOx+HfS z(FaU%J`xTwKD!uN!xtGouB)m1 z9{|!oEx(>{ZM#2_NIYv<<}Tm&hcM-qa01S8OHCHuWWdM93t5rK>i>dtRn<*M!XfT& zNOQ+PUWM3&hpxEVBU%4dpsGzMg)cT7)Df8wRgJM#r) zczmJ7et8gt__{-BwWjWP-hGa3-zTfu&7n}}$A)31u$F~Q1^K9sDBmc@qb?FglU;w1 zj(YQEuQ6XyRw0>b;qXP0qCh;E;M?#Xb{%)7w!Zd$+qR!zhO1MuEYtF0S&}MLRqbeB zxbSAju@kbS1RZ9&@KvfWs#*v}hKHf1wieQ<6h&*ee_CSO|LB5eB*+EP+{86#O87LZ zj1x)@*>A<6SSZ3%Pi=uUXRfC1a{25u?N#=H?9LDvNz(L+Qx+9kLBxvDHk2Ah!8Sy^ zFX|O>hPk1!ff`>t^(7*cRC2I!*%)8Y;F*8Tx!o8id6|p1+1gSb31fO4V<|Ch_rvB4 z%6#w`C_mG*k6&`hC7bWKp3tz~EK@pmzhNDrs@Nu6C)z~Z(qVYJ^IO(zCOz`Y6 zBJkK^Co)=Kq{uaYT+oe8j39jlHeVcAy`jAu)=PtR1QKLSt$%=1UmSWrXSGv2q`?J~Xw%->e@`h1OO%-VxPv-{Z zD}^A$QvfU)Gzx{n4X*3n;P~G8hU@;ummpT!6Qc%wWtZ8YQL5*9tPU1@3}{M-W_=x6 zFt0I-eiz-T<={S;QmUAmhoa1S(pMZS=xT;gries?wKO6K8L+pDD>;4Fr%4nCkBNe6 zMTVI|j((5!Sdwj0BS8%Xx`_=hIMHIOXASG{F5Xv;vgI39;cJ6WQc3QJLtF@ zC6_g!rKN>Zb(%o297v#R4o2Thvq)=av14AgBDQ>5C&Z%0(j<+lZpr5J2!K# z>-OziySqAPaBR}Z<;jgG9E}mlCzHt})=-Z&-M~5N1q&BYblugph`vk&UOogNoVN;iz{rf&3BS6AgQGF@3o9dnxVmSpOVEA*O__RZw@dyU;{OrNnH zyK&=ruxaB)_}`!Xj76@35MK!dA)bN=Gc+p%ghSw^KoH_745s0mot@46Q5vewm1X%8nyOx67>0^Y&x#r<`Sk(Y zzJQSh7cO&08m-K!hVMox_X{jv_|ES~yOFVp!6sS)1Bdy|e6)CpHti`yglNHqi@g%K zPJj`sTQGkIlp@$xP5dP$Y*VEcl)Oqq+u)wQ>AjDG~604gTy8hVo zqs9={3bEb@k^+1C`=Pn95#q@tI5?F8{=7qt9HhV0nFgseVM3`k`&%wsjau$~ zNbcElS#tjw85yOBI2MWE#7^EQ7Jq5k_6>TW@KFE${mzo^o|4s>S7zt$v7OQw5yle< z$mVj8PFKKr=Wc+#{d?g(?|L^ZS+)$WyY6~ev}hr$UbTv%&@H)auyGKH+;v{w7Da&< zg&@S!1uU}gJ?~(?P_CV(9RSb z)3edr5A}MuHq`SWoQRXX7T6}qYCK5>6VptRo;Xwk^RQ0GHX8y(J06Xw(d|7KTr_l$ zf>F1z=^1EjXarL)(gwSLgo2Sgjg8}Rk#*2eLV}7iEB|Q8dW+;XvI6@K43dtJtjv(} z%T|%{*<{}2D9t&uebC%A7Nb>-*>UkSnmW&B5gO|2VQgX?viV~FfddCFs;;d*L=;ZZ zpmxNBBz2l`p4l)cWp3|ihuOJVSaaqY*tu&LG&MB9==fMk0|_M!Bi)vJ?$0Coppjg(K{m4H_`y zdV{GqI=T?Kcpx!%7hW@S9c#W8=ex8$59^1dVf2IAnTJ7@8o1ox@5e{SpuMe?($R7^ zY)o}MCrCGm^cbmOI%%LGE4h7JL4yXz>=bOoXfQZ542u_cKz=R{+tc}&@}nb;lor`KzR?>j|#kcoOFcfy9P*#SQ7P`fC;oM+Zys5 zZ(}$X{ito*f2yi#4U!ICa7a`Z+f5S8+%i{cIY@6&Xswb~&@I&nWhIchl$J_)F36ZV zxX2dhtU-!hHNsjPb}OE5V(0W~$XL`uPKm0)}iiNG#vcyN*mmF+#D zE;Mfd;Un7)3>+AswWqjKg|DfAvVAB=M|M0~8Ail3O&4H#?SLn(NoC>kDaGpQ@_6e2{t#U7retg{kr@!AVDm z?uL(n^3Yd6iloI-oYw$8YrJ^AKQ=uz{Ta`3zR}vz{=s6g_+iiUTKO29&enC>b}kSi zdj_Slw5<=g%tIp4H0~cpjbY#}6O6wFyMcoy4Niz)8cx&DD%K8zdYQ-4QC#Yd6_q#b={$yz}g_R2WYYqqC8b5vZ@LKcdTf^a=nz z-BaE<<|(zT$nM1C^hdXD+y3nZ3m1`TuH^CK1kq|$Wfg7NyWmY1z|_|} z0PMR5q-c#G#n%wzSZ(OzvLby+@}wWilJbxQ(B*5BOZ^{<3f>8kYfAX z7As%}(jZD~JD#M_l!&ZIL`>0m48ZoNX@f#>nd$HXxsFHaZZsOFy5iLA97T$NDK;DB zvsfd<=2l!~cK-9}xnFX;!6pt8s-rtFJUkAKjSb+s^LtZx#K>omxw{QN9@>22?FaTB z`nqG=-wq<+`KSM(&YOXJ&2=YHRDx-?VAdPpc~{o3ONC zn}y(f$tlNSHBgmx>>+rK$gIPrNS&f>GQtgn<;wgj1W8ro<*hAE_~&}l_I2C!uHC+4 z$1N49l;}wR0i1M%sOmW|HhlspY2JUoh!jr5WgR~#J)qn51)Da(ie*b-dS>njxe`8xZ99>w>Y8iU ztXcE^bVceM$+wk!K3lSQ^U70c7OipwUotMMebTo}@OzAC+1~3T-WzOAQ4T+PbyBMmM4SO_xD;f)g|0N{o(+YmoQN!O zT72XP38E9R>ZiewnYe~rwR*fqT$K4NFm$=b$v0MISk)~pf#=(0)d);NvVB9ufC*B39O589{trMi>mI;33(AIm4|X{I_8Fletg!$aG{i5n$iB=X~hA^Uizq z!;c(zSDL1u-Kf{n$$(8th~`zLmEtCVB`bjOY?`D$pT^0T#wNFYFin#>No{a%ISOfe z1$B%4FeEFh9@<}_Bqj*Jv2dRky`XCV;el(cR12etH50ErtVz&Ywx@7YuBV{diM!=ZEZqqQbHW!sg>f` ziN2&$6vq4^isQfNb$bu_e(>u>QM|B#!t=d=KBv%93ym0zTZ_pl8Ds3&}Fpi++*hDbo zdM(*1X--FHkF|xU0M30zrXYIAC?O4 zOaJ(fM5xdGH`l<->>SL^-w%_M+m8KZd3m1y?DaqR{CDK>V9c>O=LLA3u`m{31y9z2 zD>%F!s^SX%I}AVnGisNb9-`0H-pcX{_a=>KU8dnk)Giy;+V;?#0zW9)?N!>qLE>$% ztiawqXWhQMwDdbgQT#pzkZs)SX>($e6XLK^99;Jf@Xxve+&kZ`$LA9TuCC%Z`l^+| z%WIALwP4wQ7RT{fSh3)mTuK8CLnyRb=NjjmUcXOdINI{4cjh{_cyiJI$agVK%M1`Q zKwxuPJXqtpOID<2NQ3@_s13x&%2#0fwuzEh$rv^>VsA4QHjdLsAlQ=(FeD1|p}7ZY zEWvE@HN@PMU8n6LBE_G1RYWfUO-~Opj(|uCq$%P@3T^y(9Ty)`u ze-+2km5z<^0~xI{azR@5DJ3=lD_`2&VUu0_K*1S0k|H|&&YfW$IeNlO@k4vj=-XA7RZaz@(ZiccDoIy?buG%WC$FJ;HHh3 z%97y&PgT)Cp;52XwdHb@bcVrP?X@b1>?4iO_J{1j))Wjuuq)k)0XuDdYAJRgR9)NE%}sb6Y$rJ6!eRfM;&jNC_Lw zCgf~$hE=l&$E({jME+vw#vd@%j2gV1cvs5L&rBV@^w-|@D-XZ_eIK}NdS>eD8}vfj zbT~-}5lT|jLCfX=R#@%!>Vy8cd!FaIZ;zt*W|GrHCUK6exC&0Vf&+L<%HN-40w`s}{Db{cmu1=FspzSA5)mS(Bxe(X zdQ^GVjs}Cb`hM`|wrzjTwya4a8Ir)*Z247`Z(hkxUS3%tf|{J1gnqAQj@Y&f8N}p@ z4eXbQF5XzFp*9f*B(-`#(jC`qjeysv!`f;aOk9FrRznWwKM&FbMq48gr>58D@Prx3 z14+5t>k*0IPz47ziz_R4OifL_3oFm6RlkWBH6|B=dQgKm|H7N#na}#Z-(Faly9{M4 zQH1y7m)kb9eUq9ay2}$`tbm2EJgyi~x+A*6<>h6v7b9!1X0x{Sfy)C%t?57 z9L0X81V8l$gCh?-^w1k|u(M;wj`I28b$2>zM2KR~k5%Yer{mU}jdv_A9=!=ALE;mc zWK8H>9aA;NLTV&(kM^}qm7A~zl6tA0M^zzC=^KrDXKI^QdD2jj0w(WSGk?j`8Nl1uKmE>4Y-i7ao6MbQ) zJS@`)`%0ds&yM5xPSbQ8)t8I5*mP}$ zSqc2_Nt!)g;}kqWx7(rbZyTQ|zqYcv0xx;d3tzeK+;e{&tI0AQkb9T9;^BxSUcEM%RC}TgW!a7#sl^Rk2vMrX>itR@ zphq7#9c!e~xcQ|odC~nJ``9P{!eQ-Z~P;ueg3^*>7Zp(fGfpbuh;vjX1)GC+i^eO z2f^jiz<0QrFO7fWLuP&!$!=w3m3nU&;t1`T=UAuOj|JIw| za(5c{CrNi%;AGfn32~ZS9%s3NBPzFT_JK6jqmV5|Ck$9TE@UUiR3Y^077g$uUo6SQ zm;xaoT{1kW5+GEj&GNGj=R(`%wB0hg&LDtZcWv*@|M3^@{huHC$a4=JI()!!xBmX~ zNlb_W9kgsl6x?@PZLfZLa&q!{Q5@gndG7bnV8wQgyNv}#cZkPH$~7stz{D@PBs|_W zxs6B$`-@3pDx`X&25}gdxym$H@y#k55e1qvL=m)CS7CH)6yhkM>2yv+W5SyxYSqM! z;)X|h=Urd;;y1`}ma97?m%V52fydvd5{p`18Y5p^4gt688iCcgW4RrT;bHelut*&Fi z_d-$p58JkHBohKW20J$R>~51;#wS~(Cn%K0H|YH0GK`Il8OLsN!}cH?L{#Mg5{_$| z?HF|1;h-oSW?*R60IQ&WxK3(g`g`VxiSn2tGnM1~!s4IpJ?ESxndms#)xB zR{mZMx_2unh(f;dC;g7h{xuP|RGj!+kaT0-#7X&sNLm0m;KJVreNfmgB)O>?@x$ZH z(|5n@tTWGi)?IhqbstHkwlKB`A?oh)rUu1>`u(Yy=~wSM{q!%}1zcirFO1x5@ED7c zs2s(K)8kq#;ED=hb*)2$xP8YChz31+)3#boivO&6K8dq&!b={Fs9AK402=)dJN*Ip zwFX5K;OZOp2aCcUdNd+oBqTZc`>N&;c=IF*{9}eIJ-FuTYhJ&&wA}I>;2^2tkrpe) zs@ZJyPa!m%s2@1+==#W3{=PhxZKn2RAF&*MRPIx>lt^+&c2a@TpG?rQxl-r<4SmE;^p ztov*cjT`3){|mr_YL;e$BFldy&GQdgVEquStW`qUvC8v(m+Y(Jc$mTBQCvVmCJf^v zO{fKaIWQQ6k%<%K$u0EkAMdfp4nAeQPL9_w%+og8 zBy4l$R1*Khs!Rxw?9TYOEze7;Mma9ie{|%|Y4GFbC=D|G#eO(2)nyt(%?nJ9Od1h! z;{El*KK}kL*uVdhAARJ&V}DiEW^OfXF+$Yc=cfgwpx2^`p@5T`(kOq#?sMT1GuS(}$DC#!7H;aS0|y zTBZkSvv!XvO+J!Rg~>jHX--D8=(ydrZ5Sb4UpjnlmYJ?Dwb%Y~q}eQchrm{0Yu)ZT zJFh{1;M{!kn?E`>(%2hwn3hY%4a0$j%{zF~_p^D31H8A4Jwq7|RVT(!8JJWf3_RCe zcVw0-QL0Ii(@31Ed{6GP8nsF(f-G2%(zyJ$mD?a0lD3olB~4{YA7ohu3ybq`>1CJR zJUuh_SM}P~RdZ}HLKNuk^LGMEsy*9~6S5W>w4yr=nkLW@jSN;T+RVVOONBzmvIvI) zH5eHmp$(HFj7xH?0{?dC;5W^`kL$i`-}%pYX*dY?6R}w)Xv)Snc$$F=h3WgT83Vb) zV1*X=&>Qr?iCi>YE&FwjXGq4Z0T$)@8xCFSwE#NpHjIz7AWkAC661#BIt6sPozLe~ z>@w*`5nO)RrEtOd&sf(B%(DE7OZQ*$Lo17mL?o2bSGY#T!$z>x9b%U=Uu2ql=*hz* z78ilK=mx90K)D}@H3-O8GAk=XsSaKKz0lLm&GQwq#K)GSHhtJsJ_KyJJr?JVO-E(l zHLHABDWadHO*_~4Z=aCG7@6kQYT!A+_crT|^LoAB!Hs{FZVa|4A%gBc9}9lkCN|VE znI|;dNFa(r8ZIE|;n3pnHy^LaG=|4O;3}rtQ>$v}P2E750Z8n1( zolOpNG&eJS<>dAqA1N$&33}a=(LiW&pHt2?!N+a{#{R2@86#+D;2OzEuh%D|27L3% zaKmMhvBgy*I>khB0`+E{%wSQ9gSSi2pV9TO$M|=S;~a7-!xSWw#||EZM-L9)_jp9V z{<`aKXfH3(mW_~{RXOg;*RqNb+Ek4;tSm26E={!;Sd{~nCbs$TYo$vzZ|MY;)je{{ zDOhrprBq3hl*Y14GBh7#=0l6f+UCl$FfQbH6qac?UN4E!3!|l^+q+IV48kE8YMRb} z#(6(HJ3IIOt$J+U!h{Ga$pJb3+NA44xd*P6p;EXiHl z)Hv}Vp%u5a)ecyN4XtK_`d?V3V$V?4<$xVwQr6jF^|`pR0^?)jL@)uGxu`3{G!5T{9RG;uJzWb^wDb zgHk=pphb))ssxHFfIg@5;n6*cP0tTY!0w<&l{{8_b-!kQH#O6b1a{RKL<4R$uwF4u z%E!VX3s#Cq&iFxq-?uGeHMV2t!OeYYaEI3XIGN|GEocA1`22GL*uaS}q> zj_6HB$GwV38MS;*H-wO|G8-Eoh3Tm&vbi_GQ6^yzkDPckot~PS-+lTSzh}ALo5^Gr z-Lt6&X#D>`@{UQ1SQv*GG)%}+B81Lbhr;gBfm@EEF%Kf7x}xC*_SVo$HOrvq_Ml#G zU}fBk!|0>UdSktb0~*zO!`}-M!QONCoi;W$`n|yVM3nASt+(X&F3-QriS~UsdUTEm zi3l%>*16Tt@tA!LMIR{Dd3DetYk~N>m0^dFFmUCb@X;6tLD&WvYmJf_hDCml5u|y_ zj^Pg2h0Q*cK;Nr|Y~k||t2;mDxp%GI?_&|d3APx}jJ6W|me#H}sK!S^5; zp9TT#zINBvpx5cri(0g4b|rNVj;a2RH^>^_GOKI5&)iKtz{ekdqTJEN>sne``t4o2 zcfT3?T6vt(W=b5Vyt|x~>wD(@Oiv7tk2HAkU9#iHH~Sb(lJoM2h{9)y1xS*NvQ#Ju z5DW>pj`Iju)(jGL8GscanMW%DHB zULy7`pM3JLA>?8xj5gUOR#}Y-vC*C~Mhm#!I;l=cpj;&aOJ^ig25*PNTW9Y_&vqe7 zBDyamM7lOyZ?ugK8a~rTt7%Ly(uAr=+HOI+@*Fo{O z97ab*O*AQGy~O1(p^OwIn|^Z)>~*7=rNspZg7wEgJX$~S;DhBaJdNzmBvpdhRI!3uKydQjC zctlRS31!=0RZYVd=}lq@h`04zA~x#Z<{1p;O->COH*{9lOlD0G(Css{CaW4j*kUne zvY~sul^=NG&>CfH6YF2usw%ef6tf9Zp#J%?^BI-poj;N9DoT*f^Ya z{%NqdyhLxhPPhA|*67$@+OGQsa0(MXkKTbC$S#&!MPyRua@uD$0}R@7!I*$FhjzC| znnQB9;oh9+4qb^D;NM%GrcdnLwQG3PwSbPc&$;Gmyq@x!gCMwk`}p_;#tU&MZ2>;k z9&5a?ys}KY&$thqvk?TDN>p;51yq?8Ie*`#mO@&Q)Rd$t88EDmq*#VtAHu<)+`^$X zM0N>B(sQ{FNn1f;^1!Ns8b!Uv6q+R_wb*{Z>p-y$4O!|9s=(2q+am#dMAh+WySD%6 z0}np*OKAAB;V+=$j8ljZ1)E=zBh{U38a)2^brT6k%??h;%Xv`D`o~4AiWiXWF1Wo|<6Q2dk3BHY=JI+@{j?5vwNHLHdt@h;@j4xo6 zn1E5soV1YcrLoL66;GaJqojR2y#mPd(Bf=k$&tp#o!B-JZQC~VH^f0nud@aV3(MulBi`4GUwFe6 z7%NZ}MazzIIUSB7SXy2(sdzNC9qtxaH&Da{$8jo>7Q8JUSv{ZJyHP@el^PLP60@S+ z^gS0Aj0Tbf)mY78%z|r%O-P((6)`0u$Dbjx=QfMk%rW;Rt~f%9avgF^&bUIC9x3K& znt_OoSgqmL~#o6ul8f>2!D@_^F)R0f37SOsM66ujA4-cv~UCT?$ z@WwaX1XYs6@1K44*%#u53leF>yTMWsqJhG~{JgR5VlxCh!ZvDk==QoqX63MjlkTcp zB&7y12ME&$Mj9<5!JM)HfgE{StrjdSF4E(y(->mEvKExXAFCpnk_wk(SA_|zqO2P< z*XuaNN3KJrL6SraH3%`z*qvU0` z8IH{-o12K^I6HRi*m0)gI5*h7cZLg)S+?yYNn$5SV%e4z?>+aNODx-NIgaCmX@bh| zaBO1YlHOp@D!6JyonglAD??`(GmP+Am`!;r;`0}oC{foBAW9SP9G`|IE^S?y4C8LU zN18g@mQ_7~ZqM`qQ_NGT*T0@rLYngBWq8)JE{8pP_6(n(WkGv+X<~I{(WLh=iD5q% z!{Lc|?BSLPIm;vo447ajTLu#a&32Bd9IYV{5}6UXrL-}E0}|U9p^*bPwiFH@ISjpS zkNSQ_UkPOk04K?$BQ=qIrjO~^R6R;=3a|kL5+IUcY0O*sFp$;2lmyxCdWRsa;(1D) za+Pga)|NC!Jf#US_nL6{#*e|-AOEpUL53$AxYAp29A_blqHm;O_zRnw%||Kv6DOWFzkz8|o|)lDxsicuXGWauI&7vICA2QsY&9VbBM31RinVr06oQRn z?joZJs8l+x=hL7d%))XgWwAILC#x97v~BzLbrPhBi3#|-JMN$?=q=E)6(P>K|N0ZN+Sqh4d$PJE9|`UR{_#KfLlM&mvvG>MBZ7NCcS?D z_iDA^5A!sAQIh93I9YzRYdIHM)St@DCM{{=@-q6w!~oJKq@uWk`-mpXx1Sn(#^p|V#ZA8D9Ws3Hgi7p z=}(svZN$v%99(?y1+}q}CT-VLH(IJBAzxd!fl_g%&I?l|7M1>~#2DZ)AIYBt)40Q& zCN!a*nw~PT14LYQxg8_DW^wL8GNk?=uOG(vHEa!F^~vE`vOR;9A62RNJS?-{)Dk=VJ zAkvVch~g;zn=H@&2K#P~?LMnkt6vWQueNM^KlKFBbtNy#oj_|{pgM3IfNQEpBty<9 z7AXo=WX83Id#fm0p}yXb$V_G96FK&?KG;Y&Xh`e1@|Z;!MformASVsr3$DLz-O~!g z2=9M85(`#*X4zQja1fIxVwxHqA#h|Vwamz5ASUOPD9VVS@HPp%;KZ@G&19Utl9a@QMib3e z!;lkJNVaV`_Rx$GPrX=4O-^oG_gsirJy5e=3ggu*%@L8Oc z!Gc~emtO|3Jxvsv5w7xsroKfeG!XF)Trn#@o_Q1u=GOA zGHPGo2MZD{wjc0GV9y$l>`vm8iUuKi;I+r9*CPT4Ikh0zypz7~0!oOC+;YH=+IoC` znlUuq2M7oK+ib_Z*Z2L`6b0Pq``#|9NDAXLjRhXA>j6)$y>eJ!MlaY$#B@86mrz(0 zYV^>?icAq~CJ893r9$$bG0o3vnu#?ZEggEZ^Yx)If@Qyy0}R*WR6u^p-o#Xupq(8Sin2*{BeC(C$y%#rDKI`rIS ztxq;%pyD=EmH$XyNBl`Wdg+lV0L~Md@rEi84`7?*@8yB zQHsYUsXph4b3W{>+4UB|QMMXNa} zB%5J>#Oh`eejO`5l+;WenWDr&FR0N`90xN|V(h^(b{WS?J8ylkU7z%gD1^uT zYm8FB9wtt;y}*O+T9+h1xsan}L9@~PhYf!bZ2*)IkAV(ajz4I>Hcgk3Bzt|Y+xbA? z1@Ejm_KN`DxOj9aw{3+;`i#b6Z(K0!JS>uGhxE04OCV##{l9yF`H8-z@mZ zoE5`kr|CPUB>zeBgjxW`ddnq}LZU>c>Y14tS{KA4?6JvqI4q$fH}+2}5e4F?gVo&H zS_c-Mn4%AnAQ+(!0IaI}_#pu{nOuMf;|q)8Mx(sohyeWE*1+=&$sU=SqdsP{QG-#6 zY%mFZxJ8694-V$v0K^;dTG?nQAs&l=YS41%4*I*|X@q6*Q91i+YNs!DJr6T3|1ALA z3;?4ZRzlSCGQBqk2N{`JPqWxpF-;R5hB#&ug^rOxdPF2eOZt13@ga=j5C#LAWH-G* z-x?nqyC}=@!*WS;^YifYZ+a7KpPVc&6Mt@Pt)2Ax9q@Px4AyYyfL?<%$p#6BvQ0)a z_VTzl2(B5n33YGe)JfJx|Gflq} z$KeS$?~I#NJ+lW+gBy|p6?AP*<*`UggBr!icrgYniti23EvH+G(0A)AEx zjY#x*biYi9xB-F#A{l_tMAmoM-8-OTaaNcO`Mxzc~(ZmW5oqN1W zG9K_I3GFQ7^JQ6*5SdKopFDDyo;wmRTAPKuVpnj^vdw$(ecYwS+qf>YI~|ZAF_Iq+ zimJx8Xwqx?rIv9U_v;WRDLIJm+_sZa46nNCs)ZBqayjl$Li}eSgO=&%zDp%J#~YlQ zmnCS3=-%Y}{_p2$^2=GC{e;J2;lRi3i3FU&95r#OYmUbfFKT*RvL+|4)5f*h>_HtZvHJP^C08 zw+O!91Q&-%c|pfw$F@j^C?6oelX8cT@F5RrB>yE$5>6g0h%m9TOmbs>VKQeL6t`g8 zKD3$>(CLSev^xh6Jo?z|Ti)`P6Y^3yo=`&km!OiIjf1SD6;L>~{k2}V`zpWQ_*x8J9uq3;JKLnJZguQunH7%7Tzv&P%VKn2)P6=OqvlFme&AyPko+rG(CdxxUr zbI&>xPT#e2ogS~zY8>DbK9qsZyt7qBv=*7 zF0r`c2r(mhC7E#olByJMgF_A!WTRp3!N;F~kygtDX(eWQU1QCm#mRp$ui+JJXffbj zYW&?v09HZzNh7(DBeP8S(b-4hUM27f%m>FmoPOHQ!HIZ@9B(Kgej89p&c*|W8O8)R z`OrkOb^Bm2c-^SuzBSGAu_7_mV8h`la^X<_43ErMWlDSkC*_%FRP2{QX8LZ94U3%) z_`WkTHGKpmUi#X+wR-ENo21&N4`$Xw}}?Hps+K=~*rKIg#`R&Pjh5fc>!*ZTn+nVyDblZP*| zi9!*qrnguXXw!6Pw(81M#+nXbERfhN67oWkSpMXE{slZHcn0JC#P|9X0Q z=7haAjwh55zg?&#XTxDxvH@csU0q%M&m$uvzvTzDKMkY!ryZK61|+#j!NdyKwro^j zZ!rSjMKxoB-^%a zBTq~`re~FyR~nLFh09LiIq!)(yi1O@aabKzGoHonORlAw-;76mtUj?K2Ocarya^P? z@p8M}{)bj;OD?J?A$})NNzREu!J8Rj7#6nU{)`R9?^u@o+D>QfjkTaw$Gm3J$XUka z2J=&l8EaO$V;hp>(53=77bQD0OOw$wiPwYx$&uPBDs)Ju4ZZvC|N8sRJ7>?Yp-e{z zY8cgOty^=GO%XZfR&!T?dwSLF5($K_}GgTq3jUj^O>EUC36X^(u_5vP0zz} zhAV+GK~9<6+)A!>8Pm!!2MJe9)(e5BS@PvLj@wmf(pJLOd{)N` zy8C=WVYGcjMBm8r>=%9Czco&i*C%=Q?;PLXMQ?7)m}kifn;+mrIWjIgm7_6v{^j}U zHP3rl+E4%7;w?TrVvkOY!FaP?N?h>178m9}bnc$B{zDK1EefCKV<=Q|mE{Obl^&BC zy6U)m+?0)z>dGCk^NfUnC2Twa{2@RodbI$K&M&|kZm^({1MP8peA}$takeY#eNH73 zRouyKt{xqB9$I(pOpXy(k~#MO5}>Li8|;=cwuXgOgh!?sM& z)9}X<|^Xg-u)Wn~hghpk$ z8-~%LG|9f;*6bfiSQ;ZyqLQK~*(Wh=&_F4pk)v_d{hWp%wHh6(jp0Q`@dybMCw>i& z%j4tYaCmBpq(^o1D6FjOp%Zu*rsd;MHHd3`JQQg*8qn+a*Hx{uA5GP3y-w!6c)fV6 zE|`3AVm+L48^JjW+$qX5jz8~Ouw`HKN{IhT=%8g2fG4|2mMzx+UhCM-`{Ou%x9_;u z=XqWrt)#$2gaP(AI6zsBT~Ke$M?-}$d}S8)e>F{#C*^KYIx{&j4ilqe<+0cg02Wu* zzPMv@>_=>_pyW7Q9*dbEGoJ1eF|r_9oPEfmi;uQFoZyNpH9vO1`^!j(C=HsOn!iPUpL#tvsgixYQR8L%MnAsJ%76QdV!RU7{_|5;$yYLMga1ACje7MP|qwU1cP zZRATf$#}4OPDtaKJ$!WG=phTXW_1Wkh~Fi2(6Xsu+xAzjqIlu>=;--tYioZS#_<`X zQ{>4hPM5owd+d2-#&H;i-o)t0`B|1fS-r2dUJt@SSpJ<{vOAqmoptSVZtV?v;MghJkJm=5_rasN7XOyJ4;Vfj3yfFmsgQeNK_TFUyOIEZcrv zUcj3uSxmyQuo`p8y8o5`zm|Gu8O(%l49kJT)3fVLXK@?l$n^9t-T1N>U2g-NV-X2u zrQ0_Wk63oeKtx=v#ZcCSy}RZ9HOYTCh-zhJnTX2V#<=K+@1jVC%Io9lbD25q4oxP2 zr8ripCdUA+CF)n=F&i+jtFY*JEx!v9WK%Dady;4mhEE?W#m;KyElHf+GtwB{n19F< z1SQ0$3%dKf=^zPyd6qxq+V(HDn$165?sh%~MX`_aotZpb*S*Bb<6Q;hbHks;iYy^f zbv1Wob#1Nv&Bveo@WmIN|27 zr?Womx)3YU71F8MDeWkm;Ec}hy2JZJilb{werKItMcLKUwOdyBY- zjs4WDu!!h@D&(jXX3Oy#4R^zSNCNYsD87F1;A6jAjZ4_7P(pkfp}WtU69w~G5=CEc z+V**t?YtO@;wRGrUJQBB=!P*g9p~A-PXFWU-|#l|&%|~NF*-U5^9xIVaQg1v8w20l zX4yWZxs6FJP!tyJRs*DEK)oE#0UY|i=@)v?>Gq-DH~G)#0qMGE?&{DG1PYh>d2x&c z6qKuY2@_J)Bvz_Xe4HG6jC_>G%6EQs)d;&AEt*bSUQkY%{lFtDGP5J@mwin6J|^CK zybs;$c7D6x?LZLJ)>Wxn5lVnC&NMi z6!AHZLM~u9pyy{Ul0-y!j3+BLl{gpsoKNcd^Jui|@?^E4PIGFHA_px}|~#KH(=J zbPc)k6!-1e3S^?rLoYvmQp6SQcsK4sw-gNiC`6Y|lPa;T^zFQ=-i3{(6q^&h?>ids z+Qd&Fcv%JuU+0y^;JDCAa18GBxuKEX)uQYOTK{rQ9{H^|6?BXVbN9Ry!rWfa4l zf-=PaQThS4T`gWXEK#%orB_Fhn}zzq(6>y zu$=6I3H0+-KR}76yKQDofN+;;L<_vmoH;`euXH;3qUjHIov7^rcyy{x$?cm;vY^yN zVgj_(xgh7ohSByH)eupi-M<8sI|T1z!W&hv{{)}x++OcpPppw|8fL#QG@UWD_bJ+h z*dlFZFD4>sd+|M1ymqCAdtl#IQDNp(8<%lVa0E2cOpIWn-{2L{kO3Dur*$Wh{4*>q zGjSZ%qOHoxijn~~*2+sgE+%GIoJpZ?{(QFdRLqzj2gD?)a?l%N(V4F1jCu}Oj=o_W zuz~dE`+S%Ne^710GGHMk>a$SoK||u|<;O=;L=!Hnbj7zzn&=g3z#Xat#&&B>^U4<- zB?~N1r2~^lt;ie>4NtzMu0To^ou6%b)T!sN(Y2403};P2OmG zqQLwq_ze57afWr2Z;Eb--|<3BID<;>MU`=G7>yI*d5v1JgwO{$cX0mrJ=GSAy(?n& z$-_kqau9XX19EPt?(sv7C7_!{67XE-qkw1r>ABUl0 z5)Mh#^^(BCde-3MQo>)LnK0y4JNOsU1&0ZhqA@YXK+Ls*DIKP;IUY<3sS|SEa|j`(Vi;At`<L(I)oZTh0yfdE}FJP-C8x?9jX4NgvmT!x5b>10g?U=R5J&&Yodt#Q_;~<>akFW7- zw32CoT!uyi`4v&pR?k;_o4xXcnkg1gn9M;A{A;W{h`uuXYlOQmylhSFq! z(w#W8^dlzs$o2k3ca8BK`bB5cJez@XQeI4*1(QRv+gEfIkF15-Z?SxaMCXHAX}8MG z%yrO>W$IUAz;<#6JeI{p%<8`b5*S8Vk^Lbdu!zhYoyV|@6#ohC-og>;T7e-FkHarT z@>VdmlBHjK7i0+(kMU4)NfPAzGcwrYUlGI&|Qk+oX(>!*I(;~_NiG04sR7|CmC{lTA{ zyST$&TanqvN{Ryt2+%5t7xny9x&IgFjzT}!tfyUn}h;|0d& zEs^r!+QwiuzhTU!`RZF=X$;dqYA8;z|%?NXb z|Mpw9i)%^~=aHC-a)(0k-^t=JyvgDe*`wVt@fd|lX#<$TDX>82L$X*IsuZjBNaUnI zBDwV5ODqBmQnpD%l@bvDQ{c4*I+tP*l9(icL{u9V<%$3c-2d0)--`YJz@#4Wk8XZA Td7;@tj*BB`TSuE$C<6Jv!E~4x literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png b/android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png new file mode 100644 index 0000000000000000000000000000000000000000..95173e46e2639ce57ef9b792188b0f1d60bde599 GIT binary patch literal 49058 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�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 w8xPUhk{2Y!b&_#v^|} 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 Jt7XkY{|_}0UY7s> literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..ca3826a --- /dev/null +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..d047760 --- /dev/null +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..f48d51d37484826f1f634b76d2886b887fded47f GIT binary patch literal 3981 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..efed571b67f41249880fb8fead1eb50cc4c860c9 GIT binary patch literal 2098 zcmV-22+jA2P)Zev}l?baPQd=lZlZd7P*I-N|kim&s9AXSMhhOTZ9Cv%S-0t1&-QMj>bzZZc&de^( zd^pX`&OFcWdFFW?)YH?$aU1}^{~U7?Mf`|8$02S9! z%QQ{o@UXu*q;a}9b%L(5=p3ZKI+SUw1V;b>A|N~8Ow+`P68!LWT6CN%u2dX~O&?dS zWmynHL`x4Lbht8gLtH3<$>v0Cz?DtNh99>q3lYXa7!Xc^z7ztA2L<9U4i2})Iv`qH z;ye!D!A%>un{DAMj$jT5{1WU5qOZWg%aj=Z%4Cdt4HG2+f)EVZZb^V;x~T1zG&9<4 znP_nBI-=s9zYd51?(oJHOFIbDckt*!e|1co3EClua5N4xT0Z)AXnhcyiR+-fk0!Vd z$O$<%3F4%Ok>ZMBS`0IC5(kMnB1riC{;gZP005FCWip~+7&t$s54z#@j^l1S5wTP% zm2Tdg>*-LQspRca|$3sMKaD>@;geycO1bfWR&duDIjS0fw z;DNn+2fj7({P&I>%|FObO21acWi9@(4m97clWonL0_@Ry>~A)c5a-u zLbrs2hsyOxO`vu}w>R-TPzuWF)9+op`0>cdbKTuro0^(CIy%1d-Irf_d1QL}llR{{ zlT0SpF2x!hedoyRN25hvwxqoeO65<7;6heT0~ z#bO;D9RmZq`uqDnnf~I z-9Nv7<;oN-CyfJF6`9NMkV>cu)(0?j{iBb@Zr`3ieE87({6Z`iYj6LG&)0C^!2a#q zzpAQbdqktrBd>hBsVQ{s+&EEb5$Yjs6S>(PQFu61Amlg>E-o&gIPu4k7oRf>Ls68j zu1*M{APD*TkPX8~rBdN=^EZbEYqi>i3zObu3I2(3WrUsxW49*|a>Y{dPpAI!?6U{s z@on?-3vF#}fq*{{2q1)VIjK^qWV5+kPTKd(*JN3lp8k{;j|dzL4H1eVL_r8`*|J3t z1f`%nkR&mi)3oZ@vwuHwY_7LAkw_!}2jsl0sw#v?mW#n)Ae+rqG))kqmIXqgpkC99 zMYU8?S65dfk(T9U%c=I=?4<5x_y@v}Sqa~gq};^Bq!1JO`w}gYNFWe2ElVv|blnJr zf(50Z>v|;8QYQuB`STMuZ_aggcE;n~`}co+VPWC^{WM_}M74v6c;&66x;+EH@gSGY zUAQnAk3SWEI_~rN5aKJEW|&4(C}b2$rfG2;7(ITXp`qc|zxico@OQo!wryfS93NEdkjr&u1C7PxcgP9`Jv_4WFL0e_=!En^fzfk3fP92+~&^ZZ+H z|4I-9P16)bsnu!#fS#WCYp?&{r$6~cwOVzxq0RIXw4UKw!c*k@)YR4fUAsa}A%COK zE{GLbURqlE+0TC*i9|F_lV#a7Ohg$&08HQObl`R0|e7>`Di!95UrkQJ_P$-nkWjv?_g8@}76VD0^ z4bhDfT{+-$MNwuypN&LYw{Ckf7_56-v80-&r5n1cs-|J;hOQ_|r9L!8F6w#>p~nJ& z#%fh3{A)u)kGL0?BHy6}c}|jYxvVG%v94`T`WhP_YxMnlWmObK!!WDWx{@@lmVc19 z0B4zItyW2;QsuIW5F(-s+o-*@f}>f-WC0!mi{m9Jm(6A$f8vQqYqU@(UY(kbKOMK~ zXsYE(#WJm`t{00XUDs!>e?~;ejUwNTr3V^(9h0w45kgMPq|@m%gxvV}Bti|%%}w?; zwNfdUE2e3F@x_0amzEKNOoGUxo$!W2&mUGP+!`xRt5!bz@a&GAJKEdZ>xONaTDfxf z?&8wo5<<{<#lnv>av70|-Fg?i$fC8iJ^?^CYS;gH{rbOV0)D??8fr=9IKcCeu7nsy z?e>_*Y_Hs^V{(5zPSz*ovbt6;@WeUS)ZvZETUBnz+*s1KjK>$`&B;5Bc%!kqa=LtW zYd_Z8FAq*%s&RH>KpUI~<&C~<^J6nrAM*&VDk72Ng9PLq58Wzrw{5ga=$eA@g63w_ z#B(R{I{rumOs^)mFf@cmAh-70Lm%FOfLZZ)8#todeI_T`%-!6R#>CVmy+}S-eJKO- zwjS@-VO#lD@07*qoM6N<$f^`QHU;qFB literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c041604832e1cb73ff2dadf2547543ea84a11f GIT binary patch literal 6509 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 z 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle.kts b/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html new file mode 100644 index 0000000..c22491d --- /dev/null +++ b/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +

+ +
+ Loading... +
+ + + + + + diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..f018a61 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +android.useAndroidX=true +android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..ac3b479 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..fb605bc --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.9.1" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false +} + +include(":app") diff --git a/assets/icon/bg.png b/assets/icon/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..5388f594777081dc16e44f390d41e1de3d43c351 GIT binary patch literal 174258 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 k&h-4OEo1gP$di;vLQg$kP~x^-N1m2P#n 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 R*d&Tak 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

`e0iza0X7)b&*0Pnc!56gs9C+NauqFe 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 z z$K_a$tP?6U39DN^cB9kD%~)7FK{ODigXXRPA=p|Y!T*&^D{35U(>xPd%8-AWw|#S~a$TfzuG9cLz;VHBFXks4Nz%mvY^ie0fGMt_&6)*xA@`T7XQm z&PdAqnb|k)YkdRVVgx3ld{}1D(TFUAtlR$uFjUC(LaP3TgbuTYa81Q)4_rOi!d%klOe%={}T&=OrxwzlSsRn$gDN+`??nXB_w8$26J&3dFdMncF^{*6vH7v6vHqe#_n?wrSJ^z` zNJsv36ukor|=1@X}1qFZ5qLHkpysNbN92Lu|#f!(mD=uc^8pDs+Z zlkOciskc+%ceAM?^6>kB)7x0G)&HnpvtwE zQ?8PLZyy8%tOdSm!o7N2c)x~8AU4xWLtx&b&w{@o4iKv}q?u~dFAU^zpje)jOMP<2 zY6)?p^L1APX%6(Js_IQiR-L+B8@U6HFN+*pRW*Ob90NjhT-rUW`N1Y`lBj%OBTgm` z(zqH~q}dkrdgMy2^Ws8;&%=U>r#}hB8B|Q5yO98v=Z&+YaAY5pp@^NUd`5VqeEG2s za89h7V^o3Hr71Q+KRjWVyg8C_44zG1Yob)Y`%O$|xV;PWaD}N=a@CD&SGTz5KdI=i zB$ElJdrcKx>Dn0!p4cc0=ret*kjq@5qc`Tf6CXaVr<1q2O?@x4hPl7&-&+Ab`G6U; zFt0pk`k;s%(-nx9du&y7#h$H_4n$QxVk^L#%1Vewj9f%a>E-$$VoQyy%*we6J4Zj6 zR9i88t&N~Wb~9_b0*zfN`%o>@&$p>_`!^iEGo>(Pa#i+L z{a6WLW0Q%VI(hDFozrui`+*A|oQqz>Hn2#mQi#ms7$1T9V-+bWOK&RcXuneSjNhpm zvuF)EAM+?Gg_@C_7%C;DzcoP+@?arF|{v)jaQt~#)) zBsSfv-tNQHR-t|~%)*SL)}m-CM0_e;2$cKjX4a1<@5t7g0F@2d!w`Mjd$))Yxpaxy zUiWlq?dcN5Qw?=TUvr!Jt7N<=5nKs+8-;l>rwA2~5l9zKU8x&Z*SA#_7rn`(WjpM* zGrI&d7CKONH8XatkCu*RWDs%StSu^FTiVA+7OFM5Qt1?Ag8Nr!#xhB^&5v@qs3-`< z3Y{G>f}p$6g5b`6T?+WMIPnhS!ewktgN1zc#OH{y^OGKk80|J?Xt zFZ4M7!%sijOnC8ddpP2!hot9(%1fPaA&A_yZ0R`Zh|APs<`)w_)fUP$;0>Nk8${B1 z*En`}SksqLlpY8`H2(rnEcuG$gt<$EBl}@4;O}sRSc(`)A>yCA-dxJIANCg;!$DH& zoelpaiI4oa4uX?+8$`%~768_O867i-Zb~@q7=$HljhV{sZvyf?ol734pAyveM-9tp zKPC6~Y@Tyij_bx1_d}k{6s6+|neNX%JR=pd-S1oIiVnz^NVOz7kbyNI{v(nlpV(f} zI=Oi6uj)?AHDz`0yfdPnPqk@GBYY7PjC;zcwURfN^OWC1^uy!hMzYLM8fEXaIZB79 zxu+N*;gTbLO@QQ#=6k_4GKgYI_cP zhHk8J${$vzMAR^wg`8B;@XP$MvrnxG z3=IN2p(`NaxHI<3LdXXWP0yprlg?q~egt`)+-5vzl?mWj$oFh)8XpwUT5aP!Ly8C3tZ;glI-ZFqa zValF#&hEr5KjX08^Z1Yi5E+?;#&nC1RC!AnNZsXg!<6;eWaZ@&;aZOuwT*Ode|dOA zqV?Hs*IhXH_k@6TrwaO@Pq=yW9)IiMtFi`jYJP~9<#;@DetDCbi26W~Dk-CKo5~4+ z8@;}A@$FuK^#$!pRWf>yRU==01t+SU&wdtT_;jwE1H-HI)9;3!zP{J_k(+D7b^b@T zjSU!T#T`b$p6fjbgOw<3t@?}JwK#CPp%{A2DWXo<_t6D37RNo{BwsZHBP{|-Y2>`5 zR=QLW7tpNAHPA})m=!w4*882)dVB09!xvNju5tPx^IkE*$=cD-!3C9Qc%$r(9fFA= z(eDb~wi~&|cO0tcfj)^N8Aec+x5-aDgtedPx2@F7T?BBPZ~jM`6ibW`n#6tlt%O+e z7bIs(1p8Sc=Vh5orr-CsTWf6;Cg$|5W8l2*sK<=BeYdwfo$+1>FHcVp>vXN~5E|Hq z`x{+cs2)@dxtAwLu~&N=q4*WaU8X?C;J2ULjZ3wGkK=;IS5i4cb~t7}MA5=HNhdu3 zx@T-$;0E*&z9DFDfWLRucH}_|xP6NZGzrBl?ROF=3+S`8KO{EBj~0ea%Y8k6kToI! z6c#7UZLq}!B{B>MNa9WgUVnRnO7y9=TjUgGO(5|muPWTJCl!F?$FIMRe2j=UPy22a0#HtkFq98ESfF7e*8Elm__7l-i#E3W*5j+1){c6?FhqNq$6?YG;x0=h!2;wg`ch^O)2*7W+^s<-ky1 zmRGb;vCnms4IH1E!p-RxRodm9(j+3OpF1=}`tWev+dg|_Xv2P%#ka8lskCUjn0r)U zV0_~v-CxWD;Y}3x9m*vTerRS(_kq4G`uoCmF*!>8861H!0hw-hnSc=8UY!6UZ%3hC z-oI`RHHZ?Y9JGI*gkPJyTJHtu$PH3PbM5s|P+<5ed_~$b%2amwHmR;(ZNEb)o?fkp z{KWwR`HkQ@ zPwvFj6gexqpYg)xrmJ^@3?8`BpzVwX89i|;-p}KW#BI=PapG@}xlpEfo1_>xyJHsp zS)2ZL$YB0QYD&-56a95qdeBTn$~0YS?vK|`{P9L zPyuG+a3TbVFqM`~zSkJ;_%MmmA81`U2H@U6-j|8qfQHrJJBB+*g+G!%raqOOc@ca%gs=wFf{boVQ61 z(G;Lv#ed&8zv;G%&$Bh5gL#EsheM?;;#5X|SAglpY)FY7U&5L*ky>bGQsG zwBBy*sV5YVHUh*p4^bJA^6XbW)yWHdb}kDsjU0=*?4J(PWTHdrEX8Y;I?s4nN>!cC z#US#_)hx%qh6J)gAOR0x9m?O#q_+4FJzjmHCEk@0!E{JmaEcjp$CY1bn>53s$S6N% z=1E`-#o1MVb*{U-4q)2=366nq9uuep+y(NyK--G;6Mh3h#{dbR>7Ota1} zKh-b4V*QO+*C z9Of25pC7QXq_qhOZN42I_MYO;jR?BgR{ZkGT7XJCgKIxrRQM(+UI7ktd2YYTm$?I+d)EZ1CdWG6XRJdCd7Yo}xD_RGJkE!vvPQ|{v^Ir-B{&ai_dYiTwg zN}O-%#54>#%cHJXCg_2yNj1z*FEw)i9K{^^0xt3$!~5{-!LD{f9^y!Aoy&8!L$rc8 zqw{R$S2#6Nu=V(rqN!bIzpo-Am9gG>b1n8;@W|5YkL#wsGcn~D-s8N^ePdafq?;nJ#*TP5-u9NNTt@oOi*FG!h7GTEP3-H ztTcFMT9Wb6CMH8o6?b`gS$BQBGJ?eS{#M2jjyHUz{LivMZsg*3^2pq{-T^2^e))U!t{^6_>!t2 z5YtpPuL6u`2))Un{#q7&5gQd1wIP2dATu9xf#eVYHXG}|+`8@?E!wr^7$t{Rs{9eb zJ-KZXR#o+o#~ULKLCSud_Z-6@^+^42#+ImgUdo-&8TaR#x*rsE!!AqjvX+PYWN^5?Kb#GZDiwapiT0?5GkKBg?q!5Xje{V-X|cXI?P3 zfn}*bhumpj|GYylKQV&Gy`>V(maL0E1&cszx=ozXx&@B$HRFk_Wq=0=o}FBIxT7$Nz6UZ(cPWj5 z6MxT$n#*cyQ>5ioinu$turohz9mqO6R@=YjU!x9XwD=vgKZ`o-0AprGJVd3=?z}UB z?IU;|elnK4;aE@4N9h+X)`wzwA_HrJ8KsH_nU-`Asj<9K)j^{d@lAg0U^ zamG>n@4}JSa>;lm`zTf3KPa?|ysBBmREs(%N29btPz{b(11)|iax89$^kq(Y;`xnO=t($#UYTDF{5A%A! z+4h1Hgrky#XB9$#!-;31kW~>i=AO03K6`kOh2kF5$L}CC<>6*MU!c52j0SD!debw2 z{}mWLFHR>{R`&f#Z#+IXf-|Vofmgh?5L@^yJs&>@F{;Ok-ju9*Cqxf0cSoQ#+?Wt*vmWzM4h8u82`sCfC210Y} zg2|-&sbkP6M`3tN?({ydYjO1aCfm6dniCgOjdIy~e1Cc?C!^((o5P=Bea0DtXa6j5 zs;G+{%qr^gZY0CA^Y#4q)t@M>UY`Fd{w>Ujmsh=9RJLCEJAcV18d(#lR-5AMn52CU z=?3(=EE6;vazj&KL8Wtecp<`nYm$#7V$ZInp>-BQ2_*A@20-?@N@o9;b=7I0ateMa z^w^I-I@_J#U=1N{S_~@SXeTOI>FnicrR?dzhR3z zh2QLe$YN4y)s@p6mpYMT4R8FYz?P$RY8>;!KMO`g}v zVK+2A2bG>wMoO$&qdhLmuMb(D|3#3eF+-ObgVmI7DK4t1bSv74s8T_@ZOc!E?6#h~9o zPxIhp-65GdMz}6J@f&4JsKukLDd6j60}?~=HAdZr-YK#h*_sLQeeM{8jh0MEl_WJV z_g-|Q(%T<1Sp*)EkGEwX@#%Ap<$aweD+=t4guP$*leCnw<`wNLGE)M+=awK{d5=Yz%M-?cF}bQb!eyEO$}2bV zoQ?8=b)!GP=hH!-DTf?_%Oxxlfp98Gr7~xa2zDxHN8$>#c*6wRar1B=6jM|*W}l;A z44!RY*AVB$F8(yB-uYDz7lly}P$NsJU16=U-o24F6#)g;mE@i8|BbbkyHK1N1;o2l z)Lg=>cYm712bTQXk%|-;i%BZ(3QO!|fxi51XQhZqh=Nq&nNPdvBu8Md^p6Ab%tY@Q z?`OK$AH(f51!JDGN;~&b=8mT}89dkarS0&)lw=cmEM{f6q7}zQKw_qZd6noP=ZNP1 zXMHW<`GgQqX)U4Uzk!#n4h|lr6gyu`xF8qIUh|Od*pL3SdYz~BJ}o(~~rwMUBrL(?)%C)U4P)aPM}(Ue?!Zfv0X4SH8eG8$x_ z_fE3p6RlC7v2Q5a!LFF*$ z1liNEJFn-vB3!?;S6@tV8`>q>6dn*ZA@x%~tRIy>g!BrNuODNjx!$U`+)U-eWYU72 z59sN3W}CebZFA^jF>Y6i09R|E4-5<{Q!^RA_(5E32NI ziZi4Eo~nDqly*IgdI>-K2_P!$RUHkq56H1XWWkT%!#jsEfvJc-cqZdya z#)_glGGQn6?x6XO!6pT}?geu|U<+)Y82-iD0f=)}cYrvzAE{eN@Ir)#OuJ({&5lh9 znIQ%8Lr3Fg_QQU!cPpmP`fs)G*I}Ixs!#_BPW+ERybKth$!wbb%ojqX!S7*+wWBxtf z@L!lMVE<~CA{|HyINRFs2yv0WZ!8Eo{-`o)Mr$u@^WN?7({kj#el@zjfF26ZHt!2f5AaCcp@yPlr^8(vgZTN&*HtZk6HjSofY^shM$nM4esiFDX^Ku4fu`QH|X;sxjlYinyj4;nHT>>aw-({fCx z+>rin-AtohG@ASr{wKUKIYPNZqROjbf-yrF{AwC{PYTQam*-e50h}24Pto4R1b8@c*5X zWkC9TEKtsWM~|<^h2rcEljwDzM4I@9HZn%Wg5>BLJ~t30cWUZU@E~*>!JmV@G zU#Th<~@)-@@mnRVa150)z zem%9Og1-Eg5I@cVgo=!ub2UW@?3qjac}mph&Q6!y1GzzToY7Tp2jZ2~MGpX2$GWwK z81bL7;HMkvEX_kW+sr(7R}@u^$6u=edf5x)Y$C&+;0;-BZa6s#L9tZw6l_nQy`P#$ zK1lQ_{Oxg=l~kz`iXA9I7VACdJ;EglcY#< z3Urqj9%NhTLkB86@fj%ygNm(eT0}uR8XFWE>O1muf660tSLMDZq0PijDzyLB*IBYcRv^Pa?UXk(r#!>%a?F{554V%)eirK&e6h_YdSv x5b!6|E*3b&|9iv#*5QBq;eY4i|GW4=Qt%UNxr$ms*@1u`O*K8$3T2zf{|C2R!N>pr literal 0 HcmV?d00001 diff --git a/assets/images/komet_512.png b/assets/images/komet_512.png new file mode 100644 index 0000000000000000000000000000000000000000..1d5e2d164224eede67663b8fedf44f273abdf825 GIT binary patch literal 80682 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 R*d&Tak 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

`e0iza0X7)b&*0Pnc!56gs9C+NauqFe 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 z z$K_a$tP?6U39DN^cB9kD%~)7FK{ODigXXRPA=p|Y!T*&^D{35U(>xPd%8-AWw|#S~a$TfzuG9cLz;VHBFXks4Nz%mvY^ie0fGMt_&6)*xA@`T7XQm z&PdAqnb|k)YkdRVVgx3ld{}1D(TFUAtlR$uFjUC(LaP3TgbuTYa81Q)4_rOi!d%klOe%={}T&=OrxwzlSsRn$gDN+`??nXB_w8$26J&3dFdMncF^{*6vH7v6vHqe#_n?wrSJ^z` zNJsv36ukor|=1@X}1qFZ5qLHkpysNbN92Lu|#f!(mD=uc^8pDs+Z zlkOciskc+%ceAM?^6>kB)7x0G)&HnpvtwE zQ?8PLZyy8%tOdSm!o7N2c)x~8AU4xWLtx&b&w{@o4iKv}q?u~dFAU^zpje)jOMP<2 zY6)?p^L1APX%6(Js_IQiR-L+B8@U6HFN+*pRW*Ob90NjhT-rUW`N1Y`lBj%OBTgm` z(zqH~q}dkrdgMy2^Ws8;&%=U>r#}hB8B|Q5yO98v=Z&+YaAY5pp@^NUd`5VqeEG2s za89h7V^o3Hr71Q+KRjWVyg8C_44zG1Yob)Y`%O$|xV;PWaD}N=a@CD&SGTz5KdI=i zB$ElJdrcKx>Dn0!p4cc0=ret*kjq@5qc`Tf6CXaVr<1q2O?@x4hPl7&-&+Ab`G6U; zFt0pk`k;s%(-nx9du&y7#h$H_4n$QxVk^L#%1Vewj9f%a>E-$$VoQyy%*we6J4Zj6 zR9i88t&N~Wb~9_b0*zfN`%o>@&$p>_`!^iEGo>(Pa#i+L z{a6WLW0Q%VI(hDFozrui`+*A|oQqz>Hn2#mQi#ms7$1T9V-+bWOK&RcXuneSjNhpm zvuF)EAM+?Gg_@C_7%C;DzcoP+@?arF|{v)jaQt~#)) zBsSfv-tNQHR-t|~%)*SL)}m-CM0_e;2$cKjX4a1<@5t7g0F@2d!w`Mjd$))Yxpaxy zUiWlq?dcN5Qw?=TUvr!Jt7N<=5nKs+8-;l>rwA2~5l9zKU8x&Z*SA#_7rn`(WjpM* zGrI&d7CKONH8XatkCu*RWDs%StSu^FTiVA+7OFM5Qt1?Ag8Nr!#xhB^&5v@qs3-`< z3Y{G>f}p$6g5b`6T?+WMIPnhS!ewktgN1zc#OH{y^OGKk80|J?Xt zFZ4M7!%sijOnC8ddpP2!hot9(%1fPaA&A_yZ0R`Zh|APs<`)w_)fUP$;0>Nk8${B1 z*En`}SksqLlpY8`H2(rnEcuG$gt<$EBl}@4;O}sRSc(`)A>yCA-dxJIANCg;!$DH& zoelpaiI4oa4uX?+8$`%~768_O867i-Zb~@q7=$HljhV{sZvyf?ol734pAyveM-9tp zKPC6~Y@Tyij_bx1_d}k{6s6+|neNX%JR=pd-S1oIiVnz^NVOz7kbyNI{v(nlpV(f} zI=Oi6uj)?AHDz`0yfdPnPqk@GBYY7PjC;zcwURfN^OWC1^uy!hMzYLM8fEXaIZB79 zxu+N*;gTbLO@QQ#=6k_4GKgYI_cP zhHk8J${$vzMAR^wg`8B;@XP$MvrnxG z3=IN2p(`NaxHI<3LdXXWP0yprlg?q~egt`)+-5vzl?mWj$oFh)8XpwUT5aP!Ly8C3tZ;glI-ZFqa zValF#&hEr5KjX08^Z1Yi5E+?;#&nC1RC!AnNZsXg!<6;eWaZ@&;aZOuwT*Ode|dOA zqV?Hs*IhXH_k@6TrwaO@Pq=yW9)IiMtFi`jYJP~9<#;@DetDCbi26W~Dk-CKo5~4+ z8@;}A@$FuK^#$!pRWf>yRU==01t+SU&wdtT_;jwE1H-HI)9;3!zP{J_k(+D7b^b@T zjSU!T#T`b$p6fjbgOw<3t@?}JwK#CPp%{A2DWXo<_t6D37RNo{BwsZHBP{|-Y2>`5 zR=QLW7tpNAHPA})m=!w4*882)dVB09!xvNju5tPx^IkE*$=cD-!3C9Qc%$r(9fFA= z(eDb~wi~&|cO0tcfj)^N8Aec+x5-aDgtedPx2@F7T?BBPZ~jM`6ibW`n#6tlt%O+e z7bIs(1p8Sc=Vh5orr-CsTWf6;Cg$|5W8l2*sK<=BeYdwfo$+1>FHcVp>vXN~5E|Hq z`x{+cs2)@dxtAwLu~&N=q4*WaU8X?C;J2ULjZ3wGkK=;IS5i4cb~t7}MA5=HNhdu3 zx@T-$;0E*&z9DFDfWLRucH}_|xP6NZGzrBl?ROF=3+S`8KO{EBj~0ea%Y8k6kToI! z6c#7UZLq}!B{B>MNa9WgUVnRnO7y9=TjUgGO(5|muPWTJCl!F?$FIMRe2j=UPy22a0#HtkFq98ESfF7e*8Elm__7l-i#E3W*5j+1){c6?FhqNq$6?YG;x0=h!2;wg`ch^O)2*7W+^s<-ky1 zmRGb;vCnms4IH1E!p-RxRodm9(j+3OpF1=}`tWev+dg|_Xv2P%#ka8lskCUjn0r)U zV0_~v-CxWD;Y}3x9m*vTerRS(_kq4G`uoCmF*!>8861H!0hw-hnSc=8UY!6UZ%3hC z-oI`RHHZ?Y9JGI*gkPJyTJHtu$PH3PbM5s|P+<5ed_~$b%2amwHmR;(ZNEb)o?fkp z{KWwR`HkQ@ zPwvFj6gexqpYg)xrmJ^@3?8`BpzVwX89i|;-p}KW#BI=PapG@}xlpEfo1_>xyJHsp zS)2ZL$YB0QYD&-56a95qdeBTn$~0YS?vK|`{P9L zPyuG+a3TbVFqM`~zSkJ;_%MmmA81`U2H@U6-j|8qfQHrJJBB+*g+G!%raqOOc@ca%gs=wFf{boVQ61 z(G;Lv#ed&8zv;G%&$Bh5gL#EsheM?;;#5X|SAglpY)FY7U&5L*ky>bGQsG zwBBy*sV5YVHUh*p4^bJA^6XbW)yWHdb}kDsjU0=*?4J(PWTHdrEX8Y;I?s4nN>!cC z#US#_)hx%qh6J)gAOR0x9m?O#q_+4FJzjmHCEk@0!E{JmaEcjp$CY1bn>53s$S6N% z=1E`-#o1MVb*{U-4q)2=366nq9uuep+y(NyK--G;6Mh3h#{dbR>7Ota1} zKh-b4V*QO+*C z9Of25pC7QXq_qhOZN42I_MYO;jR?BgR{ZkGT7XJCgKIxrRQM(+UI7ktd2YYTm$?I+d)EZ1CdWG6XRJdCd7Yo}xD_RGJkE!vvPQ|{v^Ir-B{&ai_dYiTwg zN}O-%#54>#%cHJXCg_2yNj1z*FEw)i9K{^^0xt3$!~5{-!LD{f9^y!Aoy&8!L$rc8 zqw{R$S2#6Nu=V(rqN!bIzpo-Am9gG>b1n8;@W|5YkL#wsGcn~D-s8N^ePdafq?;nJ#*TP5-u9NNTt@oOi*FG!h7GTEP3-H ztTcFMT9Wb6CMH8o6?b`gS$BQBGJ?eS{#M2jjyHUz{LivMZsg*3^2pq{-T^2^e))U!t{^6_>!t2 z5YtpPuL6u`2))Un{#q7&5gQd1wIP2dATu9xf#eVYHXG}|+`8@?E!wr^7$t{Rs{9eb zJ-KZXR#o+o#~ULKLCSud_Z-6@^+^42#+ImgUdo-&8TaR#x*rsE!!AqjvX+PYWN^5?Kb#GZDiwapiT0?5GkKBg?q!5Xje{V-X|cXI?P3 zfn}*bhumpj|GYylKQV&Gy`>V(maL0E1&cszx=ozXx&@B$HRFk_Wq=0=o}FBIxT7$Nz6UZ(cPWj5 z6MxT$n#*cyQ>5ioinu$turohz9mqO6R@=YjU!x9XwD=vgKZ`o-0AprGJVd3=?z}UB z?IU;|elnK4;aE@4N9h+X)`wzwA_HrJ8KsH_nU-`Asj<9K)j^{d@lAg0U^ zamG>n@4}JSa>;lm`zTf3KPa?|ysBBmREs(%N29btPz{b(11)|iax89$^kq(Y;`xnO=t($#UYTDF{5A%A! z+4h1Hgrky#XB9$#!-;31kW~>i=AO03K6`kOh2kF5$L}CC<>6*MU!c52j0SD!debw2 z{}mWLFHR>{R`&f#Z#+IXf-|Vofmgh?5L@^yJs&>@F{;Ok-ju9*Cqxf0cSoQ#+?Wt*vmWzM4h8u82`sCfC210Y} zg2|-&sbkP6M`3tN?({ydYjO1aCfm6dniCgOjdIy~e1Cc?C!^((o5P=Bea0DtXa6j5 zs;G+{%qr^gZY0CA^Y#4q)t@M>UY`Fd{w>Ujmsh=9RJLCEJAcV18d(#lR-5AMn52CU z=?3(=EE6;vazj&KL8Wtecp<`nYm$#7V$ZInp>-BQ2_*A@20-?@N@o9;b=7I0ateMa z^w^I-I@_J#U=1N{S_~@SXeTOI>FnicrR?dzhR3z zh2QLe$YN4y)s@p6mpYMT4R8FYz?P$RY8>;!KMO`g}v zVK+2A2bG>wMoO$&qdhLmuMb(D|3#3eF+-ObgVmI7DK4t1bSv74s8T_@ZOc!E?6#h~9o zPxIhp-65GdMz}6J@f&4JsKukLDd6j60}?~=HAdZr-YK#h*_sLQeeM{8jh0MEl_WJV z_g-|Q(%T<1Sp*)EkGEwX@#%Ap<$aweD+=t4guP$*leCnw<`wNLGE)M+=awK{d5=Yz%M-?cF}bQb!eyEO$}2bV zoQ?8=b)!GP=hH!-DTf?_%Oxxlfp98Gr7~xa2zDxHN8$>#c*6wRar1B=6jM|*W}l;A z44!RY*AVB$F8(yB-uYDz7lly}P$NsJU16=U-o24F6#)g;mE@i8|BbbkyHK1N1;o2l z)Lg=>cYm712bTQXk%|-;i%BZ(3QO!|fxi51XQhZqh=Nq&nNPdvBu8Md^p6Ab%tY@Q z?`OK$AH(f51!JDGN;~&b=8mT}89dkarS0&)lw=cmEM{f6q7}zQKw_qZd6noP=ZNP1 zXMHW<`GgQqX)U4Uzk!#n4h|lr6gyu`xF8qIUh|Od*pL3SdYz~BJ}o(~~rwMUBrL(?)%C)U4P)aPM}(Ue?!Zfv0X4SH8eG8$x_ z_fE3p6RlC7v2Q5a!LFF*$ z1liNEJFn-vB3!?;S6@tV8`>q>6dn*ZA@x%~tRIy>g!BrNuODNjx!$U`+)U-eWYU72 z59sN3W}CebZFA^jF>Y6i09R|E4-5<{Q!^RA_(5E32NI ziZi4Eo~nDqly*IgdI>-K2_P!$RUHkq56H1XWWkT%!#jsEfvJc-cqZdya z#)_glGGQn6?x6XO!6pT}?geu|U<+)Y82-iD0f=)}cYrvzAE{eN@Ir)#OuJ({&5lh9 znIQ%8Lr3Fg_QQU!cPpmP`fs)G*I}Ixs!#_BPW+ERybKth$!wbb%ojqX!S7*+wWBxtf z@L!lMVE<~CA{|HyINRFs2yv0WZ!8Eo{-`o)Mr$u@^WN?7({kj#el@zjfF26ZHt!2f5AaCcp@yPlr^8(vgZTN&*HtZk6HjSofY^shM$nM4esiFDX^Ku4fu`QH|X;sxjlYinyj4;nHT>>aw-({fCx z+>rin-AtohG@ASr{wKUKIYPNZqROjbf-yrF{AwC{PYTQam*-e50h}24Pto4R1b8@c*5X zWkC9TEKtsWM~|<^h2rcEljwDzM4I@9HZn%Wg5>BLJ~t30cWUZU@E~*>!JmV@G zU#Th<~@)-@@mnRVa150)z zem%9Og1-Eg5I@cVgo=!ub2UW@?3qjac}mph&Q6!y1GzzToY7Tp2jZ2~MGpX2$GWwK z81bL7;HMkvEX_kW+sr(7R}@u^$6u=edf5x)Y$C&+;0;-BZa6s#L9tZw6l_nQy`P#$ zK1lQ_{Oxg=l~kz`iXA9I7VACdJ;EglcY#< z3Urqj9%NhTLkB86@fj%ygNm(eT0}uR8XFWE>O1muf660tSLMDZq0PijDzyLB*IBYcRv^Pa?UXk(r#!>%a?F{554V%)eirK&e6h_YdSv x5b!6|E*3b&|9iv#*5QBq;eY4i|GW4=Qt%UNxr$ms*@1u`O*K8$3T2zf{|C2R!N>pr literal 0 HcmV?d00001 diff --git a/assets/images/meteor.png b/assets/images/meteor.png new file mode 100644 index 0000000000000000000000000000000000000000..4b8b93f7074046ba3f3a464804501c141f9cae10 GIT binary patch literal 69540 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 F{{w}yX@vj) literal 0 HcmV?d00001 diff --git a/assets/images/spermum.webp b/assets/images/spermum.webp new file mode 100644 index 0000000000000000000000000000000000000000..13d3c2d5f91ec43a3de6c4dec4cd86e6d73f69d0 GIT binary patch literal 153195 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

1swlaqQi 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 z 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𗉄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 O0000O-#>^VWEHp!`v3nw3tR%ifSbYy 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9c18913c076c1e74e9e5b577cbde8220a96f6436 GIT binary patch literal 9594 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 Bd{F=Z literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..e05e2e72af94748272a75aabf3829e96163bedef GIT binary patch literal 2745 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 W*PWxwJ`0`z0000U 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 literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8780c73ba7f1e16dba1ffe46ecefacb8b4e5480e GIT binary patch literal 13236 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 z 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 Y0tE)`J^@USWdHyG07*qoM6N<$g5M{VPyhe` literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..56909eece8ad1e960b97a8ce51eec0d1080d9b66 GIT binary patch literal 17486 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 Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000..9c2cf69 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Gwid + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + gwid + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/lib/api_service.dart b/lib/api_service.dart new file mode 100644 index 0000000..468068c --- /dev/null +++ b/lib/api_service.dart @@ -0,0 +1,2860 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:web_socket_channel/io.dart'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:web_socket_channel/status.dart' as status; +import 'package:http/http.dart' as http; +import 'package:image_picker/image_picker.dart'; +import 'package:gwid/spoofing_service.dart'; +import 'package:uuid/uuid.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/proxy_service.dart'; +import 'package:file_picker/file_picker.dart'; + +class ApiService { + ApiService._privateConstructor(); + static final ApiService instance = ApiService._privateConstructor(); + + + int? _userId; + late int _sessionId; + int _actionId = 1; + bool _isColdStartSent = false; + late int _lastActionTime; + + + bool _isAppInForeground = true; + + final List _wsUrls = ['wss://ws-api.oneme.ru:443/websocket']; + int _currentUrlIndex = 0; + + + List get wsUrls => _wsUrls; + int get currentUrlIndex => _currentUrlIndex; + IOWebSocketChannel? _channel; + StreamSubscription? _streamSubscription; + Timer? _pingTimer; + int _seq = 0; + + + final StreamController _contactUpdatesController = + StreamController.broadcast(); + Stream get contactUpdates => _contactUpdatesController.stream; + + + final StreamController _errorController = + StreamController.broadcast(); + Stream get errorStream => _errorController.stream; + + final _reconnectionCompleteController = StreamController.broadcast(); + Stream get reconnectionComplete => + _reconnectionCompleteController.stream; + + + final Map _presenceData = {}; + String? authToken; + String? userId; + + String? get token => authToken; + + + String? _currentPasswordTrackId; + String? _currentPasswordHint; + String? _currentPasswordEmail; + + bool _isSessionOnline = false; + bool _handshakeSent = false; + Completer? _onlineCompleter; + final List> _messageQueue = []; + + final Map> _messageCache = {}; + + + final Map _contactCache = {}; + DateTime? _lastContactsUpdate; + static const Duration _contactCacheExpiry = Duration( + minutes: 5, + ); // Кэш на 5 минут + + + bool _isLoadingBlockedContacts = false; + + + bool _isSessionReady = false; + + final _messageController = StreamController>.broadcast(); + Stream> get messages => _messageController.stream; + + final _connectionStatusController = StreamController.broadcast(); + Stream get connectionStatus => _connectionStatusController.stream; + + final _connectionLogController = StreamController.broadcast(); + Stream get connectionLog => _connectionLogController.stream; + + + final List _connectionLogCache = []; + List get connectionLogCache => _connectionLogCache; + + + void _log(String message) { + print(message); // Оставляем для дебага в консоли + _connectionLogCache.add(message); + if (!_connectionLogController.isClosed) { + _connectionLogController.add(message); + } + } + + void _emitLocal(Map frame) { + try { + _messageController.add(frame); + } catch (_) {} + } + + bool get isOnline => _isSessionOnline; + Future waitUntilOnline() async { + if (_isSessionOnline && _isSessionReady) return; + _onlineCompleter ??= Completer(); + return _onlineCompleter!.future; + } + + bool get isActuallyConnected { + try { + + if (_channel == null || !_isSessionOnline) { + return false; + } + + + + return true; + } catch (e) { + print("🔴 Ошибка при проверке состояния канала: $e"); + return false; + } + } + + + Completer>? _inflightChatsCompleter; + Map? _lastChatsPayload; + DateTime? _lastChatsAt; + final Duration _chatsCacheTtl = const Duration(seconds: 5); + bool _chatsFetchedInThisSession = false; + + + Map? get lastChatsPayload => _lastChatsPayload; + + Future _connectWithFallback() async { + _log('Начало подключения...'); + + while (_currentUrlIndex < _wsUrls.length) { + final currentUrl = _wsUrls[_currentUrlIndex]; + final logMessage = + 'Попытка ${_currentUrlIndex + 1}/${_wsUrls.length}: $currentUrl'; + _log(logMessage); + _connectionLogController.add(logMessage); + + try { + await _connectToUrl(currentUrl); + final successMessage = _currentUrlIndex == 0 + ? 'Подключено к основному серверу' + : 'Подключено через резервный сервер'; + _connectionLogController.add('✅ $successMessage'); + if (_currentUrlIndex > 0) { + _connectionStatusController.add('Подключено через резервный сервер'); + } + return; // Успешно подключились + } catch (e) { + final errorMessage = '❌ Ошибка: ${e.toString().split(':').first}'; + print('Ошибка подключения к $currentUrl: $e'); + _connectionLogController.add(errorMessage); + _currentUrlIndex++; + + + if (_currentUrlIndex < _wsUrls.length) { + await Future.delayed(const Duration(milliseconds: 500)); + } + } + } + + + _log('❌ Все серверы недоступны'); + _connectionStatusController.add('Все серверы недоступны'); + throw Exception('Не удалось подключиться ни к одному серверу'); + } + + Future _connectToUrl(String url) async { + _isSessionOnline = false; + _onlineCompleter = Completer(); + _chatsFetchedInThisSession = false; + + _connectionStatusController.add('connecting'); + + final uri = Uri.parse(url); + print( + 'Parsed URI: host=${uri.host}, port=${uri.port}, scheme=${uri.scheme}', + ); + + final spoofedData = await SpoofingService.getSpoofedSessionData(); + final userAgent = + spoofedData?['useragent'] as String? ?? + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; + + final headers = { + 'Origin': 'https://web.max.ru', + 'User-Agent': userAgent, + 'Sec-WebSocket-Extensions': 'permessage-deflate', + }; + + + final proxySettings = await ProxyService.instance.loadProxySettings(); + + if (proxySettings.isEnabled && proxySettings.host.isNotEmpty) { + + print( + 'Используем HTTP/HTTPS прокси ${proxySettings.host}:${proxySettings.port}', + ); + final customHttpClient = await ProxyService.instance + .getHttpClientWithProxy(); + _channel = IOWebSocketChannel.connect( + uri, + headers: headers, + customClient: customHttpClient, + ); + } else { + + print('Подключение без прокси'); + _channel = IOWebSocketChannel.connect(uri, headers: headers); + } + + await _channel!.ready; + _listen(); + await _sendHandshake(); + _startPinging(); + } + + int _reconnectDelaySeconds = 2; + int _reconnectAttempts = 0; + static const int _maxReconnectAttempts = 10; + Timer? _reconnectTimer; + bool _isReconnecting = false; + + String generateRandomDeviceId() { + + return const Uuid().v4(); + } + + Future> _buildUserAgentPayload() async { + final spoofedData = await SpoofingService.getSpoofedSessionData(); + + if (spoofedData != null) { + print( + '--- [_buildUserAgentPayload] Используются подменённые данные сессии ---', + ); + final String finalDeviceId; + final String? idFromSpoofing = spoofedData['device_id'] as String?; + + if (idFromSpoofing != null && idFromSpoofing.isNotEmpty) { + + finalDeviceId = idFromSpoofing; + print('Используется deviceId из сессии: $finalDeviceId'); + } else { + + finalDeviceId = generateRandomDeviceId(); + print('device_id не найден в кэше, сгенерирован новый: $finalDeviceId'); + } + return { + 'deviceType': spoofedData['device_type'] as String? ?? 'IOS', + 'locale': spoofedData['locale'] as String? ?? 'ru', + 'deviceLocale': spoofedData['locale'] as String? ?? 'ru', + 'osVersion': spoofedData['os_version'] as String? ?? 'iOS 17.5.1', + 'deviceName': spoofedData['device_name'] as String? ?? 'iPhone', + 'headerUserAgent': + spoofedData['user_agent'] as String? ?? + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1', + 'appVersion': spoofedData['app_version'] as String? ?? '25.10.10', + 'screen': spoofedData['screen'] as String? ?? '1170x2532 3.0x', + 'timezone': spoofedData['timezone'] as String? ?? 'Europe/Moscow', + }; + } else { + print( + '--- [_buildUserAgentPayload] Используются псевдо-случайные данные ---', + ); + return { + 'deviceType': 'WEB', + 'locale': 'ru', + 'deviceLocale': 'ru', + 'osVersion': 'Windows', + 'deviceName': 'Chrome', + 'headerUserAgent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'appVersion': '25.10.10', + 'screen': '1920x1080 1.0x', + 'timezone': 'Europe/Moscow', + }; + } + } + + void _handleSessionTerminated() { + print("Сессия была завершена сервером"); + _isSessionOnline = false; + _isSessionReady = false; + + + authToken = null; + + + clearAllCaches(); + + + _messageController.add({ + 'type': 'session_terminated', + 'message': 'Твоя сессия больше не активна, войди снова', + }); + } + + void _handleInvalidToken() async { + print("Обработка недействительного токена"); + _isSessionOnline = false; + _isSessionReady = false; + + + authToken = null; + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('authToken'); + + + clearAllCaches(); + + + _channel?.sink.close(); + _channel = null; + _pingTimer?.cancel(); + + + _messageController.add({ + 'type': 'invalid_token', + 'message': 'Токен недействителен, требуется повторная авторизация', + }); + } + + Future _clearAuthToken() async { + print("Очищаем токен авторизации..."); + authToken = null; + _lastChatsPayload = null; + _lastChatsAt = null; + _chatsFetchedInThisSession = false; + + + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('authToken'); + + clearAllCaches(); + _connectionStatusController.add("disconnected"); + } + + + Future _sendHandshake() async { + if (_handshakeSent) { + print('Handshake уже отправлен, пропускаем...'); + return; + } + + print('Отправляем handshake...'); + + final userAgentPayload = await _buildUserAgentPayload(); + + final prefs = await SharedPreferences.getInstance(); + final deviceId = + prefs.getString('spoof_deviceid') ?? generateRandomDeviceId(); + + if (prefs.getString('spoof_deviceid') == null) { + await prefs.setString('spoof_deviceid', deviceId); + } + + final payload = {'deviceId': deviceId, 'userAgent': userAgentPayload}; + + print('Отправляем handshake с payload: $payload'); + _sendMessage(6, payload); + _handshakeSent = true; + print('Handshake отправлен, ожидаем ответ...'); + } + + + Future requestOtp(String phoneNumber) async { + + if (_channel == null) { + print('WebSocket не подключен, подключаемся...'); + try { + await connect(); + + await waitUntilOnline(); + } catch (e) { + print('Ошибка подключения к WebSocket: $e'); + throw Exception('Не удалось подключиться к серверу: $e'); + } + } + + final payload = { + "phone": phoneNumber, + "type": "START_AUTH", + "language": "ru", + }; + _sendMessage(17, payload); + } + + + void requestSessions() { + _sendMessage(96, {}); + } + + + void terminateAllSessions() { + _sendMessage(97, {}); + } + + Future blockContact(int contactId) async { + await waitUntilOnline(); + _sendMessage(34, {'contactId': contactId, 'action': 'BLOCK'}); + } + + Future unblockContact(int contactId) async { + await waitUntilOnline(); + _sendMessage(34, {'contactId': contactId, 'action': 'UNBLOCK'}); + } + + Future addContact(int contactId) async { + await waitUntilOnline(); + _sendMessage(34, {'contactId': contactId, 'action': 'ADD'}); + } + + Future subscribeToChat(int chatId, bool subscribe) async { + await waitUntilOnline(); + _sendMessage(75, {'chatId': chatId, 'subscribe': subscribe}); + } + + Future navigateToChat(int currentChatId, int targetChatId) async { + await waitUntilOnline(); + if (currentChatId != 0) { + await subscribeToChat(currentChatId, false); + } + await subscribeToChat(targetChatId, true); + } + + + Future clearChatHistory(int chatId, {bool forAll = false}) async { + await waitUntilOnline(); + final payload = { + 'chatId': chatId, + 'forAll': forAll, + 'lastEventTime': DateTime.now().millisecondsSinceEpoch, + }; + _sendMessage(54, payload); + } + + Future> getChatInfoByLink(String link) async { + await waitUntilOnline(); + + final payload = {'link': link}; + + final int seq = _sendMessage(89, payload); + print('Запрашиваем информацию о чате (seq: $seq) по ссылке: $link'); + + try { + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 10)); + + if (response['cmd'] == 3) { + final errorPayload = response['payload'] ?? {}; + final errorMessage = + errorPayload['localizedMessage'] ?? + errorPayload['message'] ?? + 'Неизвестная ошибка'; + print('Ошибка получения информации о чате: $errorMessage'); + throw Exception(errorMessage); + } + + if (response['cmd'] == 1 && + response['payload'] != null && + response['payload']['chat'] != null) { + print( + 'Информация о чате получена: ${response['payload']['chat']['title']}', + ); + return response['payload']['chat'] as Map; + } else { + print('Не удалось найти "chat" в ответе opcode 89: $response'); + throw Exception('Неверный ответ от сервера'); + } + } on TimeoutException { + print('Таймаут ожидания ответа на getChatInfoByLink (seq: $seq)'); + throw Exception('Сервер не ответил вовремя'); + } catch (e) { + print('Ошибка в getChatInfoByLink: $e'); + rethrow; + } + } + + + void markMessageAsRead(int chatId, String messageId) { + + waitUntilOnline().then((_) { + final payload = { + "type": "READ_MESSAGE", + "chatId": chatId, + "messageId": messageId, + "mark": DateTime.now().millisecondsSinceEpoch, + }; + _sendMessage(50, payload); + print( + 'Отправляем отметку о прочтении для сообщения $messageId в чате $chatId', + ); + }); + } + + + void getBlockedContacts() async { + + if (_isLoadingBlockedContacts) { + print( + 'ApiService: запрос заблокированных контактов уже выполняется, пропускаем', + ); + return; + } + + _isLoadingBlockedContacts = true; + print('ApiService: запрашиваем заблокированные контакты'); + _sendMessage(36, { + 'status': 'BLOCKED', + 'count': 100, + 'from': 0, + + }); + + + Future.delayed(const Duration(seconds: 2), () { + _isLoadingBlockedContacts = false; + }); + } + + + void notifyContactUpdate(Contact contact) { + print( + 'ApiService отправляет обновление контакта: ${contact.name} (ID: ${contact.id}), isBlocked: ${contact.isBlocked}, isBlockedByMe: ${contact.isBlockedByMe}', + ); + _contactUpdatesController.add(contact); + } + + + DateTime? getLastSeen(int userId) { + final userPresence = _presenceData[userId.toString()]; + if (userPresence != null && userPresence['seen'] != null) { + final seenTimestamp = userPresence['seen'] as int; + + return DateTime.fromMillisecondsSinceEpoch(seenTimestamp * 1000); + } + return null; + } + + + void updatePresenceData(Map presenceData) { + _presenceData.addAll(presenceData); + print('ApiService обновил presence данные: $_presenceData'); + } + + + void sendReaction(int chatId, String messageId, String emoji) { + final payload = { + "chatId": chatId, + "messageId": messageId, + "reaction": {"reactionType": "EMOJI", "id": emoji}, + }; + _sendMessage(178, payload); + print('Отправляем реакцию: $emoji на сообщение $messageId в чате $chatId'); + } + + + void removeReaction(int chatId, String messageId) { + final payload = {"chatId": chatId, "messageId": messageId}; + _sendMessage(179, payload); + print('Удаляем реакцию с сообщения $messageId в чате $chatId'); + } + + + void createGroup(String name, List participantIds) { + final payload = {"name": name, "participantIds": participantIds}; + _sendMessage(48, payload); + print('Создаем группу: $name с участниками: $participantIds'); + } + + + + + + + + + + void updateGroup(int chatId, {String? name, List? participantIds}) { + final payload = { + "chatId": chatId, + if (name != null) "name": name, + if (participantIds != null) "participantIds": participantIds, + }; + _sendMessage(272, payload); + print('Обновляем группу $chatId: $payload'); + } + + + void createGroupWithMessage(String name, List participantIds) { + final cid = DateTime.now().millisecondsSinceEpoch; + final payload = { + "message": { + "cid": cid, + "attaches": [ + { + "_type": "CONTROL", + "event": "new", + "chatType": "CHAT", + "title": name, + "userIds": participantIds, + }, + ], + }, + "notify": true, + }; + _sendMessage(64, payload); + print('Создаем группу: $name с участниками: $participantIds'); + } + + + void renameGroup(int chatId, String newName) { + final payload = {"chatId": chatId, "theme": newName}; + _sendMessage(55, payload); + print('Переименовываем группу $chatId в: $newName'); + } + + + void addGroupMember( + int chatId, + List userIds, { + bool showHistory = true, + }) { + final payload = { + "chatId": chatId, + "userIds": userIds, + "showHistory": showHistory, + "operation": "add", + }; + _sendMessage(77, payload); + print('Добавляем участников $userIds в группу $chatId'); + } + + + void removeGroupMember( + int chatId, + List userIds, { + int cleanMsgPeriod = 0, + }) { + final payload = { + "chatId": chatId, + "userIds": userIds, + "operation": "remove", + "cleanMsgPeriod": cleanMsgPeriod, + }; + _sendMessage(77, payload); + print('Удаляем участников $userIds из группы $chatId'); + } + + + void leaveGroup(int chatId) { + final payload = {"chatId": chatId}; + _sendMessage(58, payload); + print('Выходим из группы $chatId'); + } + + + + + void getGroupMembers(int chatId, {int marker = 0, int count = 50}) { + final payload = { + "type": "MEMBER", + "marker": marker, + "chatId": chatId, + "count": count, + }; + _sendMessage(59, payload); + print( + 'Запрашиваем участников группы $chatId (marker: $marker, count: $count)', + ); + } + + + Future getChatIdByUserId(int userId) async { + await waitUntilOnline(); + + final payload = { + "chatIds": [userId], + }; + final int seq = _sendMessage(48, payload); + print('Запрашиваем информацию о чате для userId: $userId (seq: $seq)'); + + try { + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 10)); + + if (response['cmd'] == 3) { + final errorPayload = response['payload'] ?? {}; + final errorMessage = + errorPayload['localizedMessage'] ?? + errorPayload['message'] ?? + 'Неизвестная ошибка'; + print('Ошибка получения информации о чате: $errorMessage'); + return null; + } + + if (response['cmd'] == 1 && response['payload'] != null) { + final chats = response['payload']['chats'] as List?; + if (chats != null && chats.isNotEmpty) { + final chat = chats[0] as Map; + final chatId = chat['id'] as int?; + final chatType = chat['type'] as String?; + + if (chatType == 'DIALOG' && chatId != null) { + print('Получен chatId для диалога с userId $userId: $chatId'); + return chatId; + } + } + } + + print('Не удалось найти chatId для userId: $userId'); + return null; + } on TimeoutException { + print('Таймаут ожидания ответа на getChatIdByUserId (seq: $seq)'); + return null; + } catch (e) { + print('Ошибка при получении chatId для userId $userId: $e'); + return null; + } + } + + + Future> getChatsOnly({bool force = false}) async { + if (authToken == null) { + final prefs = await SharedPreferences.getInstance(); + authToken = prefs.getString('authToken'); + } + if (authToken == null) throw Exception("Auth token not found"); + + + if (!force && _lastChatsPayload != null && _lastChatsAt != null) { + if (DateTime.now().difference(_lastChatsAt!) < _chatsCacheTtl) { + return _lastChatsPayload!; + } + } + + try { + final payload = {"chatsCount": 100}; + + final int chatSeq = _sendMessage(48, payload); + final chatResponse = await messages.firstWhere( + (msg) => msg['seq'] == chatSeq, + ); + + final List chatListJson = + chatResponse['payload']?['chats'] ?? []; + + if (chatListJson.isEmpty) { + final result = {'chats': [], 'contacts': [], 'profile': null}; + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + return result; + } + + final contactIds = {}; + for (var chatJson in chatListJson) { + final participants = + chatJson['participants'] as Map? ?? {}; + contactIds.addAll(participants.keys.map((id) => int.parse(id))); + } + + final int contactSeq = _sendMessage(32, { + "contactIds": contactIds.toList(), + }); + final contactResponse = await messages.firstWhere( + (msg) => msg['seq'] == contactSeq, + ); + + final List contactListJson = + contactResponse['payload']?['contacts'] ?? []; + + final result = { + 'chats': chatListJson, + 'contacts': contactListJson, + 'profile': null, + 'presence': null, + }; + _lastChatsPayload = result; + + + final contacts = contactListJson + .map((json) => Contact.fromJson(json)) + .toList(); + updateContactCache(contacts); + _lastChatsAt = DateTime.now(); + return result; + } catch (e) { + print('Ошибка получения чатов: $e'); + rethrow; + } + } + + + Future verifyCode(String token, String code) async { + + _currentPasswordTrackId = null; + _currentPasswordHint = null; + _currentPasswordEmail = null; + + if (_channel == null) { + print('WebSocket не подключен, подключаемся...'); + try { + await connect(); + + await waitUntilOnline(); + } catch (e) { + print('Ошибка подключения к WebSocket: $e'); + throw Exception('Не удалось подключиться к серверу: $e'); + } + } + + + final payload = { + 'token': token, + 'verifyCode': code, + 'authTokenType': 'CHECK_CODE', + }; + + _sendMessage(18, payload); + print('Код верификации отправлен с payload: $payload'); + } + + + Future sendPassword(String trackId, String password) async { + await waitUntilOnline(); + + final payload = {'trackId': trackId, 'password': password}; + + _sendMessage(115, payload); + print('Пароль отправлен с payload: $payload'); + } + + + Map getPasswordAuthData() { + return { + 'trackId': _currentPasswordTrackId, + 'hint': _currentPasswordHint, + 'email': _currentPasswordEmail, + }; + } + + + void clearPasswordAuthData() { + _currentPasswordTrackId = null; + _currentPasswordHint = null; + _currentPasswordEmail = null; + } + + + Future setAccountPassword(String password, String hint) async { + await waitUntilOnline(); + + final payload = {'password': password, 'hint': hint}; + + _sendMessage(116, payload); + print('Запрос на установку пароля отправлен с payload: $payload'); + } + + + Future> joinGroupByLink(String link) async { + await waitUntilOnline(); + + final payload = {'link': link}; + + final int seq = _sendMessage(57, payload); + print('Отправляем запрос на присоединение (seq: $seq) по ссылке: $link'); + + try { + final response = await messages + .firstWhere((msg) => msg['seq'] == seq && msg['opcode'] == 57) + .timeout(const Duration(seconds: 15)); + + if (response['cmd'] == 3) { + final errorPayload = response['payload'] ?? {}; + final errorMessage = + errorPayload['localizedMessage'] ?? + errorPayload['message'] ?? + 'Неизвестная ошибка'; + print('Ошибка присоединения к группе: $errorMessage'); + throw Exception(errorMessage); + } + + if (response['cmd'] == 1 && response['payload'] != null) { + print('Успешно присоединились: ${response['payload']}'); + return response['payload'] as Map; + } else { + print('Неожиданный ответ на joinGroupByLink: $response'); + throw Exception('Неверный ответ от сервера'); + } + } on TimeoutException { + print('Таймаут ожидания ответа на joinGroupByLink (seq: $seq)'); + throw Exception('Сервер не ответил вовремя'); + } catch (e) { + print('Ошибка в joinGroupByLink: $e'); + rethrow; + } + } + + + Future searchContactByPhone(String phone) async { + await waitUntilOnline(); + + final payload = {'phone': phone}; + + _sendMessage(46, payload); + print('Запрос на поиск контакта отправлен с payload: $payload'); + } + + + Future searchChannels(String query) async { + await waitUntilOnline(); + + + final payload = {'contactIds': []}; + + _sendMessage(32, payload); + print('Запрос на поиск каналов отправлен с payload: $payload'); + } + + + Future enterChannel(String link) async { + await waitUntilOnline(); + + final payload = {'link': link}; + + _sendMessage(89, payload); + print('Запрос на вход в канал отправлен с payload: $payload'); + } + + + Future subscribeToChannel(String link) async { + await waitUntilOnline(); + + final payload = {'link': link}; + + _sendMessage(57, payload); + print('Запрос на подписку на канал отправлен с payload: $payload'); + } + + Future> getChatsAndContacts({bool force = false}) async { + await waitUntilOnline(); + + if (authToken == null) { + print("Токен авторизации не найден, требуется повторная авторизация"); + throw Exception("Auth token not found - please re-authenticate"); + } + + + if (!force && _lastChatsPayload != null && _lastChatsAt != null) { + if (DateTime.now().difference(_lastChatsAt!) < _chatsCacheTtl) { + return _lastChatsPayload!; + } + } + + + if (_chatsFetchedInThisSession && _lastChatsPayload != null && !force) { + return _lastChatsPayload!; + } + + + if (_inflightChatsCompleter != null) { + return _inflightChatsCompleter!.future; + } + _inflightChatsCompleter = Completer>(); + + + if (_isSessionOnline && + _isSessionReady && + _lastChatsPayload != null && + !force) { + _inflightChatsCompleter!.complete(_lastChatsPayload!); + _inflightChatsCompleter = null; + return _lastChatsPayload!; + } + + try { + Map chatResponse; + + + final int opcode; + final Map payload; + + final prefs = await SharedPreferences.getInstance(); + final deviceId = + prefs.getString('spoof_deviceid') ?? generateRandomDeviceId(); + + + if (prefs.getString('spoof_deviceid') == null) { + await prefs.setString('spoof_deviceid', deviceId); + } + + if (!_chatsFetchedInThisSession) { + + opcode = 19; + payload = { + "chatsCount": 100, + "chatsSync": 0, + "contactsSync": 0, + "draftsSync": 0, + "interactive": true, + "presenceSync": 0, + "token": authToken, + + + }; + + + if (userId != null) { + payload["userId"] = userId; + } + } else { + + return await getChatsOnly(force: force); + } + + final int chatSeq = _sendMessage(opcode, payload); + chatResponse = await messages.firstWhere((msg) => msg['seq'] == chatSeq); + + if (opcode == 19 && chatResponse['cmd'] == 1) { + print("✅ Авторизация (opcode 19) успешна. Сессия ГОТОВА."); + _isSessionReady = true; // <-- ВОТ ТЕПЕРЬ СЕССИЯ ПОЛНОСТЬЮ ГОТОВА! + + _connectionStatusController.add("ready"); + + final profile = chatResponse['payload']?['profile']; + final contactProfile = profile?['contact']; + + if (contactProfile != null && contactProfile['id'] != null) { + print( + "[getChatsAndContacts] ✅ Профиль и ID пользователя найдены. ID: ${contactProfile['id']}. ЗАПУСКАЕМ АНАЛИТИКУ.", + ); + _userId = contactProfile['id']; + _sessionId = DateTime.now().millisecondsSinceEpoch; + _lastActionTime = _sessionId; + + + sendNavEvent('COLD_START'); + + + _sendInitialSetupRequests(); + } else { + print( + "[getChatsAndContacts] ❌ ВНИМАНИЕ: Профиль или ID в ответе пустой, аналитика не будет отправлена.", + ); + } + + + if (_onlineCompleter != null && !_onlineCompleter!.isCompleted) { + _onlineCompleter!.complete(); + } + + + _startPinging(); + _processMessageQueue(); + } + + final profile = chatResponse['payload']?['profile']; + final presence = chatResponse['payload']?['presence']; + final config = chatResponse['payload']?['config']; + final List chatListJson = + chatResponse['payload']?['chats'] ?? []; + + if (chatListJson.isEmpty) { + final result = { + 'chats': [], + 'contacts': [], + 'profile': profile, + 'config': config, + }; + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + _chatsFetchedInThisSession = true; + _inflightChatsCompleter!.complete(_lastChatsPayload!); + _inflightChatsCompleter = null; + return result; + } + + final contactIds = {}; + for (var chatJson in chatListJson) { + final participants = chatJson['participants'] as Map; + contactIds.addAll(participants.keys.map((id) => int.parse(id))); + } + + final int contactSeq = _sendMessage(32, { + "contactIds": contactIds.toList(), + }); + final contactResponse = await messages.firstWhere( + (msg) => msg['seq'] == contactSeq, + ); + + final List contactListJson = + contactResponse['payload']?['contacts'] ?? []; + + + if (presence != null) { + updatePresenceData(presence); + } + + final result = { + 'chats': chatListJson, + 'contacts': contactListJson, + 'profile': profile, + 'presence': presence, + 'config': config, + }; + _lastChatsPayload = result; + + + final contacts = contactListJson + .map((json) => Contact.fromJson(json)) + .toList(); + updateContactCache(contacts); + _lastChatsAt = DateTime.now(); + _chatsFetchedInThisSession = true; + _inflightChatsCompleter!.complete(result); + _inflightChatsCompleter = null; + return result; + } catch (e) { + final error = e; + _inflightChatsCompleter?.completeError(error); + _inflightChatsCompleter = null; + rethrow; + } + } + + + Future> getMessageHistory( + int chatId, { + bool force = false, + }) async { + if (!force && _messageCache.containsKey(chatId)) { + print("Загружаем сообщения для чата $chatId из кэша."); + return _messageCache[chatId]!; + } + + print("Запрашиваем историю для чата $chatId с сервера."); + final payload = { + "chatId": chatId, + + + "from": DateTime.now() + .add(const Duration(days: 1)) + .millisecondsSinceEpoch, + "forward": 0, + "backward": 1000, // Увеличиваем лимит для получения всех сообщений + "getMessages": true, + }; + + try { + final int seq = _sendMessage(49, payload); + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 15)); + + + if (response['cmd'] == 3) { + final error = response['payload']; + print('Ошибка получения истории сообщений: $error'); + + + if (error['error'] == 'proto.state') { + print( + 'Ошибка состояния сессии при получении истории, переподключаемся...', + ); + await reconnect(); + await waitUntilOnline(); + + return getMessageHistory(chatId, force: true); + } + throw Exception('Ошибка получения истории: ${error['message']}'); + } + + final List messagesJson = response['payload']?['messages'] ?? []; + final messagesList = + messagesJson.map((json) => Message.fromJson(json)).toList() + ..sort((a, b) => a.time.compareTo(b.time)); + + _messageCache[chatId] = messagesList; + + return messagesList; + } catch (e) { + print('Ошибка при получении истории сообщений: $e'); + + return []; + } + } + + + Future?> loadOldMessages( + int chatId, + String fromMessageId, + int count, + ) async { + print( + "Запрашиваем старые сообщения для чата $chatId начиная с $fromMessageId", + ); + + final payload = { + "chatId": chatId, + "from": int.parse(fromMessageId), + "forward": 0, + "backward": count, + "getMessages": true, + }; + + try { + final int seq = _sendMessage(49, payload); + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 15)); + + + if (response['cmd'] == 3) { + final error = response['payload']; + print('Ошибка получения старых сообщений: $error'); + return null; + } + + return response['payload']; + } catch (e) { + print('Ошибка при получении старых сообщений: $e'); + return null; + } + } + + void setAppInForeground(bool isForeground) { + _isAppInForeground = isForeground; + } + + + void sendNavEvent(String event, {int? screenTo, int? screenFrom}) { + if (_userId == null) return; + + final now = DateTime.now().millisecondsSinceEpoch; + final Map params = { + 'session_id': _sessionId, + 'action_id': _actionId++, + }; + + switch (event) { + case 'COLD_START': + if (_isColdStartSent) return; + params['screen_to'] = 150; + params['source_id'] = 1; + _isColdStartSent = true; + break; + case 'WARM_START': + params['screen_to'] = + 150; // Предполагаем, что всегда возвращаемся на главный экран + params['screen_from'] = 1; // 1 = приложение свернуто + params['prev_time'] = _lastActionTime; + break; + case 'GO': + params['screen_to'] = screenTo; + params['screen_from'] = screenFrom; + params['prev_time'] = _lastActionTime; + break; + } + + _lastActionTime = now; + _sendMessage(5, { + "events": [ + { + "type": "NAV", + "event": event, + "userId": _userId, + "time": now, + "params": params, + }, + ], + }); + } + + + Future _sendInitialSetupRequests() async { + print("Запускаем отправку единичных запросов при старте..."); + + await Future.delayed(const Duration(seconds: 2)); + _sendMessage(272, {"folderSync": 0}); + await Future.delayed(const Duration(milliseconds: 500)); + _sendMessage(27, {"sync": 0, "type": "STICKER"}); + await Future.delayed(const Duration(milliseconds: 500)); + _sendMessage(27, {"sync": 0, "type": "FAVORITE_STICKER"}); + await Future.delayed(const Duration(milliseconds: 500)); + _sendMessage(79, {"forward": false, "count": 100}); + + await Future.delayed(const Duration(seconds: 5)); + _sendMessage(26, { + "sectionId": "NEW_STICKER_SETS", + "from": 5, + "count": 100, + }); + + print("Единичные запросы отправлены."); + } + + void clearCacheForChat(int chatId) { + _messageCache.remove(chatId); + print("Кэш для чата $chatId очищен."); + } + + void clearChatsCache() { + _lastChatsPayload = null; + _lastChatsAt = null; + _chatsFetchedInThisSession = false; + print("Кэш чатов очищен."); + } + + + Contact? getCachedContact(int contactId) { + if (_contactCache.containsKey(contactId)) { + final contact = _contactCache[contactId]!; + print('Контакт $contactId получен из кэша: ${contact.name}'); + return contact; + } + return null; + } + + + Future> getNetworkStatistics() async { + + final prefs = await SharedPreferences.getInstance(); + + + final totalTraffic = + prefs.getDouble('network_total_traffic') ?? + (150.0 * 1024 * 1024); // 150 MB по умолчанию + final messagesTraffic = + prefs.getDouble('network_messages_traffic') ?? (totalTraffic * 0.15); + final mediaTraffic = + prefs.getDouble('network_media_traffic') ?? (totalTraffic * 0.6); + final syncTraffic = + prefs.getDouble('network_sync_traffic') ?? (totalTraffic * 0.1); + + + final currentSpeed = _isSessionOnline + ? 512.0 * 1024 + : 0.0; // 512 KB/s если онлайн + + + final ping = 25; + + return { + 'totalTraffic': totalTraffic, + 'messagesTraffic': messagesTraffic, + 'mediaTraffic': mediaTraffic, + 'syncTraffic': syncTraffic, + 'otherTraffic': totalTraffic * 0.15, + 'currentSpeed': currentSpeed, + 'isConnected': _isSessionOnline, + 'connectionType': 'Wi-Fi', // Можно определить реальный тип + 'signalStrength': 85, + 'ping': ping, + 'jitter': 2.5, + 'packetLoss': 0.01, + 'hourlyStats': [], // Пока пустой массив, можно реализовать позже + }; + } + + + bool isContactCacheValid() { + if (_lastContactsUpdate == null) return false; + return DateTime.now().difference(_lastContactsUpdate!) < + _contactCacheExpiry; + } + + + void updateContactCache(List contacts) { + _contactCache.clear(); + for (final contact in contacts) { + _contactCache[contact.id] = contact; + } + _lastContactsUpdate = DateTime.now(); + print('Кэш контактов обновлен: ${contacts.length} контактов'); + } + + + void updateCachedContact(Contact contact) { + _contactCache[contact.id] = contact; + print('Контакт ${contact.id} обновлен в кэше: ${contact.name}'); + } + + + void clearContactCache() { + _contactCache.clear(); + _lastContactsUpdate = null; + print("Кэш контактов очищен."); + } + + + void clearAllCaches() { + clearContactCache(); + clearChatsCache(); + _messageCache.clear(); + clearPasswordAuthData(); + print("Все кэши очищены из-за ошибки подключения."); + } + + + Future clearAllData() async { + try { + + clearAllCaches(); + + + authToken = null; + + + final prefs = await SharedPreferences.getInstance(); + await prefs.clear(); + + + _pingTimer?.cancel(); + await _channel?.sink.close(); + _channel = null; + + + _isSessionOnline = false; + _isSessionReady = false; + _chatsFetchedInThisSession = false; + _reconnectAttempts = 0; + _currentUrlIndex = 0; + + + _messageQueue.clear(); + _presenceData.clear(); + + print("Все данные приложения полностью очищены."); + } catch (e) { + print("Ошибка при полной очистке данных: $e"); + rethrow; + } + } + + + void sendMessage( + int chatId, + String text, { + String? replyToMessageId, + int? cid, + }) { + final int clientMessageId = cid ?? DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": text, + "cid": clientMessageId, + "elements": [], + "attaches": [], + if (replyToMessageId != null) + "link": {"type": "REPLY", "messageId": replyToMessageId}, + }, + "notify": true, + }; + + + clearChatsCache(); + + if (_isSessionOnline) { + _sendMessage(64, payload); + } else { + print("Сессия не онлайн. Сообщение добавлено в очередь."); + _messageQueue.add({'opcode': 64, 'payload': payload}); + } + } + + void _processMessageQueue() { + if (_messageQueue.isEmpty) return; + print("Отправка ${_messageQueue.length} сообщений из очереди..."); + for (var message in _messageQueue) { + _sendMessage(message['opcode'], message['payload']); + } + _messageQueue.clear(); + } + + + Future editMessage(int chatId, String messageId, String newText) async { + final payload = { + "chatId": chatId, + "messageId": messageId, + "text": newText, + "elements": [], + "attachments": [], + }; + + + clearChatsCache(); + + + await waitUntilOnline(); + + + if (!_isSessionOnline) { + print('Сессия не онлайн, пытаемся переподключиться...'); + await reconnect(); + await waitUntilOnline(); + } + + Future sendOnce() async { + try { + final int seq = _sendMessage(67, payload); + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 10)); + + + if (response['cmd'] == 3) { + final error = response['payload']; + print('Ошибка редактирования сообщения: $error'); + + + if (error['error'] == 'proto.state') { + print('Ошибка состояния сессии, переподключаемся...'); + await reconnect(); + await waitUntilOnline(); + return false; // Попробуем еще раз + } + + + if (error['error'] == 'error.edit.invalid.message') { + print( + 'Сообщение не может быть отредактировано: ${error['localizedMessage']}', + ); + throw Exception( + 'Сообщение не может быть отредактировано: ${error['localizedMessage']}', + ); + } + + return false; + } + + return response['cmd'] == 1; // Успешный ответ + } catch (e) { + print('Ошибка при редактировании сообщения: $e'); + return false; + } + } + + + for (int attempt = 0; attempt < 3; attempt++) { + print( + 'Попытка редактирования сообщения $messageId (попытка ${attempt + 1}/3)', + ); + bool ok = await sendOnce(); + if (ok) { + print('Сообщение $messageId успешно отредактировано'); + return; + } + + if (attempt < 2) { + print( + 'Повторяем запрос редактирования для сообщения $messageId через 2 секунды...', + ); + await Future.delayed(const Duration(seconds: 2)); + } + } + + print('Не удалось отредактировать сообщение $messageId после 3 попыток'); + } + + + Future deleteMessage( + int chatId, + String messageId, { + bool forMe = false, + }) async { + final payload = { + "chatId": chatId, + "messageIds": [messageId], + "forMe": forMe, + }; + + + clearChatsCache(); + + + await waitUntilOnline(); + + + if (!_isSessionOnline) { + print('Сессия не онлайн, пытаемся переподключиться...'); + await reconnect(); + await waitUntilOnline(); + } + + Future sendOnce() async { + try { + final int seq = _sendMessage(66, payload); + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 10)); + + + if (response['cmd'] == 3) { + final error = response['payload']; + print('Ошибка удаления сообщения: $error'); + + + if (error['error'] == 'proto.state') { + print('Ошибка состояния сессии, переподключаемся...'); + await reconnect(); + await waitUntilOnline(); + return false; // Попробуем еще раз + } + return false; + } + + return response['cmd'] == 1; // Успешный ответ + } catch (e) { + print('Ошибка при удалении сообщения: $e'); + return false; + } + } + + + for (int attempt = 0; attempt < 3; attempt++) { + print('Попытка удаления сообщения $messageId (попытка ${attempt + 1}/3)'); + bool ok = await sendOnce(); + if (ok) { + print('Сообщение $messageId успешно удалено'); + return; + } + + if (attempt < 2) { + print( + 'Повторяем запрос удаления для сообщения $messageId через 2 секунды...', + ); + await Future.delayed(const Duration(seconds: 2)); + } + } + + print('Не удалось удалить сообщение $messageId после 3 попыток'); + } + + + void sendTyping(int chatId, {String type = "TEXT"}) { + final payload = {"chatId": chatId, "type": type}; + if (_isSessionOnline) { + _sendMessage(65, payload); + } + } + + + void updateProfileText( + String firstName, + String lastName, + String description, + ) { + final payload = { + "firstName": firstName, + "lastName": lastName, + "description": description, + }; + _sendMessage(16, payload); + } + + + Future updateProfilePhoto(String firstName, String lastName) async { + try { + + final picker = ImagePicker(); + final XFile? image = await picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + + + print("Запрашиваем URL для загрузки фото..."); + final int seq = _sendMessage(80, {"count": 1}); + final response = await messages.firstWhere((msg) => msg['seq'] == seq); + final String uploadUrl = response['payload']['url']; + print("URL получен: $uploadUrl"); + + + print("Загружаем фото на сервер..."); + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', image.path)); + var streamedResponse = await request.send(); + var httpResponse = await http.Response.fromStream(streamedResponse); + + if (httpResponse.statusCode != 200) { + throw Exception("Ошибка загрузки фото: ${httpResponse.body}"); + } + + final uploadResult = jsonDecode(httpResponse.body); + final String photoToken = uploadResult['photos'].values.first['token']; + print("Фото загружено, получен токен: $photoToken"); + + + print("Привязываем фото к профилю..."); + final payload = { + "firstName": firstName, + "lastName": lastName, + "photoToken": photoToken, + "avatarType": "USER_AVATAR", + }; + _sendMessage(16, payload); + print("Запрос на смену аватара отправлен."); + } catch (e) { + print("!!! Ошибка в процессе смены аватара: $e"); + } + } + + + Future sendPhotoMessage( + int chatId, { + String? localPath, + String? caption, + int? cidOverride, + int? senderId, // my user id to mark local echo as mine + }) async { + try { + XFile? image; + if (localPath != null) { + image = XFile(localPath); + } else { + + final picker = ImagePicker(); + image = await picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + } + + await waitUntilOnline(); + + final int seq80 = _sendMessage(80, {"count": 1}); + final resp80 = await messages.firstWhere((m) => m['seq'] == seq80); + final String uploadUrl = resp80['payload']['url']; + + + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', image.path)); + var streamed = await request.send(); + var httpResp = await http.Response.fromStream(streamed); + if (httpResp.statusCode != 200) { + throw Exception( + 'Ошибка загрузки фото: ${httpResp.statusCode} ${httpResp.body}', + ); + } + final uploadJson = jsonDecode(httpResp.body) as Map; + final Map photos = uploadJson['photos'] as Map; + if (photos.isEmpty) throw Exception('Не получен токен фото'); + final String photoToken = (photos.values.first as Map)['token']; + + + final int cid = cidOverride ?? DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": caption?.trim() ?? "", + "cid": cid, + "elements": [], + "attaches": [ + {"_type": "PHOTO", "photoToken": photoToken}, + ], + }, + "notify": true, + }; + + clearChatsCache(); + + if (localPath != null) { + _emitLocal({ + 'ver': 11, + 'cmd': 1, + 'seq': -1, + 'opcode': 128, + 'payload': { + 'chatId': chatId, + 'message': { + 'id': 'local_$cid', + 'sender': senderId ?? 0, + 'time': DateTime.now().millisecondsSinceEpoch, + 'text': caption?.trim() ?? '', + 'type': 'USER', + 'cid': cid, + 'attaches': [ + {'_type': 'PHOTO', 'url': 'file://$localPath'}, + ], + }, + }, + }); + } + + _sendMessage(64, payload); + } catch (e) { + print('Ошибка отправки фото-сообщения: $e'); + } + } + + + Future sendPhotoMessages( + int chatId, { + required List localPaths, + String? caption, + int? senderId, + }) async { + if (localPaths.isEmpty) return; + try { + await waitUntilOnline(); + + + final int cid = DateTime.now().millisecondsSinceEpoch; + _emitLocal({ + 'ver': 11, + 'cmd': 1, + 'seq': -1, + 'opcode': 128, + 'payload': { + 'chatId': chatId, + 'message': { + 'id': 'local_$cid', + 'sender': senderId ?? 0, + 'time': DateTime.now().millisecondsSinceEpoch, + 'text': caption?.trim() ?? '', + 'type': 'USER', + 'cid': cid, + 'attaches': [ + for (final p in localPaths) + {'_type': 'PHOTO', 'url': 'file://$p'}, + ], + }, + }, + }); + + + final List> photoTokens = []; + for (final path in localPaths) { + final int seq80 = _sendMessage(80, {"count": 1}); + final resp80 = await messages.firstWhere((m) => m['seq'] == seq80); + final String uploadUrl = resp80['payload']['url']; + + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', path)); + var streamed = await request.send(); + var httpResp = await http.Response.fromStream(streamed); + if (httpResp.statusCode != 200) { + throw Exception( + 'Ошибка загрузки фото: ${httpResp.statusCode} ${httpResp.body}', + ); + } + final uploadJson = jsonDecode(httpResp.body) as Map; + final Map photos = uploadJson['photos'] as Map; + if (photos.isEmpty) throw Exception('Не получен токен фото'); + final String photoToken = (photos.values.first as Map)['token']; + photoTokens.add({"token": photoToken}); + } + + final payload = { + "chatId": chatId, + "message": { + "text": caption?.trim() ?? "", + "cid": cid, + "elements": [], + "attaches": [ + for (final t in photoTokens) + {"_type": "PHOTO", "photoToken": t["token"]}, + ], + }, + "notify": true, + }; + + clearChatsCache(); + _sendMessage(64, payload); + } catch (e) { + print('Ошибка отправки фото-сообщений: $e'); + } + } + + + Future sendFileMessage( + int chatId, { + String? caption, + int? senderId, // my user id to mark local echo as mine + }) async { + try { + + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.any, + ); + + if (result == null || result.files.single.path == null) { + print("Выбор файла отменен"); + return; + } + + final String filePath = result.files.single.path!; + final String fileName = result.files.single.name; + final int fileSize = result.files.single.size; + + await waitUntilOnline(); + + + final int seq87 = _sendMessage(87, {"count": 1}); + final resp87 = await messages.firstWhere((m) => m['seq'] == seq87); + + if (resp87['payload'] == null || + resp87['payload']['info'] == null || + (resp87['payload']['info'] as List).isEmpty) { + throw Exception('Неверный ответ на Opcode 87: отсутствует "info"'); + } + + final uploadInfo = (resp87['payload']['info'] as List).first; + final String uploadUrl = uploadInfo['url']; + final int fileId = uploadInfo['fileId']; // <-- Ключевое отличие от фото + + print('Получен fileId: $fileId и URL: $uploadUrl'); + + + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', filePath)); + var streamed = await request.send(); + var httpResp = await http.Response.fromStream(streamed); + if (httpResp.statusCode != 200) { + throw Exception( + 'Ошибка загрузки файла: ${httpResp.statusCode} ${httpResp.body}', + ); + } + + print('Файл успешно загружен на сервер.'); + + + + final int cid = DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": caption?.trim() ?? "", + "cid": cid, + "elements": [], + "attaches": [ + {"_type": "FILE", "fileId": fileId}, // <-- Используем fileId + ], + }, + "notify": true, + }; + + clearChatsCache(); + + + _emitLocal({ + 'ver': 11, + 'cmd': 1, + 'seq': -1, + 'opcode': 128, + 'payload': { + 'chatId': chatId, + 'message': { + 'id': 'local_$cid', + 'sender': senderId ?? 0, + 'time': DateTime.now().millisecondsSinceEpoch, + 'text': caption?.trim() ?? '', + 'type': 'USER', + 'cid': cid, + 'attaches': [ + { + '_type': 'FILE', + 'name': fileName, + 'size': fileSize, + 'url': 'file://$filePath', // Локальный путь для UI + }, + ], + }, + }, + }); + + _sendMessage(64, payload); + print('Сообщение о файле (Opcode 64) отправлено.'); + } catch (e) { + print('Ошибка отправки файла: $e'); + } + } + + void _startPinging() { + _pingTimer?.cancel(); + _pingTimer = Timer.periodic(const Duration(seconds: 25), (timer) { + if (_isSessionOnline && _isSessionReady) { + print("Отправляем Ping для поддержания сессии..."); + _sendMessage(1, {"interactive": true}); + } else { + print("Сессия не готова, пропускаем ping"); + } + }); + } + + Future saveToken(String token, {String? userId}) async { + print("Сохраняем новый токен: ${token.substring(0, 20)}..."); + if (userId != null) { + print("Сохраняем UserID: $userId"); + } + authToken = token; + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('authToken', token); + if (_channel != null) { + disconnect(); + } + await connect(); + await getChatsAndContacts(force: true); + if (userId != null) { + await prefs.setString('userId', userId); + } + print("Токен и UserID успешно сохранены в SharedPreferences"); + } + + Future hasToken() async { + + if (authToken == null) { + final prefs = await SharedPreferences.getInstance(); + authToken = prefs.getString('authToken'); + userId = prefs.getString('userId'); + if (authToken != null) { + print( + "Токен загружен из SharedPreferences: ${authToken!.substring(0, 20)}...", + ); + if (userId != null) { + print("UserID загружен из SharedPreferences: $userId"); + } + } + } + return authToken != null; + } + + Future> fetchContactsByIds(List contactIds) async { + + if (contactIds.isEmpty) { + return []; + } + + print('Запрашиваем данные для ${contactIds.length} контактов...'); + try { + final int contactSeq = _sendMessage(32, {"contactIds": contactIds}); + + + final contactResponse = await messages + .firstWhere((msg) => msg['seq'] == contactSeq) + .timeout(const Duration(seconds: 10)); + + + if (contactResponse['cmd'] == 3) { + print( + "Ошибка при получении контактов по ID: ${contactResponse['payload']}", + ); + return []; + } + + final List contactListJson = + contactResponse['payload']?['contacts'] ?? []; + final contacts = contactListJson + .map((json) => Contact.fromJson(json)) + .toList(); + + + for (final contact in contacts) { + _contactCache[contact.id] = contact; + } + print("Получены и закэшированы данные для ${contacts.length} контактов."); + return contacts; + } catch (e) { + print('Исключение при получении контактов по ID: $e'); + return []; + } + } + + Future logout() async { + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('authToken'); + await prefs.remove('userId'); + authToken = null; + userId = null; + _messageCache.clear(); + _lastChatsPayload = null; + _chatsFetchedInThisSession = false; + _pingTimer?.cancel(); + await _channel?.sink.close(status.goingAway); + _channel = null; + } catch (_) {} + } + + Future connect() async { + + if (_channel != null && _isSessionOnline) { + print("WebSocket уже подключен, пропускаем подключение"); + return; + } + + print("Запускаем подключение к WebSocket..."); + + + _isSessionOnline = false; + _isSessionReady = false; + + + _connectionStatusController.add("connecting"); + await _connectWithFallback(); + } + + Future reconnect() async { + _reconnectAttempts = + 0; // Сбрасываем счетчик попыток при ручном переподключении + _currentUrlIndex = 0; // Сбрасываем индекс для повторной попытки + + _connectionStatusController.add("connecting"); + await _connectWithFallback(); + } + + + + + void sendFullJsonRequest(String jsonString) { + if (_channel == null) { + throw Exception('WebSocket is not connected. Connect first.'); + } + _log('➡️ SEND (raw): $jsonString'); + _channel!.sink.add(jsonString); + } + + + + + int sendRawRequest(int opcode, Map payload) { + if (_channel == null) { + print('WebSocket не подключен!'); + + throw Exception('WebSocket is not connected. Connect first.'); + } + + return _sendMessage(opcode, payload); + } + + + + int sendAndTrackFullJsonRequest(String jsonString) { + if (_channel == null) { + throw Exception('WebSocket is not connected. Connect first.'); + } + + + final message = jsonDecode(jsonString) as Map; + + + final int currentSeq = _seq++; + + + message['seq'] = currentSeq; + + + final encodedMessage = jsonEncode(message); + + _log('➡️ SEND (custom): $encodedMessage'); + print('Отправляем кастомное сообщение (seq: $currentSeq): $encodedMessage'); + + _channel!.sink.add(encodedMessage); + + + return currentSeq; + } + + int _sendMessage(int opcode, Map payload) { + if (_channel == null) { + print('WebSocket не подключен!'); + return -1; + } + final message = { + "ver": 11, + "cmd": 0, + "seq": _seq, + "opcode": opcode, + "payload": payload, + }; + final encodedMessage = jsonEncode(message); + if (opcode == 1) { + + _log('➡️ SEND (ping) seq: $_seq'); + } else if (opcode == 18 || opcode == 19) { + + Map loggablePayload = Map.from(payload); + if (loggablePayload.containsKey('token')) { + String token = loggablePayload['token'] as String; + + loggablePayload['token'] = token.length > 8 + ? '${token.substring(0, 4)}...${token.substring(token.length - 4)}' + : '***'; + } + final loggableMessage = {...message, 'payload': loggablePayload}; + _log('➡️ SEND: ${jsonEncode(loggableMessage)}'); + } else { + _log('➡️ SEND: $encodedMessage'); + } + print('Отправляем сообщение (seq: $_seq): $encodedMessage'); + _channel!.sink.add(encodedMessage); + return _seq++; + } + + void _listen() async { + _streamSubscription?.cancel(); // Отменяем предыдущую подписку + _streamSubscription = _channel?.stream.listen( + (message) { + if (message == null) return; + if (message is String && message.trim().isEmpty) { + + return; + } + + + String loggableMessage = message; + try { + final decoded = jsonDecode(message) as Map; + if (decoded['opcode'] == 2) { + + loggableMessage = '⬅️ RECV (pong) seq: ${decoded['seq']}'; + } else { + Map loggableDecoded = Map.from(decoded); + bool wasModified = false; + if (loggableDecoded.containsKey('payload') && + loggableDecoded['payload'] is Map) { + Map payload = Map.from( + loggableDecoded['payload'], + ); + if (payload.containsKey('token')) { + String token = payload['token'] as String; + payload['token'] = token.length > 8 + ? '${token.substring(0, 4)}...${token.substring(token.length - 4)}' + : '***'; + loggableDecoded['payload'] = payload; + wasModified = true; + } + } + if (wasModified) { + loggableMessage = '⬅️ RECV: ${jsonEncode(loggableDecoded)}'; + } else { + loggableMessage = '⬅️ RECV: $message'; + } + } + } catch (_) { + loggableMessage = '⬅️ RECV (raw): $message'; + } + _log(loggableMessage); + + + try { + final decodedMessage = message is String + ? jsonDecode(message) + : message; + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 97 && + decodedMessage['cmd'] == 1 && + decodedMessage['payload'] != null && + decodedMessage['payload']['token'] != null) { + _handleSessionTerminated(); + return; + } + + if (decodedMessage is Map && + decodedMessage['opcode'] == 6 && + decodedMessage['cmd'] == 1) { + print("Handshake успешен. Сессия ONLINE."); + _isSessionOnline = true; + _isSessionReady = false; + _reconnectDelaySeconds = 2; + _connectionStatusController.add("authorizing"); + + if (_onlineCompleter != null && !_onlineCompleter!.isCompleted) { + _onlineCompleter!.complete(); + } + _startPinging(); + _processMessageQueue(); + } + + + if (decodedMessage is Map && decodedMessage['cmd'] == 3) { + final error = decodedMessage['payload']; + print('Ошибка сервера: $error'); + + if (error != null && error['localizedMessage'] != null) { + _errorController.add(error['localizedMessage']); + } else if (error != null && error['message'] != null) { + _errorController.add(error['message']); + } + + if (error != null && error['message'] == 'FAIL_WRONG_PASSWORD') { + _errorController.add('FAIL_WRONG_PASSWORD'); + } + + + if (error != null && error['error'] == 'password.invalid') { + _errorController.add('Неверный пароль'); + } + + if (error != null && error['error'] == 'proto.state') { + print('Ошибка состояния сессии, переподключаемся...'); + _chatsFetchedInThisSession = false; + _reconnect(); + return; + } + + if (error != null && error['error'] == 'login.token') { + print('Токен недействителен, очищаем и завершаем сессию...'); + _handleInvalidToken(); + return; + } + + if (error != null && error['message'] == 'FAIL_WRONG_PASSWORD') { + print('Неверный токен авторизации, очищаем токен...'); + _clearAuthToken().then((_) { + _chatsFetchedInThisSession = false; + _messageController.add({ + 'type': 'invalid_token', + 'message': + 'Токен авторизации недействителен. Требуется повторная авторизация.', + }); + _reconnect(); + }); + return; + } + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 18 && + decodedMessage['cmd'] == 1 && + decodedMessage['payload'] != null) { + final payload = decodedMessage['payload']; + if (payload['passwordChallenge'] != null) { + final challenge = payload['passwordChallenge']; + _currentPasswordTrackId = challenge['trackId']; + _currentPasswordHint = challenge['hint']; + _currentPasswordEmail = challenge['email']; + + print( + 'Получен запрос на ввод пароля: trackId=${challenge['trackId']}, hint=${challenge['hint']}, email=${challenge['email']}', + ); + + + _messageController.add({ + 'type': 'password_required', + 'trackId': _currentPasswordTrackId, + 'hint': _currentPasswordHint, + 'email': _currentPasswordEmail, + }); + return; + } + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 22 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Настройки приватности успешно обновлены: $payload'); + + + _messageController.add({ + 'type': 'privacy_settings_updated', + 'settings': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 116 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Пароль успешно установлен: $payload'); + + + _messageController.add({ + 'type': 'password_set_success', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 57 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Успешно присоединились к группе: $payload'); + + + _messageController.add({ + 'type': 'group_join_success', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 46 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Контакт найден: $payload'); + + + _messageController.add({ + 'type': 'contact_found', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 46 && + decodedMessage['cmd'] == 3) { + final payload = decodedMessage['payload']; + print('Контакт не найден: $payload'); + + + _messageController.add({ + 'type': 'contact_not_found', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 32 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Каналы найдены: $payload'); + + + _messageController.add({ + 'type': 'channels_found', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 32 && + decodedMessage['cmd'] == 3) { + final payload = decodedMessage['payload']; + print('Каналы не найдены: $payload'); + + + _messageController.add({ + 'type': 'channels_not_found', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 89 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Вход в канал успешен: $payload'); + + + _messageController.add({ + 'type': 'channel_entered', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 89 && + decodedMessage['cmd'] == 3) { + final payload = decodedMessage['payload']; + print('Ошибка входа в канал: $payload'); + + + _messageController.add({ + 'type': 'channel_error', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 57 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Подписка на канал успешна: $payload'); + + + _messageController.add({ + 'type': 'channel_subscribed', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 57 && + decodedMessage['cmd'] == 3) { + final payload = decodedMessage['payload']; + print('Ошибка подписки на канал: $payload'); + + + _messageController.add({ + 'type': 'channel_error', + 'payload': payload, + }); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 59 && + decodedMessage['cmd'] == 1) { + final payload = decodedMessage['payload']; + print('Получены участники группы: $payload'); + + + _messageController.add({ + 'type': 'group_members', + 'payload': payload, + }); + } + + if (decodedMessage is Map) { + _messageController.add(decodedMessage); + } + } catch (e) { + print('Невалидное сообщение от сервера, пропускаем: $e'); + } + }, + onError: (error) { + print('Ошибка WebSocket: $error'); + _isSessionOnline = false; + _isSessionReady = false; + _reconnect(); + }, + onDone: () { + print('WebSocket соединение закрыто. Попытка переподключения...'); + _isSessionOnline = false; + _isSessionReady = false; + + if (!_isSessionReady) { + _reconnect(); + } + }, + cancelOnError: true, + ); + } + + void _reconnect() { + if (_isReconnecting) return; + + _isReconnecting = true; + _reconnectAttempts++; + + if (_reconnectAttempts > _maxReconnectAttempts) { + print( + "Превышено максимальное количество попыток переподключения ($_maxReconnectAttempts). Останавливаем попытки.", + ); + _connectionStatusController.add("disconnected"); + _isReconnecting = false; + return; + } + + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + _isSessionOnline = false; + _isSessionReady = false; + _onlineCompleter = Completer(); + _chatsFetchedInThisSession = false; + + + clearAllCaches(); + + + _currentUrlIndex = 0; + + + _reconnectDelaySeconds = (_reconnectDelaySeconds * 2).clamp(1, 30); + final jitter = (DateTime.now().millisecondsSinceEpoch % 1000) / 1000.0; + final delay = Duration(seconds: _reconnectDelaySeconds + jitter.round()); + + _reconnectTimer = Timer(delay, () { + print( + "Переподключаемся после ${delay.inSeconds}s... (попытка $_reconnectAttempts/$_maxReconnectAttempts)", + ); + _isReconnecting = false; + _connectWithFallback(); + }); + } + + Future getVideoUrl(int videoId, int chatId, String messageId) async { + await waitUntilOnline(); + + final payload = { + "videoId": videoId, + "chatId": chatId, + "messageId": messageId, + }; + + final int seq = _sendMessage(83, payload); + print('Запрашиваем URL для videoId: $videoId (seq: $seq)'); + + try { + + final response = await messages + .firstWhere((msg) => msg['seq'] == seq && msg['opcode'] == 83) + .timeout(const Duration(seconds: 15)); + + + if (response['cmd'] == 3) { + throw Exception( + 'Ошибка получения URL видео: ${response['payload']?['message']}', + ); + } + + + final videoPayload = response['payload'] as Map?; + if (videoPayload == null) { + throw Exception('Получен пустой payload для видео'); + } + + + String? videoUrl = + videoPayload['MP4_720'] as String? ?? + videoPayload['MP4_480'] as String? ?? + videoPayload['MP4_1080'] as String? ?? + videoPayload['MP4_360'] as String?; + + + if (videoUrl == null) { + final mp4Key = videoPayload.keys.firstWhere( + (k) => k.startsWith('MP4_'), + orElse: () => '', + ); + if (mp4Key.isNotEmpty) { + videoUrl = videoPayload[mp4Key] as String?; + } + } + + if (videoUrl != null) { + print('URL для videoId: $videoId успешно получен.'); + return videoUrl; + } else { + throw Exception('Не найден ни один MP4 URL в ответе'); + } + } on TimeoutException { + print('Таймаут ожидания URL для videoId: $videoId'); + throw Exception('Сервер не ответил на запрос видео вовремя'); + } catch (e) { + print('Ошибка в getVideoUrl: $e'); + rethrow; // Передаем ошибку дальше + } + } + + void disconnect() { + print("Отключаем WebSocket..."); + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + _streamSubscription?.cancel(); // Отменяем подписку на stream + _isSessionOnline = false; + _isSessionReady = false; + _handshakeSent = false; // Сбрасываем флаг handshake + _onlineCompleter = Completer(); + _chatsFetchedInThisSession = false; + + + _channel?.sink.close(status.goingAway); + _channel = null; + _streamSubscription = null; + + + _connectionStatusController.add("disconnected"); + } + + Future getClipboardData() async { + final data = await Clipboard.getData(Clipboard.kTextPlain); + return data?.text; + } + + + void forceReconnect() { + print("Принудительное переподключение..."); + + + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + if (_channel != null) { + print("Закрываем существующее соединение..."); + _channel!.sink.close(status.goingAway); + _channel = null; + } + + + _isReconnecting = false; + _reconnectAttempts = 0; + _reconnectDelaySeconds = 2; + _isSessionOnline = false; + _isSessionReady = false; + _chatsFetchedInThisSession = false; + _currentUrlIndex = 0; + _onlineCompleter = Completer(); // Re-create completer + + + clearAllCaches(); + _messageQueue.clear(); + _presenceData.clear(); + + + _connectionStatusController.add("connecting"); + _log("Запускаем новую сессию подключения..."); + + + _connectWithFallback(); + } + + + Future performFullReconnection() async { + print("🔄 Начинаем полное переподключение..."); + try { + + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + _streamSubscription?.cancel(); + + + if (_channel != null) { + _channel!.sink.close(); + _channel = null; + } + + + _isReconnecting = false; + _reconnectAttempts = 0; + _reconnectDelaySeconds = 2; + _isSessionOnline = false; + _isSessionReady = false; + _handshakeSent = false; + _chatsFetchedInThisSession = false; // КРИТИЧНО: сбрасываем этот флаг + _currentUrlIndex = 0; + _onlineCompleter = Completer(); + _seq = 0; + + + _lastChatsPayload = null; + _lastChatsAt = null; + + print( + "✅ Кэш чатов очищен: _lastChatsPayload = $_lastChatsPayload, _chatsFetchedInThisSession = $_chatsFetchedInThisSession", + ); + + _connectionStatusController.add("disconnected"); + + + await connect(); + + print("✅ Полное переподключение завершено"); + + + await Future.delayed(const Duration(milliseconds: 1500)); + + + if (!_reconnectionCompleteController.isClosed) { + print("📢 Отправляем уведомление о завершении переподключения"); + _reconnectionCompleteController.add(null); + } + } catch (e) { + print("❌ Ошибка полного переподключения: $e"); + rethrow; + } + } + + + Future updatePrivacySettings({ + String? hidden, + String? searchByPhone, + String? incomingCall, + String? chatsInvite, + bool? chatsPushNotification, + String? chatsPushSound, + String? pushSound, + bool? mCallPushNotification, + bool? pushDetails, + }) async { + final settings = { + if (hidden != null) 'user': {'HIDDEN': hidden == 'true'}, + if (searchByPhone != null) 'user': {'SEARCH_BY_PHONE': searchByPhone}, + if (incomingCall != null) 'user': {'INCOMING_CALL': incomingCall}, + if (chatsInvite != null) 'user': {'CHATS_INVITE': chatsInvite}, + if (chatsPushNotification != null) + 'user': {'PUSH_NEW_CONTACTS': chatsPushNotification}, + if (chatsPushSound != null) 'user': {'PUSH_SOUND': chatsPushSound}, + if (pushSound != null) 'user': {'PUSH_SOUND_GLOBAL': pushSound}, + if (mCallPushNotification != null) + 'user': {'PUSH_MCALL': mCallPushNotification}, + if (pushDetails != null) 'user': {'PUSH_DETAILS': pushDetails}, + }; + + print('Обновляем настройки приватности: $settings'); + + + if (hidden != null) { + await _updateSinglePrivacySetting({'HIDDEN': hidden == 'true'}); + } + if (searchByPhone != null) { + await _updateSinglePrivacySetting({'SEARCH_BY_PHONE': searchByPhone}); + } + if (incomingCall != null) { + await _updateSinglePrivacySetting({'INCOMING_CALL': incomingCall}); + } + if (chatsInvite != null) { + await _updateSinglePrivacySetting({'CHATS_INVITE': chatsInvite}); + } + + + if (chatsPushNotification != null) { + await _updateSinglePrivacySetting({ + 'PUSH_NEW_CONTACTS': chatsPushNotification, + }); + } + if (chatsPushSound != null) { + await _updateSinglePrivacySetting({'PUSH_SOUND': chatsPushSound}); + } + if (pushSound != null) { + await _updateSinglePrivacySetting({'PUSH_SOUND_GLOBAL': pushSound}); + } + if (mCallPushNotification != null) { + await _updateSinglePrivacySetting({'PUSH_MCALL': mCallPushNotification}); + } + if (pushDetails != null) { + await _updateSinglePrivacySetting({'PUSH_DETAILS': pushDetails}); + } + } + + + Future _updateSinglePrivacySetting(Map setting) async { + await waitUntilOnline(); + + final payload = {'settings': setting}; + + _sendMessage(22, payload); + print('Отправляем обновление настройки приватности: $payload'); + } + + void dispose() { + _pingTimer?.cancel(); + _channel?.sink.close(status.goingAway); + _reconnectionCompleteController.close(); + _messageController.close(); + } +} diff --git a/lib/api_service_simple.dart b/lib/api_service_simple.dart new file mode 100644 index 0000000..d6aa10c --- /dev/null +++ b/lib/api_service_simple.dart @@ -0,0 +1,774 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'package:image_picker/image_picker.dart'; + +import 'connection/connection_manager_simple.dart'; +import 'connection/connection_logger.dart'; +import 'connection/connection_state.dart'; +import 'connection/health_monitor.dart'; +import 'models/message.dart'; +import 'models/contact.dart'; + + +class ApiServiceSimple { + ApiServiceSimple._privateConstructor(); + static final ApiServiceSimple instance = + ApiServiceSimple._privateConstructor(); + + + final ConnectionManagerSimple _connectionManager = ConnectionManagerSimple(); + + + final ConnectionLogger _logger = ConnectionLogger(); + + + String? _authToken; + bool _isInitialized = false; + + + final Map> _messageCache = {}; + final Map _contactCache = {}; + Map? _lastChatsPayload; + DateTime? _lastChatsAt; + final Duration _chatsCacheTtl = const Duration(seconds: 5); + bool _chatsFetchedInThisSession = false; + + + final Map _presenceData = {}; + + + final StreamController _contactUpdatesController = + StreamController.broadcast(); + final StreamController> _messageController = + StreamController>.broadcast(); + + + Stream> get messages => _messageController.stream; + + + Stream get contactUpdates => _contactUpdatesController.stream; + + + Stream get connectionState => _connectionManager.stateStream; + + + Stream get logs => _connectionManager.logStream; + + + Stream get healthMetrics => + _connectionManager.healthMetricsStream; + + + ConnectionInfo get currentState => _connectionManager.currentState; + + + bool get isOnline => _connectionManager.isConnected; + + + bool get canSendMessages => _connectionManager.canSendMessages; + + + Future initialize() async { + if (_isInitialized) { + _logger.logConnection('ApiServiceSimple уже инициализирован'); + return; + } + + _logger.logConnection('Инициализация ApiServiceSimple'); + + try { + await _connectionManager.initialize(); + _setupMessageHandlers(); + _isInitialized = true; + + _logger.logConnection('ApiServiceSimple успешно инициализирован'); + } catch (e) { + _logger.logError('Ошибка инициализации ApiServiceSimple', error: e); + rethrow; + } + } + + + void _setupMessageHandlers() { + _connectionManager.messageStream.listen((message) { + _handleIncomingMessage(message); + }); + } + + + void _handleIncomingMessage(Map message) { + try { + _logger.logMessage('IN', message); + + + if (message['opcode'] == 128 && message['payload'] != null) { + _handleContactUpdate(message['payload']); + } + + + if (message['opcode'] == 129 && message['payload'] != null) { + _handlePresenceUpdate(message['payload']); + } + + + _messageController.add(message); + } catch (e) { + _logger.logError( + 'Ошибка обработки входящего сообщения', + data: {'message': message, 'error': e.toString()}, + ); + } + } + + + void _handleContactUpdate(Map payload) { + try { + final contact = Contact.fromJson(payload); + _contactCache[contact.id] = contact; + _contactUpdatesController.add(contact); + + _logger.logConnection( + 'Контакт обновлен', + data: {'contact_id': contact.id, 'contact_name': contact.name}, + ); + } catch (e) { + _logger.logError( + 'Ошибка обработки обновления контакта', + data: {'payload': payload, 'error': e.toString()}, + ); + } + } + + + void _handlePresenceUpdate(Map payload) { + try { + _presenceData.addAll(payload); + _logger.logConnection( + 'Presence данные обновлены', + data: {'keys': payload.keys.toList()}, + ); + } catch (e) { + _logger.logError( + 'Ошибка обработки presence данных', + data: {'payload': payload, 'error': e.toString()}, + ); + } + } + + + Future connect() async { + _logger.logConnection('Запрос подключения к серверу'); + + try { + await _connectionManager.connect(authToken: _authToken); + _logger.logConnection('Подключение к серверу успешно'); + } catch (e) { + _logger.logError('Ошибка подключения к серверу', error: e); + rethrow; + } + } + + + Future reconnect() async { + _logger.logConnection('Запрос переподключения'); + + try { + await _connectionManager.connect(authToken: _authToken); + _logger.logConnection('Переподключение успешно'); + } catch (e) { + _logger.logError('Ошибка переподключения', error: e); + rethrow; + } + } + + + Future disconnect() async { + _logger.logConnection('Отключение от сервера'); + + try { + await _connectionManager.disconnect(); + _logger.logConnection('Отключение от сервера успешно'); + } catch (e) { + _logger.logError('Ошибка отключения', error: e); + } + } + + + int _sendMessage(int opcode, Map payload) { + if (!canSendMessages) { + _logger.logConnection( + 'Сообщение не отправлено - соединение не готово', + data: {'opcode': opcode, 'payload': payload}, + ); + return -1; + } + + try { + final seq = _connectionManager.sendMessage(opcode, payload); + _logger.logConnection( + 'Сообщение отправлено', + data: {'opcode': opcode, 'seq': seq, 'payload': payload}, + ); + return seq; + } catch (e) { + _logger.logError( + 'Ошибка отправки сообщения', + data: {'opcode': opcode, 'payload': payload, 'error': e.toString()}, + ); + return -1; + } + } + + + Future sendHandshake() async { + _logger.logConnection('Отправка handshake'); + + final payload = { + "userAgent": { + "deviceType": "WEB", + "locale": "ru", + "deviceLocale": "ru", + "osVersion": "Windows", + "deviceName": "Chrome", + "headerUserAgent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "appVersion": "25.9.15", + "screen": "1920x1080 1.0x", + "timezone": "Europe/Moscow", + }, + "deviceId": _generateDeviceId(), + }; + + _sendMessage(6, payload); + } + + + void requestOtp(String phoneNumber) { + _logger.logConnection('Запрос OTP', data: {'phone': phoneNumber}); + + final payload = { + "phone": phoneNumber, + "type": "START_AUTH", + "language": "ru", + }; + _sendMessage(17, payload); + } + + + void verifyCode(String token, String code) { + _logger.logConnection( + 'Проверка кода', + data: {'token': token, 'code': code}, + ); + + final payload = { + "token": token, + "verifyCode": code, + "authTokenType": "CHECK_CODE", + }; + _sendMessage(18, payload); + } + + + Future> authenticateWithToken(String token) async { + _logger.logConnection('Аутентификация с токеном'); + + _authToken = token; + await saveToken(token); + + final payload = {"interactive": true, "token": token, "chatsCount": 100}; + + final seq = _sendMessage(19, payload); + + try { + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + _logger.logConnection( + 'Аутентификация успешна', + data: {'seq': seq, 'response_cmd': response['cmd']}, + ); + + return response['payload'] ?? {}; + } catch (e) { + _logger.logError( + 'Ошибка аутентификации', + data: {'token': token, 'error': e.toString()}, + ); + rethrow; + } + } + + + Future> getChatsAndContacts({bool force = false}) async { + _logger.logConnection('Запрос чатов и контактов', data: {'force': force}); + + + if (!force && _lastChatsPayload != null && _lastChatsAt != null) { + if (DateTime.now().difference(_lastChatsAt!) < _chatsCacheTtl) { + _logger.logConnection('Возвращаем данные из кэша'); + return _lastChatsPayload!; + } + } + + try { + final payload = {"chatsCount": 100}; + final seq = _sendMessage(48, payload); + + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + final List chatListJson = response['payload']?['chats'] ?? []; + + if (chatListJson.isEmpty) { + final result = {'chats': [], 'contacts': [], 'profile': null}; + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + return result; + } + + + final contactIds = {}; + for (var chatJson in chatListJson) { + final participants = + chatJson['participants'] as Map? ?? {}; + contactIds.addAll(participants.keys.map((id) => int.parse(id))); + } + + final contactSeq = _sendMessage(32, {"contactIds": contactIds.toList()}); + + final contactResponse = await messages + .firstWhere((msg) => msg['seq'] == contactSeq) + .timeout(const Duration(seconds: 30)); + + final List contactListJson = + contactResponse['payload']?['contacts'] ?? []; + + final result = { + 'chats': chatListJson, + 'contacts': contactListJson, + 'profile': null, + 'presence': null, + }; + + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + _chatsFetchedInThisSession = true; + + + final contacts = contactListJson + .map((json) => Contact.fromJson(json)) + .toList(); + updateContactCache(contacts); + + _logger.logConnection( + 'Чаты и контакты получены', + data: { + 'chats_count': chatListJson.length, + 'contacts_count': contactListJson.length, + }, + ); + + return result; + } catch (e) { + _logger.logError('Ошибка получения чатов и контактов', error: e); + rethrow; + } + } + + + Future> getMessageHistory( + int chatId, { + bool force = false, + }) async { + _logger.logConnection( + 'Запрос истории сообщений', + data: {'chat_id': chatId, 'force': force}, + ); + + if (!force && _messageCache.containsKey(chatId)) { + _logger.logConnection('История сообщений загружена из кэша'); + return _messageCache[chatId]!; + } + + try { + final payload = { + "chatId": chatId, + "from": DateTime.now() + .add(const Duration(days: 1)) + .millisecondsSinceEpoch, + "forward": 0, + "backward": 1000, + "getMessages": true, + }; + + final seq = _sendMessage(49, payload); + + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + if (response['cmd'] == 3) { + final error = response['payload']; + _logger.logError( + 'Ошибка получения истории сообщений', + data: {'chat_id': chatId, 'error': error}, + ); + throw Exception('Ошибка получения истории: ${error['message']}'); + } + + final List messagesJson = response['payload']?['messages'] ?? []; + final messagesList = + messagesJson.map((json) => Message.fromJson(json)).toList() + ..sort((a, b) => a.time.compareTo(b.time)); + + _messageCache[chatId] = messagesList; + + _logger.logConnection( + 'История сообщений получена', + data: {'chat_id': chatId, 'messages_count': messagesList.length}, + ); + + return messagesList; + } catch (e) { + _logger.logError( + 'Ошибка получения истории сообщений', + data: {'chat_id': chatId, 'error': e.toString()}, + ); + return []; + } + } + + + void sendMessage(int chatId, String text, {String? replyToMessageId}) { + _logger.logConnection( + 'Отправка сообщения', + data: { + 'chat_id': chatId, + 'text_length': text.length, + 'reply_to': replyToMessageId, + }, + ); + + final int clientMessageId = DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": text, + "cid": clientMessageId, + "elements": [], + "attaches": [], + if (replyToMessageId != null) + "link": {"type": "REPLY", "messageId": replyToMessageId}, + }, + "notify": true, + }; + + clearChatsCache(); + _sendMessage(64, payload); + } + + + Future sendPhotoMessage( + int chatId, { + String? localPath, + String? caption, + int? cidOverride, + int? senderId, + }) async { + _logger.logConnection( + 'Отправка фото', + data: {'chat_id': chatId, 'local_path': localPath, 'caption': caption}, + ); + + try { + XFile? image; + if (localPath != null) { + image = XFile(localPath); + } else { + final picker = ImagePicker(); + image = await picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + } + + + final seq80 = _sendMessage(80, {"count": 1}); + final resp80 = await messages + .firstWhere((m) => m['seq'] == seq80) + .timeout(const Duration(seconds: 30)); + + final String uploadUrl = resp80['payload']['url']; + + + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', image.path)); + var streamed = await request.send(); + var httpResp = await http.Response.fromStream(streamed); + + if (httpResp.statusCode != 200) { + throw Exception( + 'Ошибка загрузки фото: ${httpResp.statusCode} ${httpResp.body}', + ); + } + + final uploadJson = jsonDecode(httpResp.body) as Map; + final Map photos = uploadJson['photos'] as Map; + if (photos.isEmpty) throw Exception('Не получен токен фото'); + final String photoToken = (photos.values.first as Map)['token']; + + + final int cid = cidOverride ?? DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": caption?.trim() ?? "", + "cid": cid, + "elements": [], + "attaches": [ + {"_type": "PHOTO", "photoToken": photoToken}, + ], + }, + "notify": true, + }; + + clearChatsCache(); + _sendMessage(64, payload); + + _logger.logConnection( + 'Фото отправлено', + data: {'chat_id': chatId, 'photo_token': photoToken}, + ); + } catch (e) { + _logger.logError( + 'Ошибка отправки фото', + data: {'chat_id': chatId, 'error': e.toString()}, + ); + } + } + + + Future blockContact(int contactId) async { + _logger.logConnection( + 'Блокировка контакта', + data: {'contact_id': contactId}, + ); + _sendMessage(34, {'contactId': contactId, 'action': 'BLOCK'}); + } + + + Future unblockContact(int contactId) async { + _logger.logConnection( + 'Разблокировка контакта', + data: {'contact_id': contactId}, + ); + _sendMessage(34, {'contactId': contactId, 'action': 'UNBLOCK'}); + } + + + void getBlockedContacts() { + _logger.logConnection('Запрос заблокированных контактов'); + _sendMessage(36, {'status': 'BLOCKED', 'count': 100, 'from': 0}); + } + + + void createGroup(String name, List participantIds) { + _logger.logConnection( + 'Создание группы', + data: {'name': name, 'participants': participantIds}, + ); + + final payload = {"name": name, "participantIds": participantIds}; + _sendMessage(48, payload); + } + + + void addGroupMember( + int chatId, + List userIds, { + bool showHistory = true, + }) { + _logger.logConnection( + 'Добавление участника в группу', + data: {'chat_id': chatId, 'user_ids': userIds}, + ); + + final payload = { + "chatId": chatId, + "userIds": userIds, + "showHistory": showHistory, + "operation": "add", + }; + _sendMessage(77, payload); + } + + + void removeGroupMember( + int chatId, + List userIds, { + int cleanMsgPeriod = 0, + }) { + _logger.logConnection( + 'Удаление участника из группы', + data: {'chat_id': chatId, 'user_ids': userIds}, + ); + + final payload = { + "chatId": chatId, + "userIds": userIds, + "operation": "remove", + "cleanMsgPeriod": cleanMsgPeriod, + }; + _sendMessage(77, payload); + } + + + void leaveGroup(int chatId) { + _logger.logConnection('Выход из группы', data: {'chat_id': chatId}); + _sendMessage(58, {"chatId": chatId}); + } + + + void sendReaction(int chatId, String messageId, String emoji) { + _logger.logConnection( + 'Отправка реакции', + data: {'chat_id': chatId, 'message_id': messageId, 'emoji': emoji}, + ); + + final payload = { + "chatId": chatId, + "messageId": messageId, + "reaction": {"reactionType": "EMOJI", "id": emoji}, + }; + _sendMessage(178, payload); + } + + + void removeReaction(int chatId, String messageId) { + _logger.logConnection( + 'Удаление реакции', + data: {'chat_id': chatId, 'message_id': messageId}, + ); + + final payload = {"chatId": chatId, "messageId": messageId}; + _sendMessage(179, payload); + } + + + void sendTyping(int chatId, {String type = "TEXT"}) { + final payload = {"chatId": chatId, "type": type}; + _sendMessage(65, payload); + } + + + DateTime? getLastSeen(int userId) { + final userPresence = _presenceData[userId.toString()]; + if (userPresence != null && userPresence['seen'] != null) { + final seenTimestamp = userPresence['seen'] as int; + return DateTime.fromMillisecondsSinceEpoch(seenTimestamp * 1000); + } + return null; + } + + + void updateContactCache(List contacts) { + _contactCache.clear(); + for (final contact in contacts) { + _contactCache[contact.id] = contact; + } + _logger.logConnection( + 'Кэш контактов обновлен', + data: {'contacts_count': contacts.length}, + ); + } + + + Contact? getCachedContact(int contactId) { + return _contactCache[contactId]; + } + + + void clearChatsCache() { + _lastChatsPayload = null; + _lastChatsAt = null; + _chatsFetchedInThisSession = false; + _logger.logConnection('Кэш чатов очищен'); + } + + + void clearMessageCache(int chatId) { + _messageCache.remove(chatId); + _logger.logConnection('Кэш сообщений очищен', data: {'chat_id': chatId}); + } + + + void clearAllCaches() { + _messageCache.clear(); + _contactCache.clear(); + clearChatsCache(); + _logger.logConnection('Все кэши очищены'); + } + + + Future saveToken(String token) async { + _authToken = token; + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('authToken', token); + _logger.logConnection('Токен сохранен'); + } + + + Future hasToken() async { + final prefs = await SharedPreferences.getInstance(); + _authToken = prefs.getString('authToken'); + return _authToken != null; + } + + + Future logout() async { + _logger.logConnection('Выход из системы'); + + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('authToken'); + _authToken = null; + clearAllCaches(); + await disconnect(); + _logger.logConnection('Выход из системы выполнен'); + } catch (e) { + _logger.logError('Ошибка при выходе из системы', error: e); + } + } + + + String _generateDeviceId() { + final timestamp = DateTime.now().millisecondsSinceEpoch; + final random = (timestamp % 1000000).toString().padLeft(6, '0'); + return "$timestamp$random"; + } + + + Map getStatistics() { + return { + 'api_service': { + 'is_initialized': _isInitialized, + 'has_auth_token': _authToken != null, + 'message_cache_size': _messageCache.length, + 'contact_cache_size': _contactCache.length, + 'chats_fetched_in_session': _chatsFetchedInThisSession, + }, + 'connection': _connectionManager.getStatistics(), + }; + } + + + void dispose() { + _logger.logConnection('Освобождение ресурсов ApiServiceSimple'); + _connectionManager.dispose(); + _messageController.close(); + _contactUpdatesController.close(); + } +} diff --git a/lib/api_service_v2.dart b/lib/api_service_v2.dart new file mode 100644 index 0000000..d3d5820 --- /dev/null +++ b/lib/api_service_v2.dart @@ -0,0 +1,1131 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; +import 'package:image_picker/image_picker.dart'; + +import 'connection/connection_manager.dart'; +import 'connection/connection_logger.dart'; +import 'connection/connection_state.dart'; +import 'connection/health_monitor.dart'; +import 'models/message.dart'; +import 'models/contact.dart'; +import 'image_cache_service.dart'; +import 'services/cache_service.dart'; +import 'services/avatar_cache_service.dart'; +import 'services/chat_cache_service.dart'; + + +class ApiServiceV2 { + ApiServiceV2._privateConstructor(); + static final ApiServiceV2 instance = ApiServiceV2._privateConstructor(); + + + final ConnectionManager _connectionManager = ConnectionManager(); + + + final ConnectionLogger _logger = ConnectionLogger(); + + + String? _authToken; + bool _isInitialized = false; + bool _isAuthenticated = false; + + + final Map> _messageCache = {}; + final Map _contactCache = {}; + Map? _lastChatsPayload; + DateTime? _lastChatsAt; + final Duration _chatsCacheTtl = const Duration(seconds: 5); + bool _chatsFetchedInThisSession = false; + + + final Map _presenceData = {}; + + + final StreamController _contactUpdatesController = + StreamController.broadcast(); + final StreamController> _messageController = + StreamController>.broadcast(); + + + Stream> get messages => _messageController.stream; + + + Stream get contactUpdates => _contactUpdatesController.stream; + + + Stream get connectionState => _connectionManager.stateStream; + + + Stream get logs => _connectionManager.logStream; + + + Stream get healthMetrics => + _connectionManager.healthMetricsStream; + + + ConnectionInfo get currentConnectionState => _connectionManager.currentState; + + + bool get isOnline => _connectionManager.isConnected; + + + bool get canSendMessages => _connectionManager.canSendMessages; + + + Future initialize() async { + if (_isInitialized) { + _logger.logConnection('ApiServiceV2 уже инициализирован'); + return; + } + + _logger.logConnection('Инициализация ApiServiceV2'); + + try { + await _connectionManager.initialize(); + _setupMessageHandlers(); + + + _isAuthenticated = false; + + _isInitialized = true; + + _logger.logConnection('ApiServiceV2 успешно инициализирован'); + } catch (e) { + _logger.logError('Ошибка инициализации ApiServiceV2', error: e); + rethrow; + } + } + + + void _setupMessageHandlers() { + _connectionManager.messageStream.listen((message) { + _handleIncomingMessage(message); + }); + } + + + void _handleIncomingMessage(Map message) { + try { + _logger.logMessage('IN', message); + + + if (message['opcode'] == 19 && + message['cmd'] == 1 && + message['payload'] != null) { + _isAuthenticated = true; + _logger.logConnection('Аутентификация успешна'); + } + + + if (message['opcode'] == 128 && message['payload'] != null) { + _handleContactUpdate(message['payload']); + } + + + if (message['opcode'] == 129 && message['payload'] != null) { + _handlePresenceUpdate(message['payload']); + } + + + _messageController.add(message); + } catch (e) { + _logger.logError( + 'Ошибка обработки входящего сообщения', + data: {'message': message, 'error': e.toString()}, + ); + } + } + + + void _handleContactUpdate(Map payload) { + try { + final contact = Contact.fromJson(payload); + _contactCache[contact.id] = contact; + _contactUpdatesController.add(contact); + + _logger.logConnection( + 'Контакт обновлен', + data: {'contact_id': contact.id, 'contact_name': contact.name}, + ); + } catch (e) { + _logger.logError( + 'Ошибка обработки обновления контакта', + data: {'payload': payload, 'error': e.toString()}, + ); + } + } + + + void _handlePresenceUpdate(Map payload) { + try { + _presenceData.addAll(payload); + _logger.logConnection( + 'Presence данные обновлены', + data: {'keys': payload.keys.toList()}, + ); + } catch (e) { + _logger.logError( + 'Ошибка обработки presence данных', + data: {'payload': payload, 'error': e.toString()}, + ); + } + } + + + Future connect() async { + _logger.logConnection('Запрос подключения к серверу'); + + try { + await _connectionManager.connect(authToken: _authToken); + _logger.logConnection('Подключение к серверу успешно'); + } catch (e) { + _logger.logError('Ошибка подключения к серверу', error: e); + rethrow; + } + } + + + Future reconnect() async { + _logger.logConnection('Запрос переподключения'); + + try { + await _connectionManager.connect(authToken: _authToken); + _logger.logConnection('Переподключение успешно'); + } catch (e) { + _logger.logError('Ошибка переподключения', error: e); + rethrow; + } + } + + + Future forceReconnect() async { + _logger.logConnection('Принудительное переподключение'); + + try { + + _isAuthenticated = false; + + await _connectionManager.forceReconnect(); + _logger.logConnection('Принудительное переподключение успешно'); + + + await _performFullAuthenticationSequence(); + } catch (e) { + _logger.logError('Ошибка принудительного переподключения', error: e); + rethrow; + } + } + + + Future _performFullAuthenticationSequence() async { + _logger.logConnection( + 'Выполнение полной последовательности аутентификации', + ); + + try { + + await _waitForConnectionReady(); + + + await _sendAuthenticationToken(); + + + await _waitForAuthenticationConfirmation(); + + + await _sendPingToConfirmSession(); + + + await _requestChatsAndContacts(); + + _logger.logConnection( + 'Полная последовательность аутентификации завершена', + ); + } catch (e) { + _logger.logError('Ошибка в последовательности аутентификации', error: e); + rethrow; + } + } + + + Future _waitForConnectionReady() async { + const maxWaitTime = Duration(seconds: 30); + final startTime = DateTime.now(); + + while (DateTime.now().difference(startTime) < maxWaitTime) { + if (_connectionManager.currentState.isActive) { + + await Future.delayed(const Duration(milliseconds: 500)); + return; + } + await Future.delayed(const Duration(milliseconds: 100)); + } + + throw Exception('Таймаут ожидания готовности соединения'); + } + + + Future _sendAuthenticationToken() async { + if (_authToken == null) { + _logger.logError('Токен аутентификации отсутствует'); + return; + } + + _logger.logConnection('Отправка токена аутентификации'); + + final payload = { + "interactive": true, + "token": _authToken, + "chatsCount": 100, + "userAgent": { + "deviceType": "DESKTOP", + "locale": "ru", + "deviceLocale": "ru", + "osVersion": "Windows", + "deviceName": "Chrome", + "headerUserAgent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "appVersion": "1.0.0", + "screen": "2560x1440 1.0x", + "timezone": "Europe/Moscow", + }, + }; + + _connectionManager.sendMessage(19, payload); + + + await _waitForAuthenticationConfirmation(); + } + + + Future _waitForAuthenticationConfirmation() async { + const maxWaitTime = Duration(seconds: 10); + final startTime = DateTime.now(); + + while (DateTime.now().difference(startTime) < maxWaitTime) { + + if (_connectionManager.currentState.isActive && _isAuthenticated) { + _logger.logConnection('Аутентификация подтверждена'); + return; + } + await Future.delayed(const Duration(milliseconds: 100)); + } + + throw Exception('Таймаут ожидания подтверждения аутентификации'); + } + + + Future _sendPingToConfirmSession() async { + _logger.logConnection('Отправка ping для подтверждения готовности сессии'); + + final payload = {"interactive": true}; + _connectionManager.sendMessage(1, payload); + + + await Future.delayed(const Duration(milliseconds: 500)); + + _logger.logConnection('Ping отправлен, сессия готова'); + } + + + Future _waitForSessionReady() async { + const maxWaitTime = Duration(seconds: 30); + final startTime = DateTime.now(); + + while (DateTime.now().difference(startTime) < maxWaitTime) { + if (canSendMessages && _isAuthenticated) { + _logger.logConnection('Сессия готова для отправки сообщений'); + return; + } + await Future.delayed(const Duration(milliseconds: 100)); + } + + throw Exception('Таймаут ожидания готовности сессии'); + } + + + Future _requestChatsAndContacts() async { + _logger.logConnection('Запрос чатов и контактов'); + + + final chatsPayload = {"chatsCount": 100}; + + _connectionManager.sendMessage(48, chatsPayload); + + + final contactsPayload = {"status": "BLOCKED", "count": 100, "from": 0}; + + _connectionManager.sendMessage(36, contactsPayload); + } + + + Future disconnect() async { + _logger.logConnection('Отключение от сервера'); + + try { + await _connectionManager.disconnect(); + _logger.logConnection('Отключение от сервера успешно'); + } catch (e) { + _logger.logError('Ошибка отключения', error: e); + } + } + + + int _sendMessage(int opcode, Map payload) { + if (!canSendMessages) { + _logger.logConnection( + 'Сообщение не отправлено - соединение не готово', + data: {'opcode': opcode, 'payload': payload}, + ); + return -1; + } + + + if (_requiresAuthentication(opcode) && !_isAuthenticated) { + _logger.logConnection( + 'Сообщение не отправлено - требуется аутентификация', + data: {'opcode': opcode, 'payload': payload}, + ); + return -1; + } + + try { + final seq = _connectionManager.sendMessage(opcode, payload); + _logger.logConnection( + 'Сообщение отправлено', + data: {'opcode': opcode, 'seq': seq, 'payload': payload}, + ); + return seq; + } catch (e) { + _logger.logError( + 'Ошибка отправки сообщения', + data: {'opcode': opcode, 'payload': payload, 'error': e.toString()}, + ); + return -1; + } + } + + + bool _requiresAuthentication(int opcode) { + + const authRequiredOpcodes = { + 19, // Аутентификация + 32, // Получение контактов + 36, // Получение заблокированных контактов + 48, // Получение чатов + 49, // Получение истории сообщений + 64, // Отправка сообщений + 65, // Статус набора + 66, // Удаление сообщений + 67, // Редактирование сообщений + 77, // Управление участниками группы + 78, // Управление участниками группы + 80, // Загрузка файлов + 178, // Отправка реакций + 179, // Удаление реакций + }; + + return authRequiredOpcodes.contains(opcode); + } + + + Future sendHandshake() async { + _logger.logConnection('Отправка handshake'); + + final payload = { + "userAgent": { + "deviceType": "WEB", + "locale": "ru", + "deviceLocale": "ru", + "osVersion": "Windows", + "deviceName": "Chrome", + "headerUserAgent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "appVersion": "25.9.15", + "screen": "1920x1080 1.0x", + "timezone": "Europe/Moscow", + }, + "deviceId": _generateDeviceId(), + }; + + _sendMessage(6, payload); + } + + + void requestOtp(String phoneNumber) { + _logger.logConnection('Запрос OTP', data: {'phone': phoneNumber}); + + final payload = { + "phone": phoneNumber, + "type": "START_AUTH", + "language": "ru", + }; + _sendMessage(17, payload); + } + + + void verifyCode(String token, String code) { + _logger.logConnection( + 'Проверка кода', + data: {'token': token, 'code': code}, + ); + + final payload = { + "token": token, + "verifyCode": code, + "authTokenType": "CHECK_CODE", + }; + _sendMessage(18, payload); + } + + + Future> authenticateWithToken(String token) async { + _logger.logConnection('Аутентификация с токеном'); + + _authToken = token; + await saveToken(token); + + final payload = {"interactive": true, "token": token, "chatsCount": 100}; + + final seq = _sendMessage(19, payload); + + try { + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + _logger.logConnection( + 'Аутентификация успешна', + data: {'seq': seq, 'response_cmd': response['cmd']}, + ); + + return response['payload'] ?? {}; + } catch (e) { + _logger.logError( + 'Ошибка аутентификации', + data: {'token': token, 'error': e.toString()}, + ); + rethrow; + } + } + + + Future> getChatsAndContacts({bool force = false}) async { + _logger.logConnection('Запрос чатов и контактов', data: {'force': force}); + + + if (!force && _lastChatsPayload != null && _lastChatsAt != null) { + if (DateTime.now().difference(_lastChatsAt!) < _chatsCacheTtl) { + _logger.logConnection('Возвращаем данные из локального кэша'); + return _lastChatsPayload!; + } + } + + + if (!force) { + final chatService = ChatCacheService(); + final cachedChats = await chatService.getCachedChats(); + final cachedContacts = await chatService.getCachedContacts(); + + if (cachedChats != null && + cachedContacts != null && + cachedChats.isNotEmpty) { + _logger.logConnection('Возвращаем данные из сервиса кэша'); + final result = { + 'chats': cachedChats, + 'contacts': cachedContacts + .map( + (contact) => { + 'id': contact.id, + 'name': contact.name, + 'firstName': contact.firstName, + 'lastName': contact.lastName, + 'photoBaseUrl': contact.photoBaseUrl, + 'isBlocked': contact.isBlocked, + 'isBlockedByMe': contact.isBlockedByMe, + 'accountStatus': contact.accountStatus, + 'status': contact.status, + }, + ) + .toList(), + 'profile': null, + 'presence': null, + }; + + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + _chatsFetchedInThisSession = true; + + return result; + } + } + + + await _waitForSessionReady(); + + try { + final payload = {"chatsCount": 100}; + final seq = _sendMessage(48, payload); + + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + final List chatListJson = response['payload']?['chats'] ?? []; + + if (chatListJson.isEmpty) { + final result = {'chats': [], 'contacts': [], 'profile': null}; + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + return result; + } + + + final contactIds = {}; + for (var chatJson in chatListJson) { + final participants = + chatJson['participants'] as Map? ?? {}; + contactIds.addAll(participants.keys.map((id) => int.parse(id))); + } + + final contactSeq = _sendMessage(32, {"contactIds": contactIds.toList()}); + + final contactResponse = await messages + .firstWhere((msg) => msg['seq'] == contactSeq) + .timeout(const Duration(seconds: 30)); + + final List contactListJson = + contactResponse['payload']?['contacts'] ?? []; + + final result = { + 'chats': chatListJson, + 'contacts': contactListJson, + 'profile': null, + 'presence': null, + }; + + _lastChatsPayload = result; + _lastChatsAt = DateTime.now(); + _chatsFetchedInThisSession = true; + + + final contacts = contactListJson + .map((json) => Contact.fromJson(json)) + .toList(); + updateContactCache(contacts); + + + final chatService = ChatCacheService(); + await chatService.cacheChats(chatListJson.cast>()); + await chatService.cacheContacts(contacts); + + + _preloadContactAvatars(contacts); + + _logger.logConnection( + 'Чаты и контакты получены', + data: { + 'chats_count': chatListJson.length, + 'contacts_count': contactListJson.length, + }, + ); + + return result; + } catch (e) { + _logger.logError('Ошибка получения чатов и контактов', error: e); + rethrow; + } + } + + + Future> getMessageHistory( + int chatId, { + bool force = false, + }) async { + _logger.logConnection( + 'Запрос истории сообщений', + data: {'chat_id': chatId, 'force': force}, + ); + + + if (!force && _messageCache.containsKey(chatId)) { + _logger.logConnection('История сообщений загружена из локального кэша'); + return _messageCache[chatId]!; + } + + + if (!force) { + final chatService = ChatCacheService(); + final cachedMessages = await chatService.getCachedChatMessages(chatId); + + if (cachedMessages != null && cachedMessages.isNotEmpty) { + _logger.logConnection('История сообщений загружена из сервиса кэша'); + _messageCache[chatId] = cachedMessages; + return cachedMessages; + } + } + + + await _waitForSessionReady(); + + try { + final payload = { + "chatId": chatId, + "from": DateTime.now() + .add(const Duration(days: 1)) + .millisecondsSinceEpoch, + "forward": 0, + "backward": 1000, + "getMessages": true, + }; + + final seq = _sendMessage(49, payload); + + final response = await messages + .firstWhere((msg) => msg['seq'] == seq) + .timeout(const Duration(seconds: 30)); + + if (response['cmd'] == 3) { + final error = response['payload']; + _logger.logError( + 'Ошибка получения истории сообщений', + data: {'chat_id': chatId, 'error': error}, + ); + throw Exception('Ошибка получения истории: ${error['message']}'); + } + + final List messagesJson = response['payload']?['messages'] ?? []; + final messagesList = + messagesJson.map((json) => Message.fromJson(json)).toList() + ..sort((a, b) => a.time.compareTo(b.time)); + + _messageCache[chatId] = messagesList; + + + final chatService = ChatCacheService(); + await chatService.cacheChatMessages(chatId, messagesList); + + + _preloadMessageImages(messagesList); + + _logger.logConnection( + 'История сообщений получена', + data: {'chat_id': chatId, 'messages_count': messagesList.length}, + ); + + return messagesList; + } catch (e) { + _logger.logError( + 'Ошибка получения истории сообщений', + data: {'chat_id': chatId, 'error': e.toString()}, + ); + return []; + } + } + + + void sendMessage(int chatId, String text, {String? replyToMessageId}) { + _logger.logConnection( + 'Отправка сообщения', + data: { + 'chat_id': chatId, + 'text_length': text.length, + 'reply_to': replyToMessageId, + }, + ); + + final int clientMessageId = DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": text, + "cid": clientMessageId, + "elements": [], + "attaches": [], + if (replyToMessageId != null) + "link": {"type": "REPLY", "messageId": replyToMessageId}, + }, + "notify": true, + }; + + clearChatsCache(); + _sendMessage(64, payload); + } + + + Future sendPhotoMessage( + int chatId, { + String? localPath, + String? caption, + int? cidOverride, + int? senderId, + }) async { + _logger.logConnection( + 'Отправка фото', + data: {'chat_id': chatId, 'local_path': localPath, 'caption': caption}, + ); + + try { + XFile? image; + if (localPath != null) { + image = XFile(localPath); + } else { + final picker = ImagePicker(); + image = await picker.pickImage(source: ImageSource.gallery); + if (image == null) return; + } + + + final seq80 = _sendMessage(80, {"count": 1}); + final resp80 = await messages + .firstWhere((m) => m['seq'] == seq80) + .timeout(const Duration(seconds: 30)); + + final String uploadUrl = resp80['payload']['url']; + + + var request = http.MultipartRequest('POST', Uri.parse(uploadUrl)); + request.files.add(await http.MultipartFile.fromPath('file', image.path)); + var streamed = await request.send(); + var httpResp = await http.Response.fromStream(streamed); + + if (httpResp.statusCode != 200) { + throw Exception( + 'Ошибка загрузки фото: ${httpResp.statusCode} ${httpResp.body}', + ); + } + + final uploadJson = jsonDecode(httpResp.body) as Map; + final Map photos = uploadJson['photos'] as Map; + if (photos.isEmpty) throw Exception('Не получен токен фото'); + final String photoToken = (photos.values.first as Map)['token']; + + + final int cid = cidOverride ?? DateTime.now().millisecondsSinceEpoch; + final payload = { + "chatId": chatId, + "message": { + "text": caption?.trim() ?? "", + "cid": cid, + "elements": [], + "attaches": [ + {"_type": "PHOTO", "photoToken": photoToken}, + ], + }, + "notify": true, + }; + + clearChatsCache(); + _sendMessage(64, payload); + + _logger.logConnection( + 'Фото отправлено', + data: {'chat_id': chatId, 'photo_token': photoToken}, + ); + } catch (e) { + _logger.logError( + 'Ошибка отправки фото', + data: {'chat_id': chatId, 'error': e.toString()}, + ); + } + } + + + Future blockContact(int contactId) async { + _logger.logConnection( + 'Блокировка контакта', + data: {'contact_id': contactId}, + ); + _sendMessage(34, {'contactId': contactId, 'action': 'BLOCK'}); + } + + + Future unblockContact(int contactId) async { + _logger.logConnection( + 'Разблокировка контакта', + data: {'contact_id': contactId}, + ); + _sendMessage(34, {'contactId': contactId, 'action': 'UNBLOCK'}); + } + + + void getBlockedContacts() { + _logger.logConnection('Запрос заблокированных контактов'); + _sendMessage(36, {'status': 'BLOCKED', 'count': 100, 'from': 0}); + } + + + void createGroup(String name, List participantIds) { + _logger.logConnection( + 'Создание группы', + data: {'name': name, 'participants': participantIds}, + ); + + final payload = {"name": name, "participantIds": participantIds}; + _sendMessage(48, payload); + } + + + void addGroupMember( + int chatId, + List userIds, { + bool showHistory = true, + }) { + _logger.logConnection( + 'Добавление участника в группу', + data: {'chat_id': chatId, 'user_ids': userIds}, + ); + + final payload = { + "chatId": chatId, + "userIds": userIds, + "showHistory": showHistory, + "operation": "add", + }; + _sendMessage(77, payload); + } + + + void removeGroupMember( + int chatId, + List userIds, { + int cleanMsgPeriod = 0, + }) { + _logger.logConnection( + 'Удаление участника из группы', + data: {'chat_id': chatId, 'user_ids': userIds}, + ); + + final payload = { + "chatId": chatId, + "userIds": userIds, + "operation": "remove", + "cleanMsgPeriod": cleanMsgPeriod, + }; + _sendMessage(77, payload); + } + + + void leaveGroup(int chatId) { + _logger.logConnection('Выход из группы', data: {'chat_id': chatId}); + _sendMessage(58, {"chatId": chatId}); + } + + + void sendReaction(int chatId, String messageId, String emoji) { + _logger.logConnection( + 'Отправка реакции', + data: {'chat_id': chatId, 'message_id': messageId, 'emoji': emoji}, + ); + + final payload = { + "chatId": chatId, + "messageId": messageId, + "reaction": {"reactionType": "EMOJI", "id": emoji}, + }; + _sendMessage(178, payload); + } + + + void removeReaction(int chatId, String messageId) { + _logger.logConnection( + 'Удаление реакции', + data: {'chat_id': chatId, 'message_id': messageId}, + ); + + final payload = {"chatId": chatId, "messageId": messageId}; + _sendMessage(179, payload); + } + + + void sendTyping(int chatId, {String type = "TEXT"}) { + final payload = {"chatId": chatId, "type": type}; + _sendMessage(65, payload); + } + + + DateTime? getLastSeen(int userId) { + final userPresence = _presenceData[userId.toString()]; + if (userPresence != null && userPresence['seen'] != null) { + final seenTimestamp = userPresence['seen'] as int; + return DateTime.fromMillisecondsSinceEpoch(seenTimestamp * 1000); + } + return null; + } + + + void updateContactCache(List contacts) { + _contactCache.clear(); + for (final contact in contacts) { + _contactCache[contact.id] = contact; + } + _logger.logConnection( + 'Кэш контактов обновлен', + data: {'contacts_count': contacts.length}, + ); + } + + + Contact? getCachedContact(int contactId) { + return _contactCache[contactId]; + } + + + void clearChatsCache() { + _lastChatsPayload = null; + _lastChatsAt = null; + _chatsFetchedInThisSession = false; + _logger.logConnection('Кэш чатов очищен'); + } + + + void clearMessageCache(int chatId) { + _messageCache.remove(chatId); + _logger.logConnection('Кэш сообщений очищен', data: {'chat_id': chatId}); + } + + + Future clearAllCaches() async { + _messageCache.clear(); + _contactCache.clear(); + clearChatsCache(); + + + try { + await CacheService().clear(); + await AvatarCacheService().clearAvatarCache(); + await ChatCacheService().clearAllChatCache(); + } catch (e) { + _logger.logError('Ошибка очистки сервисов кеширования', error: e); + } + + _logger.logConnection('Все кэши очищены'); + } + + + Future saveToken(String token) async { + _authToken = token; + final prefs = await SharedPreferences.getInstance(); + + + await prefs.setString('authToken', token); + + _logger.logConnection('Токен сохранен'); + } + + + Future hasToken() async { + final prefs = await SharedPreferences.getInstance(); + _authToken = prefs.getString('authToken'); + return _authToken != null; + } + + + Future logout() async { + _logger.logConnection('Выход из системы'); + + try { + final prefs = await SharedPreferences.getInstance(); + await prefs.remove('authToken'); + _authToken = null; + clearAllCaches(); + await disconnect(); + _logger.logConnection('Выход из системы выполнен'); + } catch (e) { + _logger.logError('Ошибка при выходе из системы', error: e); + } + } + + + Future _preloadContactAvatars(List contacts) async { + try { + final avatarUrls = contacts + .map((contact) => contact.photoBaseUrl) + .where((url) => url != null && url.isNotEmpty) + .toList(); + + if (avatarUrls.isNotEmpty) { + _logger.logConnection( + 'Предзагрузка аватарок контактов', + data: {'count': avatarUrls.length}, + ); + + await ImageCacheService.instance.preloadContactAvatars(avatarUrls); + } + } catch (e) { + _logger.logError('Ошибка предзагрузки аватарок контактов', error: e); + } + } + + + Future _preloadMessageImages(List messages) async { + try { + final imageUrls = []; + + for (final message in messages) { + for (final attach in message.attaches) { + if (attach['_type'] == 'PHOTO' || attach['_type'] == 'SHARE') { + final url = attach['url'] ?? attach['baseUrl']; + if (url is String && url.isNotEmpty) { + imageUrls.add(url); + } + } + } + } + + if (imageUrls.isNotEmpty) { + _logger.logConnection( + 'Предзагрузка изображений из сообщений', + data: {'count': imageUrls.length}, + ); + + await ImageCacheService.instance.preloadContactAvatars(imageUrls); + } + } catch (e) { + _logger.logError( + 'Ошибка предзагрузки изображений из сообщений', + error: e, + ); + } + } + + + String _generateDeviceId() { + final timestamp = DateTime.now().millisecondsSinceEpoch; + final random = (timestamp % 1000000).toString().padLeft(6, '0'); + return "$timestamp$random"; + } + + + Future> getStatistics() async { + final imageCacheStats = await ImageCacheService.instance.getCacheStats(); + final cacheServiceStats = await CacheService().getCacheStats(); + final avatarCacheStats = await AvatarCacheService().getAvatarCacheStats(); + final chatCacheStats = await ChatCacheService().getChatCacheStats(); + + return { + 'api_service': { + 'is_initialized': _isInitialized, + 'has_auth_token': _authToken != null, + 'message_cache_size': _messageCache.length, + 'contact_cache_size': _contactCache.length, + 'chats_fetched_in_session': _chatsFetchedInThisSession, + }, + 'connection': _connectionManager.getStatistics(), + 'cache_service': cacheServiceStats, + 'avatar_cache': avatarCacheStats, + 'chat_cache': chatCacheStats, + 'image_cache': imageCacheStats, + }; + } + + + void dispose() { + _logger.logConnection('Освобождение ресурсов ApiServiceV2'); + _connectionManager.dispose(); + _messageController.close(); + _contactUpdatesController.close(); + } +} diff --git a/lib/cache_management_screen.dart b/lib/cache_management_screen.dart new file mode 100644 index 0000000..b36fa9d --- /dev/null +++ b/lib/cache_management_screen.dart @@ -0,0 +1,431 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/services/cache_service.dart'; +import 'package:gwid/services/avatar_cache_service.dart'; +import 'package:gwid/services/chat_cache_service.dart'; + +class CacheManagementScreen extends StatefulWidget { + const CacheManagementScreen({super.key}); + + @override + State createState() => _CacheManagementScreenState(); +} + +class _CacheManagementScreenState extends State { + Map _cacheStats = {}; + Map _avatarCacheStats = {}; + Map _chatCacheStats = {}; + bool _isLoading = true; + + @override + void initState() { + super.initState(); + _loadCacheStats(); + } + + Future _loadCacheStats() async { + setState(() { + _isLoading = true; + }); + + try { + final cacheService = CacheService(); + final avatarService = AvatarCacheService(); + final chatService = ChatCacheService(); + + + await cacheService.initialize(); + await chatService.initialize(); + await avatarService.initialize(); + + final cacheStats = await cacheService.getCacheStats(); + final avatarStats = await avatarService.getAvatarCacheStats(); + final chatStats = await chatService.getChatCacheStats(); + + if (!mounted) return; + + setState(() { + _cacheStats = cacheStats; + _avatarCacheStats = avatarStats; + _chatCacheStats = chatStats; + _isLoading = false; + }); + } catch (e) { + if (!mounted) return; + + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка загрузки статистики кэша: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + + Future _clearAllCache() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Очистить весь кэш?'), + content: const Text( + 'Это действие удалит все кэшированные данные, включая чаты, сообщения и аватарки. ' + 'Приложение будет работать медленнее до повторной загрузки данных.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + ), + child: const Text('Очистить'), + ), + ], + ), + ); + + if (confirmed == true) { + try { + final cacheService = CacheService(); + final avatarService = AvatarCacheService(); + final chatService = ChatCacheService(); + + + await cacheService.initialize(); + await chatService.initialize(); + await avatarService.initialize(); + + await cacheService.clear(); + await avatarService.clearAvatarCache(); + await chatService.clearAllChatCache(); + + await _loadCacheStats(); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Весь кэш очищен'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка очистки кэша: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + } + + Future _clearAvatarCache() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Очистить кэш аватарок?'), + content: const Text( + 'Это действие удалит все кэшированные аватарки. ' + 'Они будут загружены заново при следующем просмотре.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + child: const Text('Очистить'), + ), + ], + ), + ); + + if (confirmed == true) { + try { + final avatarService = AvatarCacheService(); + + + await avatarService.initialize(); + await avatarService.clearAvatarCache(); + await _loadCacheStats(); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Кэш аватарок очищен'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка очистки кэша аватарок: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + } + + Widget _buildStatCard( + String title, + String value, + IconData icon, + Color color, + ) { + return Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + Icon(icon, color: color, size: 32), + const SizedBox(height: 8), + Text( + title, + style: Theme.of(context).textTheme.titleSmall, + textAlign: TextAlign.center, + ), + const SizedBox(height: 4), + Text( + value, + style: Theme.of(context).textTheme.headlineSmall?.copyWith( + color: color, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } + + Widget _buildCacheSection(String title, Map? data) { + if (data == null || data.isEmpty) { + return const SizedBox.shrink(); + } + + return Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 12), + ...data.entries.map( + (entry) => Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(entry.key), + Text( + entry.value.toString(), + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text("Управление кэшем"), + actions: [ + IconButton( + onPressed: _loadCacheStats, + icon: const Icon(Icons.refresh), + ), + ], + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + + Text( + "Общая статистика", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + const SizedBox(height: 12), + GridView.count( + crossAxisCount: 2, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + childAspectRatio: 1.2, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + children: [ + _buildStatCard( + "Чаты в кэше", + _chatCacheStats['cachedChats']?.toString() ?? "0", + Icons.chat, + colors.primary, + ), + _buildStatCard( + "Контакты в кэше", + _chatCacheStats['cachedContacts']?.toString() ?? "0", + Icons.contacts, + colors.secondary, + ), + _buildStatCard( + "Аватарки в памяти", + _avatarCacheStats['memoryImages']?.toString() ?? "0", + Icons.person, + colors.tertiary, + ), + _buildStatCard( + "Размер кэша", + "${_avatarCacheStats['diskSizeMB'] ?? "0"} МБ", + Icons.storage, + colors.error, + ), + ], + ), + + const SizedBox(height: 24), + + + Text( + "Детальная статистика", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + const SizedBox(height: 12), + + _buildCacheSection("Кэш чатов", _chatCacheStats['cacheStats']), + const SizedBox(height: 12), + _buildCacheSection("Кэш аватарок", _avatarCacheStats), + const SizedBox(height: 12), + _buildCacheSection("Общий кэш", _cacheStats), + const SizedBox(height: 12), + _buildCacheSection("Кэш в памяти", { + 'Записей в памяти': _cacheStats['memoryEntries'] ?? 0, + 'Максимум записей': _cacheStats['maxMemorySize'] ?? 0, + }), + + const SizedBox(height: 32), + + + Text( + "Управление кэшем", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + const SizedBox(height: 12), + + Card( + child: Column( + children: [ + ListTile( + leading: const Icon(Icons.delete_sweep), + title: const Text("Очистить кэш аватарок"), + subtitle: const Text( + "Удалить все кэшированные аватарки", + ), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: _clearAvatarCache, + ), + const Divider(height: 1), + ListTile( + leading: Icon( + Icons.delete_forever, + color: colors.error, + ), + title: Text( + "Очистить весь кэш", + style: TextStyle(color: colors.error), + ), + subtitle: const Text("Удалить все кэшированные данные"), + trailing: Icon( + Icons.chevron_right_rounded, + color: colors.error, + ), + onTap: _clearAllCache, + ), + ], + ), + ), + + const SizedBox(height: 24), + + + Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.info_outline, color: colors.primary), + const SizedBox(width: 8), + Text( + "О кэшировании", + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 12), + const Text( + "Кэширование ускоряет работу приложения, сохраняя часто используемые данные локально. " + "Чаты кэшируются на 1 час, контакты на 6 часов, сообщения на 2 часа, аватарки на 7 дней.", + ), + const SizedBox(height: 8), + const Text( + "Очистка кэша может замедлить работу приложения до повторной загрузки данных.", + style: TextStyle(fontStyle: FontStyle.italic), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/channels_list_screen.dart b/lib/channels_list_screen.dart new file mode 100644 index 0000000..0ef32d3 --- /dev/null +++ b/lib/channels_list_screen.dart @@ -0,0 +1,342 @@ + + +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/channel.dart'; +import 'package:gwid/search_channels_screen.dart'; + +class ChannelsListScreen extends StatefulWidget { + const ChannelsListScreen({super.key}); + + @override + State createState() => _ChannelsListScreenState(); +} + +class _ChannelsListScreenState extends State { + final TextEditingController _searchController = TextEditingController(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + List _channels = []; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + _loadPopularChannels(); + } + + @override + void dispose() { + _searchController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'channels_found') { + setState(() { + _isLoading = false; + _errorMessage = null; + }); + + final payload = message['payload']; + final channelsData = payload['contacts'] as List?; + + if (channelsData != null) { + _channels = channelsData + .map((channelJson) => Channel.fromJson(channelJson)) + .toList(); + } + } + + + if (message['type'] == 'channels_not_found') { + setState(() { + _isLoading = false; + _channels.clear(); + }); + + final payload = message['payload']; + String errorMessage = 'Каналы не найдены'; + + if (payload != null) { + if (payload['localizedMessage'] != null) { + errorMessage = payload['localizedMessage']; + } else if (payload['message'] != null) { + errorMessage = payload['message']; + } + } + + setState(() { + _errorMessage = errorMessage; + }); + } + }); + } + + void _loadPopularChannels() async { + setState(() { + _isLoading = true; + _errorMessage = null; + }); + + try { + + await ApiService.instance.searchChannels('каналы'); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка загрузки каналов: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + void _searchChannels() async { + final searchQuery = _searchController.text.trim(); + + if (searchQuery.isEmpty) { + _loadPopularChannels(); + return; + } + + setState(() { + _isLoading = true; + _errorMessage = null; + }); + + try { + await ApiService.instance.searchChannels(searchQuery); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка поиска каналов: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + void _viewChannel(Channel channel) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChannelDetailsScreen(channel: channel), + ), + ); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Каналы'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + actions: [ + IconButton( + icon: const Icon(Icons.search), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SearchChannelsScreen(), + ), + ); + }, + ), + ], + ), + body: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + child: TextField( + controller: _searchController, + decoration: InputDecoration( + hintText: 'Поиск каналов...', + prefixIcon: const Icon(Icons.search), + suffixIcon: _searchController.text.isNotEmpty + ? IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _searchController.clear(); + _loadPopularChannels(); + }, + ) + : null, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + onSubmitted: (_) => _searchChannels(), + onChanged: (value) { + setState(() {}); + }, + ), + ), + + + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _channels.isEmpty + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.broadcast_on_personal, + size: 64, + color: colors.onSurfaceVariant, + ), + const SizedBox(height: 16), + Text( + _errorMessage ?? 'Каналы не найдены', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 16, + ), + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: _loadPopularChannels, + child: const Text('Обновить'), + ), + ], + ), + ) + : ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 16), + itemCount: _channels.length, + itemBuilder: (context, index) { + final channel = _channels[index]; + return _buildChannelCard(channel); + }, + ), + ), + ], + ), + ); + } + + Widget _buildChannelCard(Channel channel) { + final colors = Theme.of(context).colorScheme; + + return Card( + margin: const EdgeInsets.only(bottom: 12), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: ListTile( + contentPadding: const EdgeInsets.all(16), + leading: CircleAvatar( + radius: 24, + backgroundImage: channel.photoBaseUrl != null + ? NetworkImage(channel.photoBaseUrl!) + : null, + child: channel.photoBaseUrl == null + ? Text( + channel.name.isNotEmpty ? channel.name[0].toUpperCase() : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + ), + ) + : null, + ), + title: Text( + channel.name, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (channel.description?.isNotEmpty == true) ...[ + const SizedBox(height: 4), + Text( + channel.description!, + style: TextStyle(color: colors.onSurfaceVariant, fontSize: 14), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + const SizedBox(height: 8), + Wrap( + spacing: 8, + runSpacing: 4, + children: [ + if (channel.options.contains('BOT')) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.primaryContainer, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + 'Бот', + style: TextStyle( + color: colors.onPrimaryContainer, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + if (channel.options.contains('HAS_WEBAPP')) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.secondaryContainer, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + 'Веб-приложение', + style: TextStyle( + color: colors.onSecondaryContainer, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ], + ), + trailing: Icon( + Icons.arrow_forward_ios, + size: 16, + color: colors.onSurfaceVariant, + ), + onTap: () => _viewChannel(channel), + ), + ); + } +} diff --git a/lib/chat_screen.dart b/lib/chat_screen.dart new file mode 100644 index 0000000..e424296 --- /dev/null +++ b/lib/chat_screen.dart @@ -0,0 +1,4302 @@ +import 'dart:async'; +import 'dart:ui'; +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:gwid/api_service.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/widgets/chat_message_bubble.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:gwid/services/chat_cache_service.dart'; +import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; +import 'package:gwid/screens/group_settings_screen.dart'; +import 'package:flutter_linkify/flutter_linkify.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:video_player/video_player.dart'; + +bool _debugShowExactDate = false; + + +void toggleDebugExactDate() { + _debugShowExactDate = !_debugShowExactDate; + print('Debug режим точной даты: $_debugShowExactDate'); +} + +abstract class ChatItem {} + +class MessageItem extends ChatItem { + final Message message; + final bool isFirstInGroup; + final bool isLastInGroup; + final bool isGrouped; + + MessageItem( + this.message, { + this.isFirstInGroup = false, + this.isLastInGroup = false, + this.isGrouped = false, + }); +} + +class DateSeparatorItem extends ChatItem { + final DateTime date; + DateSeparatorItem(this.date); +} + +class ChatScreen extends StatefulWidget { + final int chatId; + final Contact contact; + final int myId; + final VoidCallback? onChatUpdated; + final bool isGroupChat; + final bool isChannel; + final int? participantCount; + final bool isDesktopMode; + + const ChatScreen({ + super.key, + required this.chatId, + required this.contact, + required this.myId, + this.onChatUpdated, + this.isGroupChat = false, + this.isChannel = false, + this.participantCount, + this.isDesktopMode = false, + }); + + @override + State createState() => _ChatScreenState(); +} + +class _ChatScreenState extends State { + final List _messages = []; + List _chatItems = []; + final Set _animatedMessageIds = {}; + + bool _isLoadingHistory = true; + final TextEditingController _textController = TextEditingController(); + final FocusNode _textFocusNode = FocusNode(); + StreamSubscription? _apiSubscription; + final ItemScrollController _itemScrollController = ItemScrollController(); + final ItemPositionsListener _itemPositionsListener = + ItemPositionsListener.create(); + final ValueNotifier _showScrollToBottomNotifier = ValueNotifier(false); + + + late Contact _currentContact; + + + Message? _replyingToMessage; + + final Map _contactDetailsCache = {}; + + final Map _lastReadMessageIdByParticipant = {}; + + int? _actualMyId; + + bool _isIdReady = false; + + bool _isSearching = false; + final TextEditingController _searchController = TextEditingController(); + final FocusNode _searchFocusNode = FocusNode(); + List _searchResults = []; + int _currentResultIndex = -1; + final Map _messageKeys = {}; + + void _checkContactCache() { + final cachedContact = ApiService.instance.getCachedContact( + widget.contact.id, + ); + if (cachedContact != null) { + _currentContact = cachedContact; + if (mounted) { + setState(() {}); + } + } + } + + void _scrollToBottom() { + _itemScrollController.scrollTo( + index: 0, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOutCubic, + ); + } + + void _loadContactDetails() { + final chatData = ApiService.instance.lastChatsPayload; + if (chatData != null && chatData['contacts'] != null) { + final contactsJson = chatData['contacts'] as List; + for (var contactJson in contactsJson) { + final contact = Contact.fromJson(contactJson); + _contactDetailsCache[contact.id] = contact; + } + print( + 'Кэш контактов для экрана чата заполнен: ${_contactDetailsCache.length} контактов.', + ); + } + } + + @override + void initState() { + super.initState(); + _currentContact = widget.contact; + _initializeChat(); + } + + Future _initializeChat() async { + await _loadCachedContacts(); + + final profileData = ApiService.instance.lastChatsPayload?['profile']; + final contactProfile = profileData?['contact'] as Map?; + + if (contactProfile != null && + contactProfile['id'] != null && + contactProfile['id'] != 0) { + _actualMyId = contactProfile['id']; + print('✅ ID пользователя успешно получен из ApiService: $_actualMyId'); + } else { + _actualMyId = widget.myId; + print('ПРЕДУПРЕЖДЕНИЕ: Используется ID из виджета: $_actualMyId'); + } + + if (mounted) { + setState(() { + _isIdReady = true; + }); + } + + _loadContactDetails(); + _checkContactCache(); + + if (!ApiService.instance.isContactCacheValid()) { + Future.delayed(const Duration(milliseconds: 500), () { + if (mounted) { + ApiService.instance.getBlockedContacts(); + } + }); + } + + ApiService.instance.contactUpdates.listen((contact) { + if (contact.id == _currentContact.id && mounted) { + ApiService.instance.updateCachedContact(contact); + setState(() { + _currentContact = contact; + }); + } + }); + + _itemPositionsListener.itemPositions.addListener(() { + final positions = _itemPositionsListener.itemPositions.value; + if (positions.isNotEmpty) { + _showScrollToBottomNotifier.value = positions.first.index > 0; + } + }); + + _searchController.addListener(() { + if (_searchController.text.isEmpty && _searchResults.isNotEmpty) { + setState(() { + _searchResults.clear(); + _currentResultIndex = -1; + }); + } else if (_searchController.text.isNotEmpty) { + _performSearch(_searchController.text); + } + }); + + _loadHistoryAndListen(); + } + + @override + void didUpdateWidget(ChatScreen oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.contact.id != widget.contact.id) { + _currentContact = widget.contact; + _checkContactCache(); + if (!ApiService.instance.isContactCacheValid()) { + Future.delayed(const Duration(milliseconds: 200), () { + if (mounted) { + ApiService.instance.getBlockedContacts(); + } + }); + } + } + } + + void _loadHistoryAndListen() { + _paginateInitialLoad(); + + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + final opcode = message['opcode']; + final cmd = message['cmd']; + final payload = message['payload']; + + if (payload == null) return; + + final dynamic incomingChatId = payload['chatId']; + final int? chatIdNormalized = incomingChatId is int + ? incomingChatId + : int.tryParse(incomingChatId?.toString() ?? ''); + + if (opcode == 64 && cmd == 1) { + if (chatIdNormalized == widget.chatId) { + final newMessage = Message.fromJson(payload['message']); + print( + 'Получено подтверждение (Opcode 64) для cid: ${newMessage.cid}. Обновляем сообщение.', + ); + _updateMessage( + newMessage, + ); // Обновляем временное сообщение на настоящее + } + } else if (opcode == 128) { + if (chatIdNormalized == widget.chatId) { + final newMessage = Message.fromJson(payload['message']); + final hasSameId = _messages.any((m) => m.id == newMessage.id); + final hasSameCid = + newMessage.cid != null && + _messages.any((m) => m.cid != null && m.cid == newMessage.cid); + if (hasSameId || hasSameCid) { + _updateMessage(newMessage); + } else { + _addMessage(newMessage); + } + } + } else if (opcode == 129) { + if (chatIdNormalized == widget.chatId) { + print('Пользователь печатает в чате $chatIdNormalized'); + } + } else if (opcode == 132) { + if (chatIdNormalized == widget.chatId) { + print('Обновлен статус присутствия для чата $chatIdNormalized'); + + final dynamic contactIdAny = + payload['contactId'] ?? payload['userId']; + if (contactIdAny != null) { + final int? cid = contactIdAny is int + ? contactIdAny + : int.tryParse(contactIdAny.toString()); + if (cid != null) { + final currentTime = DateTime.now().millisecondsSinceEpoch ~/ 1000; + final isOnline = payload['online'] == true; + final userPresence = { + 'seen': currentTime, + 'on': isOnline ? 'ON' : 'OFF', + }; + ApiService.instance.updatePresenceData({ + cid.toString(): userPresence, + }); + + print( + 'Обновлен presence для пользователя $cid: online=$isOnline, seen=$currentTime', + ); + + if (mounted) { + setState(() {}); + } + } + } + } + } else if (opcode == 67) { + if (chatIdNormalized == widget.chatId) { + final editedMessage = Message.fromJson(payload['message']); + _updateMessage(editedMessage); + } + } else if (opcode == 66) { + if (chatIdNormalized == widget.chatId) { + final deletedMessageIds = List.from( + payload['messageIds'] ?? [], + ); + _removeMessages(deletedMessageIds); + } + } else if (opcode == 178) { + if (chatIdNormalized == widget.chatId) { + final messageId = payload['messageId'] as String?; + final reactionInfo = payload['reactionInfo'] as Map?; + if (messageId != null && reactionInfo != null) { + _updateMessageReaction(messageId, reactionInfo); + } + } + } else if (opcode == 179) { + if (chatIdNormalized == widget.chatId) { + final messageId = payload['messageId'] as String?; + final reactionInfo = payload['reactionInfo'] as Map?; + if (messageId != null) { + _updateMessageReaction(messageId, reactionInfo ?? {}); + } + } + } + }); + } + + static const int _pageSize = 50; + bool _isLoadingMore = false; + bool _hasMore = true; + int? _oldestLoadedTime; + + bool get _optimize => context.read().optimizeChats; + bool get _ultraOptimize => context.read().ultraOptimizeChats; + bool get _anyOptimize => _optimize || _ultraOptimize; + + int get _optPage => _ultraOptimize ? 10 : (_optimize ? 50 : _pageSize); + + Future _paginateInitialLoad() async { + setState(() => _isLoadingHistory = true); + + final chatCacheService = ChatCacheService(); + List? cachedMessages = await chatCacheService + .getCachedChatMessages(widget.chatId); + + bool hasCache = cachedMessages != null && cachedMessages.isNotEmpty; + if (hasCache) { + print("✅ Показываем ${cachedMessages.length} сообщений из кэша..."); + if (!mounted) return; + _messages.clear(); + _messages.addAll(cachedMessages); + _buildChatItems(); + setState(() { + _isLoadingHistory = false; + }); + } + + try { + print("📡 Запрашиваем актуальные сообщения с сервера..."); + final allMessages = await ApiService.instance.getMessageHistory( + widget.chatId, + force: true, + ); + if (!mounted) return; + print("✅ Получено ${allMessages.length} сообщений с сервера."); + + + final Set senderIds = {}; + for (final message in allMessages) { + senderIds.add(message.senderId); + + if (message.isReply && message.link?['message']?['sender'] != null) { + final replySenderId = message.link!['message']!['sender']; + if (replySenderId is int) { + senderIds.add(replySenderId); + } + } + } + senderIds.remove(0); // Удаляем системный ID, если он есть + + + final idsToFetch = senderIds + .where((id) => !_contactDetailsCache.containsKey(id)) + .toList(); + if (idsToFetch.isNotEmpty) { + final newContacts = await ApiService.instance.fetchContactsByIds( + idsToFetch, + ); + + for (final contact in newContacts) { + _contactDetailsCache[contact.id] = contact; + } + } + + await chatCacheService.cacheChatMessages(widget.chatId, allMessages); + + final page = _anyOptimize ? _optPage : _pageSize; + final slice = allMessages.length > page + ? allMessages.sublist(allMessages.length - page) + : allMessages; + + setState(() { + _messages.clear(); + _messages.addAll(slice); + _oldestLoadedTime = _messages.isNotEmpty ? _messages.first.time : null; + _hasMore = allMessages.length > _messages.length; + _buildChatItems(); + _isLoadingHistory = false; + }); + } catch (e) { + print("❌ Ошибка при загрузке с сервера: $e"); + if (mounted) { + setState(() { + _isLoadingHistory = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось обновить историю чата')), + ); + } + } + + final theme = context.read(); + if (theme.debugReadOnEnter && + _messages.isNotEmpty && + widget.onChatUpdated != null) { + final lastMessageId = _messages.last.id; + ApiService.instance.markMessageAsRead(widget.chatId, lastMessageId); + } + } + + Future _loadMore() async { + if (_isLoadingMore || !_hasMore) return; + _isLoadingMore = true; + setState(() {}); + + final all = await ApiService.instance.getMessageHistory( + widget.chatId, + force: false, + ); + if (!mounted) return; + + final page = _anyOptimize ? _optPage : _pageSize; + + final older = all + .where((m) => m.time < (_oldestLoadedTime ?? 1 << 62)) + .toList(); + + if (older.isEmpty) { + _hasMore = false; + _isLoadingMore = false; + setState(() {}); + return; + } + + older.sort((a, b) => a.time.compareTo(b.time)); + final take = older.length > page + ? older.sublist(older.length - page) + : older; + + _messages.insertAll(0, take); + _oldestLoadedTime = _messages.first.time; + _hasMore = all.length > _messages.length; + + _buildChatItems(); + _isLoadingMore = false; + setState(() {}); + + + } + + bool _isSameDay(DateTime date1, DateTime date2) { + return date1.year == date2.year && + date1.month == date2.month && + date1.day == date2.day; + } + + bool _isMessageGrouped(Message currentMessage, Message? previousMessage) { + if (previousMessage == null) return false; + + final currentTime = DateTime.fromMillisecondsSinceEpoch( + currentMessage.time, + ); + final previousTime = DateTime.fromMillisecondsSinceEpoch( + previousMessage.time, + ); + + final timeDifference = currentTime.difference(previousTime).inMinutes; + + return currentMessage.senderId == previousMessage.senderId && + timeDifference <= 5; + } + + void _buildChatItems() { + final List items = []; + final source = _messages; + + for (int i = 0; i < source.length; i++) { + final currentMessage = source[i]; + final previousMessage = (i > 0) ? source[i - 1] : null; + + final currentDate = DateTime.fromMillisecondsSinceEpoch( + currentMessage.time, + ).toLocal(); + final previousDate = previousMessage != null + ? DateTime.fromMillisecondsSinceEpoch(previousMessage.time).toLocal() + : null; + + if (previousMessage == null || !_isSameDay(currentDate, previousDate!)) { + items.add(DateSeparatorItem(currentDate)); + } + + final isGrouped = _isMessageGrouped(currentMessage, previousMessage); + + print( + 'DEBUG GROUPING: Message ${i}: sender=${currentMessage.senderId}, time=${currentMessage.time}', + ); + if (previousMessage != null) { + print( + 'DEBUG GROUPING: Previous: sender=${previousMessage.senderId}, time=${previousMessage.time}', + ); + print('DEBUG GROUPING: isGrouped=$isGrouped'); + } + + + final isFirstInGroup = + previousMessage == null || + !_isMessageGrouped(currentMessage, previousMessage); + + + final isLastInGroup = + i == source.length - 1 || + !_isMessageGrouped(source[i + 1], currentMessage); + + print( + 'DEBUG GROUPING: isFirstInGroup=$isFirstInGroup, isLastInGroup=$isLastInGroup', + ); + + items.add( + MessageItem( + currentMessage, + isFirstInGroup: isFirstInGroup, + isLastInGroup: isLastInGroup, + isGrouped: isGrouped, + ), + ); + } + _chatItems = items; + } + + void _addMessage(Message message) { + if (_messages.any((m) => m.id == message.id)) { + print('Сообщение ${message.id} уже существует, пропускаем добавление'); + return; + } + + ApiService.instance.clearCacheForChat(widget.chatId); + + final lastMessage = _messages.isNotEmpty ? _messages.last : null; + _messages.add(message); + + final currentDate = DateTime.fromMillisecondsSinceEpoch( + message.time, + ).toLocal(); + final lastDate = lastMessage != null + ? DateTime.fromMillisecondsSinceEpoch(lastMessage.time).toLocal() + : null; + + if (lastMessage == null || !_isSameDay(currentDate, lastDate!)) { + final separator = DateSeparatorItem(currentDate); + _chatItems.add(separator); + } + + final lastMessageItem = + _chatItems.isNotEmpty && _chatItems.last is MessageItem + ? _chatItems.last as MessageItem + : null; + + final isGrouped = _isMessageGrouped(message, lastMessageItem?.message); + final isFirstInGroup = lastMessageItem == null || !isGrouped; + final isLastInGroup = true; + + final messageItem = MessageItem( + message, + isFirstInGroup: isFirstInGroup, + isLastInGroup: isLastInGroup, + isGrouped: isGrouped, + ); + _chatItems.add(messageItem); + + final theme = context.read(); + if (theme.messageTransition == TransitionOption.slide) { + print('Добавлено новое сообщение для анимации Slide+: ${message.id}'); + } else { + _animatedMessageIds.add(message.id); + } + + if (mounted) { + setState(() {}); + } + } + + void _updateMessageReaction( + String messageId, + Map reactionInfo, + ) { + final messageIndex = _messages.indexWhere((m) => m.id == messageId); + if (messageIndex != -1) { + final message = _messages[messageIndex]; + final updatedMessage = message.copyWith(reactionInfo: reactionInfo); + _messages[messageIndex] = updatedMessage; + + _buildChatItems(); + + print('Обновлена реакция для сообщения $messageId: $reactionInfo'); + + if (mounted) { + setState(() {}); + } + } + } + + void _updateReactionOptimistically(String messageId, String emoji) { + final messageIndex = _messages.indexWhere((m) => m.id == messageId); + if (messageIndex != -1) { + final message = _messages[messageIndex]; + final currentReactionInfo = message.reactionInfo ?? {}; + final currentCounters = List>.from( + currentReactionInfo['counters'] ?? [], + ); + + final existingCounterIndex = currentCounters.indexWhere( + (counter) => counter['reaction'] == emoji, + ); + + if (existingCounterIndex != -1) { + currentCounters[existingCounterIndex]['count'] = + (currentCounters[existingCounterIndex]['count'] as int) + 1; + } else { + currentCounters.add({'reaction': emoji, 'count': 1}); + } + + final updatedReactionInfo = { + ...currentReactionInfo, + 'counters': currentCounters, + 'yourReaction': emoji, + 'totalCount': currentCounters.fold( + 0, + (sum, counter) => sum + (counter['count'] as int), + ), + }; + + final updatedMessage = message.copyWith( + reactionInfo: updatedReactionInfo, + ); + _messages[messageIndex] = updatedMessage; + + _buildChatItems(); + + print('Оптимистично добавлена реакция $emoji к сообщению $messageId'); + + if (mounted) { + setState(() {}); + } + } + } + + void _removeReactionOptimistically(String messageId) { + final messageIndex = _messages.indexWhere((m) => m.id == messageId); + if (messageIndex != -1) { + final message = _messages[messageIndex]; + final currentReactionInfo = message.reactionInfo ?? {}; + final yourReaction = currentReactionInfo['yourReaction'] as String?; + + if (yourReaction != null) { + final currentCounters = List>.from( + currentReactionInfo['counters'] ?? [], + ); + + final counterIndex = currentCounters.indexWhere( + (counter) => counter['reaction'] == yourReaction, + ); + + if (counterIndex != -1) { + final currentCount = currentCounters[counterIndex]['count'] as int; + if (currentCount > 1) { + currentCounters[counterIndex]['count'] = currentCount - 1; + } else { + currentCounters.removeAt(counterIndex); + } + } + + final updatedReactionInfo = { + ...currentReactionInfo, + 'counters': currentCounters, + 'yourReaction': null, + 'totalCount': currentCounters.fold( + 0, + (sum, counter) => sum + (counter['count'] as int), + ), + }; + + final updatedMessage = message.copyWith( + reactionInfo: updatedReactionInfo, + ); + _messages[messageIndex] = updatedMessage; + + _buildChatItems(); + + print('Оптимистично удалена реакция с сообщения $messageId'); + + if (mounted) { + setState(() {}); + } + } + } + } + + void _updateMessage(Message updatedMessage) { + final index = _messages.indexWhere((m) => m.id == updatedMessage.id); + if (index != -1) { + print( + 'Обновляем сообщение ${updatedMessage.id}: "${_messages[index].text}" -> "${updatedMessage.text}"', + ); + + final oldMessage = _messages[index]; + final finalMessage = updatedMessage.link != null + ? updatedMessage + : updatedMessage.copyWith(link: oldMessage.link); + + print('Обновляем link: ${oldMessage.link} -> ${finalMessage.link}'); + + _messages[index] = finalMessage; + ApiService.instance.clearCacheForChat(widget.chatId); + _buildChatItems(); + setState(() {}); + } else { + print( + 'Сообщение ${updatedMessage.id} не найдено для обновления. Запрашиваем свежую историю...', + ); + ApiService.instance + .getMessageHistory(widget.chatId, force: true) + .then((fresh) { + if (!mounted) return; + _messages + ..clear() + ..addAll(fresh); + _buildChatItems(); + setState(() {}); + }) + .catchError((_) {}); + } + } + + void _removeMessages(List messageIds) { + print('Удаляем сообщения: $messageIds'); + final removedCount = _messages.length; + _messages.removeWhere((message) => messageIds.contains(message.id)); + final actuallyRemoved = removedCount - _messages.length; + print('Удалено сообщений: $actuallyRemoved'); + + if (actuallyRemoved > 0) { + ApiService.instance.clearCacheForChat(widget.chatId); + _buildChatItems(); + setState(() {}); + } + } + + void _sendMessage() { + final text = _textController.text.trim(); + if (text.isNotEmpty) { + final theme = context.read(); + final isBlocked = _currentContact.isBlockedByMe && !theme.blockBypass; + + if (isBlocked) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text( + 'Нельзя отправить сообщение заблокированному пользователю', + ), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + return; + } + + final int tempCid = DateTime.now().millisecondsSinceEpoch; + final tempMessageJson = { + 'id': 'local_$tempCid', // Временный "локальный" ID + 'text': text, + 'time': tempCid, + 'sender': _actualMyId!, + 'cid': tempCid, // Уникальный ID клиента + 'type': 'USER', + 'attaches': [], // Оптимистично без вложений (для текста) + 'link': _replyingToMessage != null + ? { + 'type': 'REPLY', + 'messageId': _replyingToMessage!.id, + 'message': { + 'sender': _replyingToMessage!.senderId, + 'id': _replyingToMessage!.id, + 'time': _replyingToMessage!.time, + 'text': _replyingToMessage!.text, + 'type': 'USER', + 'cid': _replyingToMessage!.cid, + 'attaches': _replyingToMessage!.attaches, + }, + 'chatId': 0, // Не используется, но нужно для парсинга + } + : null, + }; + + final tempMessage = Message.fromJson(tempMessageJson); + _addMessage(tempMessage); + print( + 'Создано временное сообщение с link: ${tempMessage.link} и cid: $tempCid', + ); + + ApiService.instance.sendMessage( + widget.chatId, + text, + replyToMessageId: _replyingToMessage?.id, + cid: tempCid, // Передаем тот же CID в API + ); + + if (theme.debugReadOnAction && _messages.isNotEmpty) { + final lastMessageId = _messages.last.id; + ApiService.instance.markMessageAsRead(widget.chatId, lastMessageId); + } + + _textController.clear(); + + setState(() { + _replyingToMessage = null; + }); + + widget.onChatUpdated?.call(); + } + } + + void _testSlideAnimation() { + print('=== ТЕСТ SLIDE+ АНИМАЦИИ ==='); + + final myMessage = Message( + id: 'test_my_${DateTime.now().millisecondsSinceEpoch}', + text: 'Тест моё сообщение (должно выехать справа)', + time: DateTime.now().millisecondsSinceEpoch, + senderId: _actualMyId!, + ); + _addMessage(myMessage); + + Future.delayed(const Duration(seconds: 1), () { + final otherMessage = Message( + id: 'test_other_${DateTime.now().millisecondsSinceEpoch}', + text: 'Тест сообщение собеседника (должно выехать слева)', + time: DateTime.now().millisecondsSinceEpoch, + senderId: widget.contact.id, + ); + _addMessage(otherMessage); + }); + } + + void _editMessage(Message message) { + if (!message.canEdit(_actualMyId!)) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + message.isDeleted + ? 'Удаленное сообщение нельзя редактировать' + : message.attaches.isNotEmpty + ? 'Сообщения с вложениями нельзя редактировать' + : 'Сообщение можно редактировать только в течение 24 часов', + ), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + return; + } + + showDialog( + context: context, + builder: (context) => _EditMessageDialog( + initialText: message.text, + onSave: (newText) async { + if (newText.trim().isNotEmpty && newText != message.text) { + final optimistic = message.copyWith( + text: newText.trim(), + status: 'EDITED', + updateTime: DateTime.now().millisecondsSinceEpoch, + ); + _updateMessage(optimistic); + + try { + await ApiService.instance.editMessage( + widget.chatId, + message.id, + newText.trim(), + ); + + widget.onChatUpdated?.call(); + } catch (e) { + print('Ошибка при редактировании сообщения: $e'); + _updateMessage(message); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка редактирования: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + }, + ), + ); + } + + void _replyToMessage(Message message) { + setState(() { + _replyingToMessage = message; + }); + _textController.clear(); + FocusScope.of(context).requestFocus(FocusNode()); + } + + void _cancelReply() { + setState(() { + _replyingToMessage = null; + }); + } + + void _showBlockDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Заблокировать контакт'), + content: Text( + 'Вы уверены, что хотите заблокировать ${_currentContact.name}?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () async { + Navigator.of(context).pop(); + try { + await ApiService.instance.blockContact(widget.contact.id); + if (mounted) { + setState(() { + _currentContact = Contact( + id: _currentContact.id, + name: _currentContact.name, + firstName: _currentContact.firstName, + lastName: _currentContact.lastName, + description: _currentContact.description, + photoBaseUrl: _currentContact.photoBaseUrl, + isBlocked: _currentContact.isBlocked, + isBlockedByMe: true, + accountStatus: _currentContact.accountStatus, + status: _currentContact.status, + ); + }); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Контакт заблокирован'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка блокировки: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Заблокировать'), + ), + ], + ), + ); + } + + void _showUnblockDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Разблокировать контакт'), + content: Text( + 'Вы уверены, что хотите разблокировать ${_currentContact.name}?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () async { + Navigator.of(context).pop(); + try { + await ApiService.instance.unblockContact(widget.contact.id); + if (mounted) { + setState(() { + _currentContact = Contact( + id: _currentContact.id, + name: _currentContact.name, + firstName: _currentContact.firstName, + lastName: _currentContact.lastName, + description: _currentContact.description, + photoBaseUrl: _currentContact.photoBaseUrl, + isBlocked: _currentContact.isBlocked, + isBlockedByMe: false, + accountStatus: _currentContact.accountStatus, + status: _currentContact.status, + ); + }); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Контакт разблокирован'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка разблокировки: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.green, + foregroundColor: Colors.white, + ), + child: const Text('Разблокировать'), + ), + ], + ), + ); + } + + void _showWallpaperDialog() { + showDialog( + context: context, + builder: (context) => _WallpaperSelectionDialog( + chatId: widget.chatId, + onImageSelected: (imagePath) async { + Navigator.of(context).pop(); + await _setChatWallpaper(imagePath); + }, + onRemoveWallpaper: () async { + Navigator.of(context).pop(); + await _removeChatWallpaper(); + }, + ), + ); + } + + void _showClearHistoryDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Очистить историю чата'), + content: Text( + 'Вы уверены, что хотите очистить историю чата с ${_currentContact.name}? Это действие нельзя отменить.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () async { + Navigator.of(context).pop(); + try { + await ApiService.instance.clearChatHistory(widget.chatId); + if (mounted) { + setState(() { + _messages.clear(); + _chatItems.clear(); + }); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('История чата очищена'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка очистки истории: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Очистить'), + ), + ], + ), + ); + } + + void _showDeleteChatDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Удалить чат'), + content: Text( + 'Вы уверены, что хотите удалить чат с ${_currentContact.name}? Это действие нельзя отменить.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () async { + Navigator.of(context).pop(); + try { + print('Имитация удаления чата ID: ${widget.chatId}'); + await Future.delayed(const Duration(milliseconds: 500)); + + if (mounted) { + + Navigator.of(context).pop(); + + widget.onChatUpdated?.call(); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Чат удален'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка удаления чата: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Удалить'), + ), + ], + ), + ); + } + + void _toggleNotifications() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Уведомления для этого чата выключены')), + ); + setState(() {}); + } + + void _showLeaveGroupDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Выйти из группы'), + content: Text( + 'Вы уверены, что хотите выйти из группы "${widget.contact.name}"?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () { + Navigator.of(context).pop(); // Закрываем диалог подтверждения + try { + + ApiService.instance.leaveGroup(widget.chatId); + + if (mounted) { + + Navigator.of(context).pop(); + + widget.onChatUpdated?.call(); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Вы вышли из группы'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при выходе из группы: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Выйти'), + ), + ], + ), + ); + } + + Map? _getCurrentGroupChat() { + final chatData = ApiService.instance.lastChatsPayload; + if (chatData == null || chatData['chats'] == null) return null; + + final chats = chatData['chats'] as List; + try { + return chats.firstWhere( + (chat) => chat['id'] == widget.chatId, + orElse: () => null, + ); + } catch (e) { + return null; + } + } + + Future _setChatWallpaper(String imagePath) async { + try { + final theme = context.read(); + await theme.setChatSpecificWallpaper(widget.chatId, imagePath); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Обои для чата установлены'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка установки обоев: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + + Future _removeChatWallpaper() async { + try { + final theme = context.read(); + await theme.setChatSpecificWallpaper(widget.chatId, null); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Обои для чата удалены'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка удаления обоев: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + + Future _loadCachedContacts() async { + final cachedContacts = await ChatCacheService().getCachedContacts(); + if (cachedContacts != null && cachedContacts.isNotEmpty) { + for (final contact in cachedContacts) { + _contactDetailsCache[contact.id] = contact; + } + print( + '✅ Кэш контактов для экрана чата заполнен из ChatCacheService: ${_contactDetailsCache.length} контактов.', + ); + } + } + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + + return Scaffold( + extendBodyBehindAppBar: theme.useGlassPanels, + appBar: _buildAppBar(), + body: Stack( + children: [ + Positioned.fill(child: _buildChatWallpaper(theme)), + if (!_isIdReady || _isLoadingHistory) + const Center(child: CircularProgressIndicator()) + else + ScrollablePositionedList.builder( + itemScrollController: _itemScrollController, + itemPositionsListener: _itemPositionsListener, + reverse: true, + padding: EdgeInsets.fromLTRB( + 8.0, + 90.0, + 8.0, + widget.isChannel ? 30.0 : 110.0, + ), + itemCount: _chatItems.length, + itemBuilder: (context, index) { + final mappedIndex = _chatItems.length - 1 - index; + final item = _chatItems[mappedIndex]; + final isLastVisual = index == _chatItems.length - 1; + + if (isLastVisual && _hasMore && !_isLoadingMore) { + _loadMore(); + } + + if (item is MessageItem) { + final message = item.message; + final key = _messageKeys.putIfAbsent( + message.id, + () => GlobalKey(), + ); + final bool isHighlighted = + _isSearching && + _searchResults.isNotEmpty && + _currentResultIndex != -1 && + message.id == _searchResults[_currentResultIndex].id; + + final isControlMessage = message.attaches.any( + (a) => a['_type'] == 'CONTROL', + ); + if (isControlMessage) { + return _ControlMessageChip( + message: message, + contacts: _contactDetailsCache, + myId: _actualMyId ?? widget.myId, + ); + } + + final bool isMe = item.message.senderId == _actualMyId; + + MessageReadStatus? readStatus; + if (isMe) { + final messageId = item.message.id; + if (messageId.startsWith('local_')) { + + + readStatus = MessageReadStatus.sending; + } else { + + + readStatus = MessageReadStatus.sent; + + + + + + + + + + + } + } + + if (message.isForwarded) { + final originalSenderId = + message.link?['message']?['sender'] as int?; + if (originalSenderId != null) {} + } + String? senderName; + if (widget.isGroupChat && !isMe) { + bool shouldShowName = true; + if (mappedIndex > 0) { + final previousItem = _chatItems[mappedIndex - 1]; + if (previousItem is MessageItem) { + final previousMessage = previousItem.message; + if (previousMessage.senderId == message.senderId) { + final timeDifferenceInMinutes = + (message.time - previousMessage.time) / + (1000 * 60); + if (timeDifferenceInMinutes < 5) { + shouldShowName = false; + } + } + } + } + if (shouldShowName) { + final senderContact = + _contactDetailsCache[message.senderId]; + senderName = + senderContact?.name ?? 'Участник ${message.senderId}'; + } + } + final hasPhoto = item.message.attaches.any( + (a) => a['_type'] == 'PHOTO', + ); + final isNew = !_animatedMessageIds.contains(item.message.id); + final deferImageLoading = + hasPhoto && + isNew && + !_anyOptimize && + !context.read().animatePhotoMessages; + + final bubble = ChatMessageBubble( + key: key, + message: item.message, + isMe: isMe, + readStatus: readStatus, + deferImageLoading: deferImageLoading, + myUserId: _actualMyId, + chatId: widget.chatId, + onReply: () => _replyToMessage(item.message), + onEdit: isMe ? () => _editMessage(item.message) : null, + canEditMessage: isMe + ? item.message.canEdit(_actualMyId!) + : null, + onDeleteForMe: isMe + ? () async { + await ApiService.instance.deleteMessage( + widget.chatId, + item.message.id, + forMe: true, + ); + widget.onChatUpdated?.call(); + } + : null, + onDeleteForAll: isMe + ? () async { + await ApiService.instance.deleteMessage( + widget.chatId, + item.message.id, + forMe: false, + ); + widget.onChatUpdated?.call(); + } + : null, + onReaction: (emoji) { + _updateReactionOptimistically(item.message.id, emoji); + ApiService.instance.sendReaction( + widget.chatId, + item.message.id, + emoji, + ); + widget.onChatUpdated?.call(); + }, + onRemoveReaction: () { + _removeReactionOptimistically(item.message.id); + ApiService.instance.removeReaction( + widget.chatId, + item.message.id, + ); + widget.onChatUpdated?.call(); + }, + isGroupChat: widget.isGroupChat, + isChannel: widget.isChannel, + senderName: senderName, + contactDetailsCache: _contactDetailsCache, + onReplyTap: _scrollToMessage, + useAutoReplyColor: context + .read() + .useAutoReplyColor, + customReplyColor: context + .read() + .customReplyColor, + isFirstInGroup: item.isFirstInGroup, + isLastInGroup: item.isLastInGroup, + isGrouped: item.isGrouped, + avatarVerticalOffset: + -8.0, // Смещение аватарки вверх на 8px + ); + + Widget finalMessageWidget = bubble as Widget; + + if (isHighlighted) { + return Container( + margin: const EdgeInsets.symmetric(vertical: 2), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.5), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Theme.of(context).colorScheme.primary, + width: 1.5, + ), + ), + child: finalMessageWidget, + ); + } + + return finalMessageWidget; + } else if (item is DateSeparatorItem) { + return _DateSeparatorChip(date: item.date); + } + if (isLastVisual && _isLoadingMore) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 12), + child: Center(child: CircularProgressIndicator()), + ); + } + return const SizedBox.shrink(); + }, + ), + Positioned( + right: 16, + bottom: 120, + child: ValueListenableBuilder( + valueListenable: _showScrollToBottomNotifier, + builder: (context, showButton, child) { + return showButton + ? Opacity( + opacity: 0.85, + child: FloatingActionButton( + mini: true, + onPressed: _scrollToBottom, + child: const Icon(Icons.arrow_downward_rounded), + ), + ) + : const SizedBox.shrink(); + }, + ), + ), + Positioned(left: 0, right: 0, bottom: 0, child: _buildTextInput()), + ], + ), + ); + } + + void _showContactProfile() { + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, + barrierColor: Colors.transparent, + pageBuilder: (context, animation, secondaryAnimation) { + return ContactProfileDialog( + contact: widget.contact, + isChannel: widget.isChannel, + ); + }, + transitionsBuilder: (context, animation, secondaryAnimation, child) { + return FadeTransition(opacity: animation, child: child); + }, + transitionDuration: const Duration(milliseconds: 300), + ), + ); + } + + AppBar _buildAppBar() { + final theme = context.watch(); + + if (_isSearching) { + return AppBar( + leading: IconButton( + icon: const Icon(Icons.close), + onPressed: _stopSearch, + tooltip: 'Закрыть поиск', + ), + title: TextField( + controller: _searchController, + focusNode: _searchFocusNode, + autofocus: true, + decoration: const InputDecoration( + hintText: 'Поиск по сообщениям...', + border: InputBorder.none, + ), + style: TextStyle(color: Theme.of(context).colorScheme.onSurface), + ), + actions: [ + if (_searchResults.isNotEmpty) + Center( + child: Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Text( + '${_currentResultIndex + 1} из ${_searchResults.length}', + ), + ), + ), + IconButton( + icon: const Icon(Icons.keyboard_arrow_up), + onPressed: _searchResults.isNotEmpty ? _navigateToNextResult : null, + tooltip: 'Следующий (более старый) результат', + ), + IconButton( + icon: const Icon(Icons.keyboard_arrow_down), + onPressed: _searchResults.isNotEmpty + ? _navigateToPreviousResult + : null, + tooltip: 'Предыдущий (более новый) результат', + ), + ], + ); + } + + return AppBar( + titleSpacing: 4.0, + backgroundColor: theme.useGlassPanels ? Colors.transparent : null, + elevation: theme.useGlassPanels ? 0 : null, + flexibleSpace: theme.useGlassPanels + ? ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.topBarBlur, + sigmaY: theme.topBarBlur, + ), + child: Container( + color: Theme.of( + context, + ).colorScheme.surface.withOpacity(theme.topBarOpacity), + ), + ), + ) + : null, + leading: widget.isDesktopMode + ? null // В десктопном режиме нет кнопки "Назад" + : IconButton( + + icon: const Icon(Icons.arrow_back), + onPressed: () => Navigator.of(context).pop(), + ), + actions: [ + if (widget.isGroupChat) + IconButton( + onPressed: () { + if (_actualMyId == null) return; + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => GroupSettingsScreen( + chatId: widget.chatId, + initialContact: _currentContact, + myId: _actualMyId!, + onChatUpdated: widget.onChatUpdated, + ), + ), + ); + }, + icon: const Icon(Icons.settings), + tooltip: 'Настройки группы', + ), + PopupMenuButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + onSelected: (value) { + if (value == 'search') { + _startSearch(); + } else if (value == 'block') { + _showBlockDialog(); + } else if (value == 'unblock') { + _showUnblockDialog(); + } else if (value == 'wallpaper') { + _showWallpaperDialog(); + } else if (value == 'toggle_notifications') { + _toggleNotifications(); + } else if (value == 'clear_history') { + _showClearHistoryDialog(); + } else if (value == 'delete_chat') { + _showDeleteChatDialog(); + } else if (value == 'leave_group' || value == 'leave_channel') { + _showLeaveGroupDialog(); + } + }, + itemBuilder: (context) { + bool amIAdmin = false; + if (widget.isGroupChat) { + final currentChat = _getCurrentGroupChat(); + if (currentChat != null) { + final admins = currentChat['admins'] as List? ?? []; + if (_actualMyId != null) { + amIAdmin = admins.contains(_actualMyId); + } + } + } + final bool canDeleteChat = !widget.isGroupChat || amIAdmin; + + return [ + const PopupMenuItem( + value: 'search', + child: Row( + children: [ + Icon(Icons.search), + SizedBox(width: 8), + Text('Поиск'), + ], + ), + ), + const PopupMenuItem( + value: 'wallpaper', + child: Row( + children: [ + Icon(Icons.wallpaper), + SizedBox(width: 8), + Text('Обои'), + ], + ), + ), + if (!widget.isGroupChat && !widget.isChannel) ...[ + if (_currentContact.isBlockedByMe) + const PopupMenuItem( + value: 'unblock', + child: Row( + children: [ + Icon(Icons.person_add, color: Colors.green), + SizedBox(width: 8), + Text('Разблокировать'), + ], + ), + ) + else + const PopupMenuItem( + value: 'block', + child: Row( + children: [ + Icon(Icons.block, color: Colors.red), + SizedBox(width: 8), + Text('Заблокировать'), + ], + ), + ), + ], + PopupMenuItem( + value: 'toggle_notifications', + child: Row( + children: [ + Icon(Icons.notifications), + SizedBox(width: 8), + Text('Выкл. уведомления'), + ], + ), + ), + const PopupMenuDivider(), + if (!widget.isChannel) + const PopupMenuItem( + value: 'clear_history', + child: Row( + children: [ + Icon(Icons.clear_all, color: Colors.orange), + SizedBox(width: 8), + Text('Очистить историю'), + ], + ), + ), + + if (widget.isGroupChat) + const PopupMenuItem( + value: 'leave_group', + child: Row( + children: [ + Icon(Icons.exit_to_app, color: Colors.red), + SizedBox(width: 8), + Text('Выйти из группы'), + ], + ), + ), + + if (widget.isChannel) + const PopupMenuItem( + value: 'leave_channel', // Новое значение + child: Row( + children: [ + Icon(Icons.exit_to_app, color: Colors.red), + SizedBox(width: 8), + Text('Покинуть канал'), // Другой текст + ], + ), + ), + + if (canDeleteChat && !widget.isChannel) + const PopupMenuItem( + value: 'delete_chat', + child: Row( + children: [ + Icon(Icons.delete_forever, color: Colors.red), + SizedBox(width: 8), + Text('Удалить чат'), + ], + ), + ), + ]; + }, + ), + ], + title: Row( + children: [ + GestureDetector( + onTap: _showContactProfile, + child: Hero( + tag: 'contact_avatar_${widget.contact.id}', + child: CircleAvatar( + radius: 18, + backgroundImage: widget.contact.photoBaseUrl != null + ? NetworkImage(widget.contact.photoBaseUrl!) + : null, + child: widget.contact.photoBaseUrl == null + ? Text( + widget.contact.name.isNotEmpty + ? widget.contact.name[0].toUpperCase() + : '?', + ) + : null, + ), + ), + ), + const SizedBox(width: 8), + Expanded( + child: GestureDetector( + onTap: _showContactProfile, + behavior: HitTestBehavior.opaque, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Text( + widget.contact.name, + overflow: TextOverflow.ellipsis, + ), + ), + if (context + .watch() + .debugShowMessageCount) ...[ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: theme.ultraOptimizeChats + ? Colors.red.withOpacity(0.7) + : theme.optimizeChats + ? Colors.orange.withOpacity(0.7) + : Colors.blue.withOpacity(0.7), + borderRadius: BorderRadius.circular(10), + ), + child: Text( + '${_messages.length}${theme.ultraOptimizeChats + ? 'U' + : theme.optimizeChats + ? 'O' + : ''}', + style: const TextStyle( + fontSize: 11, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ], + ), + + const SizedBox(height: 2), + if (widget.isGroupChat || + widget.isChannel) // Объединенное условие + Text( + widget.isChannel + ? "${widget.participantCount ?? 0} подписчиков" + : "${widget.participantCount ?? 0} участников", + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ) + else + + _ContactPresenceSubtitle( + chatId: widget.chatId, + userId: widget.contact.id, + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildChatWallpaper(ThemeProvider provider) { + if (provider.hasChatSpecificWallpaper(widget.chatId)) { + final chatSpecificImagePath = provider.getChatSpecificWallpaper( + widget.chatId, + ); + if (chatSpecificImagePath != null) { + return Image.file( + File(chatSpecificImagePath), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ); + } + } + + if (!provider.useCustomChatWallpaper) { + return Container(color: Theme.of(context).colorScheme.surface); + } + switch (provider.chatWallpaperType) { + case ChatWallpaperType.solid: + return Container(color: provider.chatWallpaperColor1); + case ChatWallpaperType.gradient: + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + provider.chatWallpaperColor1, + provider.chatWallpaperColor2, + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + ); + case ChatWallpaperType.image: + final Widget image; + if (provider.chatWallpaperImagePath != null) { + image = Stack( + fit: StackFit.expand, + children: [ + Image.file( + File(provider.chatWallpaperImagePath!), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), + if (provider.chatWallpaperImageBlur > 0) + BackdropFilter( + filter: ImageFilter.blur( + sigmaX: provider.chatWallpaperImageBlur, + sigmaY: provider.chatWallpaperImageBlur, + ), + child: Container(color: Colors.transparent), + ), + ], + ); + } else { + image = Container( + color: Theme.of(context).colorScheme.surfaceContainerHighest, + ); + } + return Stack( + fit: StackFit.expand, + children: [ + image, + if (provider.chatWallpaperBlur) + BackdropFilter( + filter: ImageFilter.blur( + sigmaX: provider.chatWallpaperBlurSigma, + sigmaY: provider.chatWallpaperBlurSigma, + ), + child: Container(color: Colors.black.withOpacity(0.0)), + ), + ], + ); + case ChatWallpaperType.video: + + if (Platform.isWindows) { + return Container( + color: Theme.of(context).colorScheme.surface, + child: Center( + child: Text( + 'Видео-обои не поддерживаются\nна Windows', + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.6), + ), + textAlign: TextAlign.center, + ), + ), + ); + } + if (provider.chatWallpaperVideoPath != null && + provider.chatWallpaperVideoPath!.isNotEmpty) { + return _VideoWallpaperBackground( + videoPath: provider.chatWallpaperVideoPath!, + ); + } else { + return Container(color: Theme.of(context).colorScheme.surface); + } + } + } + + Widget _buildTextInput() { + if (widget.isChannel) { + return const SizedBox.shrink(); // Возвращаем пустой виджет для каналов + } + final theme = context.watch(); + final isBlocked = _currentContact.isBlockedByMe && !theme.blockBypass; + + if (_currentContact.name.toLowerCase() == 'max') { + return const SizedBox.shrink(); + } + + if (theme.useGlassPanels) { + return ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.bottomBarBlur, + sigmaY: theme.bottomBarBlur, + ), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 12.0, + ), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.surface.withOpacity(theme.bottomBarOpacity), + border: Border( + top: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5, + ), + ), + ), + child: SafeArea( + top: false, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_replyingToMessage != null) ...[ + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of( + context, + ).colorScheme.primary.withOpacity(0.3), + ), + ), + child: Row( + children: [ + Icon( + Icons.reply, + size: 16, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Ответ на сообщение', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of( + context, + ).colorScheme.primary, + ), + ), + const SizedBox(height: 2), + Text( + _replyingToMessage!.text.isNotEmpty + ? _replyingToMessage!.text + : 'Фото', + style: TextStyle( + fontSize: 13, + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.8), + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + IconButton( + onPressed: _cancelReply, + icon: const Icon(Icons.close), + iconSize: 18, + color: Theme.of(context).colorScheme.primary, + ), + ], + ), + ), + ], + if (isBlocked) ...[ + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.errorContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of( + context, + ).colorScheme.error.withOpacity(0.5), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.block, + color: Theme.of(context).colorScheme.error, + size: 20, + ), + const SizedBox(width: 8), + Text( + 'Пользователь заблокирован', + style: TextStyle( + color: Theme.of(context).colorScheme.error, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + const SizedBox(height: 4), + Text( + 'Разблокируйте пользователя для отправки сообщений', + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.onErrorContainer, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + Text( + 'или включите block_bypass', + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.onErrorContainer, + fontSize: 12, + fontStyle: FontStyle.italic, + ), + ), + ], + ), + ), + ], + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + + child: Focus( + focusNode: + _textFocusNode, // 2. focusNode теперь здесь + onKeyEvent: (node, event) { + + if (event is KeyDownEvent) { + if (event.logicalKey == + LogicalKeyboardKey.enter) { + + final bool isShiftPressed = + HardwareKeyboard.instance.logicalKeysPressed + .contains( + LogicalKeyboardKey.shiftLeft, + ) || + HardwareKeyboard.instance.logicalKeysPressed + .contains( + LogicalKeyboardKey.shiftRight, + ); + + if (!isShiftPressed) { + + _sendMessage(); + return KeyEventResult.handled; + } + } + } + return KeyEventResult.ignored; + }, + + child: TextField( + controller: _textController, + + enabled: !isBlocked, + keyboardType: TextInputType.multiline, + textInputAction: TextInputAction.newline, + minLines: 1, + maxLines: 5, + decoration: InputDecoration( + hintText: isBlocked + ? 'Пользователь заблокирован' + : 'Сообщение...', + filled: true, + fillColor: isBlocked + ? Theme.of(context) + .colorScheme + .surfaceContainerHighest + .withOpacity(0.3) + : Theme.of(context) + .colorScheme + .surfaceContainerHighest + .withOpacity(0.5), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 10.0, + ), + ), + + onChanged: isBlocked + ? null + : (v) { + if (v.isNotEmpty) { + _scheduleTypingPing(); + } + }, + ), + ), + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.photo_library_outlined), + tooltip: isBlocked + ? 'Пользователь заблокирован' + : 'Отправить фото', + onPressed: isBlocked + ? null + : () async { + final result = await _pickPhotosFlow(context); + if (result != null && result.paths.isNotEmpty) { + await ApiService.instance.sendPhotoMessages( + widget.chatId, + localPaths: result.paths, + caption: result.caption, + senderId: _actualMyId, + ); + } + }, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Theme.of(context).colorScheme.primary, + ), + if (context.watch().messageTransition == + TransitionOption.slide) + IconButton( + icon: const Icon(Icons.animation), + onPressed: isBlocked ? null : _testSlideAnimation, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Colors.orange, + tooltip: isBlocked + ? 'Пользователь заблокирован' + : 'Тест Slide+ анимации', + ), + IconButton( + icon: const Icon(Icons.send), + onPressed: isBlocked ? null : _sendMessage, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Theme.of(context).colorScheme.primary, + ), + ], + ), + ], + ), + ), + ), + ), + ); + } else { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, // Обычный цвет фона + border: Border( + top: BorderSide(color: Theme.of(context).dividerColor, width: 0.5), + ), + ), + child: SafeArea( + top: false, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_replyingToMessage != null) ...[ + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of( + context, + ).colorScheme.primary.withOpacity(0.3), + ), + ), + child: Row( + children: [ + Icon( + Icons.reply, + size: 16, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Ответ на сообщение', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: Theme.of(context).colorScheme.primary, + ), + ), + const SizedBox(height: 2), + Text( + _replyingToMessage!.text.isNotEmpty + ? _replyingToMessage!.text + : 'Фото', + style: TextStyle( + fontSize: 13, + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.8), + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + IconButton( + onPressed: _cancelReply, + icon: const Icon(Icons.close), + iconSize: 18, + color: Theme.of(context).colorScheme.primary, + ), + ], + ), + ), + ], + if (isBlocked) ...[ + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(bottom: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.errorContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of( + context, + ).colorScheme.error.withOpacity(0.5), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.block, + color: Theme.of(context).colorScheme.error, + size: 20, + ), + const SizedBox(width: 8), + Text( + 'Пользователь заблокирован', + style: TextStyle( + color: Theme.of(context).colorScheme.error, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + const SizedBox(height: 4), + Text( + 'Разблокируйте пользователя для отправки сообщений', + style: TextStyle( + color: Theme.of(context).colorScheme.onErrorContainer, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + Text( + 'или включите block_bypass', + style: TextStyle( + color: Theme.of(context).colorScheme.onErrorContainer, + fontSize: 12, + fontStyle: FontStyle.italic, + ), + ), + ], + ), + ), + ], + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Expanded( + child: TextField( + controller: _textController, + enabled: !isBlocked, + keyboardType: TextInputType.multiline, + textInputAction: TextInputAction.newline, + minLines: 1, + maxLines: 5, + decoration: InputDecoration( + hintText: isBlocked + ? 'Пользователь заблокирован' + : 'Сообщение...', + filled: true, + fillColor: isBlocked + ? Theme.of(context) + .colorScheme + .surfaceContainerHighest + .withOpacity(0.3) + : Theme.of(context) + .colorScheme + .surfaceContainerHighest + .withOpacity(0.5), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30), + borderSide: BorderSide.none, + ), + contentPadding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 10.0, + ), + ), + onChanged: isBlocked + ? null + : (v) { + if (v.isNotEmpty) { + _scheduleTypingPing(); + } + }, + ), + ), + const SizedBox(width: 8), + IconButton( + icon: const Icon(Icons.photo_library_outlined), + tooltip: isBlocked + ? 'Пользователь заблокирован' + : 'Отправить фото', + onPressed: isBlocked + ? null + : () async { + final result = await _pickPhotosFlow(context); + if (result != null && result.paths.isNotEmpty) { + await ApiService.instance.sendPhotoMessages( + widget.chatId, + localPaths: result.paths, + caption: result.caption, + senderId: _actualMyId, + ); + } + }, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Theme.of(context).colorScheme.primary, + ), + if (context.watch().messageTransition == + TransitionOption.slide) + IconButton( + icon: const Icon(Icons.animation), + onPressed: isBlocked ? null : _testSlideAnimation, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Colors.orange, + tooltip: isBlocked + ? 'Пользователь заблокирован' + : 'Тест Slide+ анимации', + ), + IconButton( + icon: const Icon(Icons.send), + onPressed: isBlocked ? null : _sendMessage, + color: isBlocked + ? Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.3) + : Theme.of(context).colorScheme.primary, + ), + ], + ), + ], + ), + ), + ); + } + } + + Timer? _typingTimer; + DateTime _lastTypingSentAt = DateTime.fromMillisecondsSinceEpoch(0); + void _scheduleTypingPing() { + final now = DateTime.now(); + if (now.difference(_lastTypingSentAt) >= const Duration(seconds: 9)) { + ApiService.instance.sendTyping(widget.chatId, type: "TEXT"); + _lastTypingSentAt = now; + } + _typingTimer?.cancel(); + _typingTimer = Timer(const Duration(seconds: 9), () { + if (!mounted) return; + if (_textController.text.isNotEmpty) { + ApiService.instance.sendTyping(widget.chatId, type: "TEXT"); + _lastTypingSentAt = DateTime.now(); + _scheduleTypingPing(); + } + }); + } + + @override + void dispose() { + _typingTimer?.cancel(); + _apiSubscription?.cancel(); + _textController.dispose(); + _textFocusNode.dispose(); + _searchController.dispose(); + _searchFocusNode.dispose(); + super.dispose(); + } + + void _startSearch() { + setState(() { + _isSearching = true; + }); + WidgetsBinding.instance.addPostFrameCallback((_) { + _searchFocusNode.requestFocus(); + }); + } + + void _stopSearch() { + setState(() { + _isSearching = false; + _searchResults.clear(); + _currentResultIndex = -1; + _searchController.clear(); + _messageKeys.clear(); + }); + } + + void _performSearch(String query) { + if (query.isEmpty) { + if (_searchResults.isNotEmpty) { + setState(() { + _searchResults.clear(); + _currentResultIndex = -1; + }); + } + return; + } + final results = _messages + .where((msg) => msg.text.toLowerCase().contains(query.toLowerCase())) + .toList(); + + setState(() { + _searchResults = results.reversed.toList(); + _currentResultIndex = _searchResults.isNotEmpty ? 0 : -1; + }); + + if (_currentResultIndex != -1) { + _scrollToResult(); + } + } + + void _navigateToNextResult() { + if (_searchResults.isEmpty) return; + setState(() { + _currentResultIndex = (_currentResultIndex + 1) % _searchResults.length; + }); + _scrollToResult(); + } + + void _navigateToPreviousResult() { + if (_searchResults.isEmpty) return; + setState(() { + _currentResultIndex = + (_currentResultIndex - 1 + _searchResults.length) % + _searchResults.length; + }); + _scrollToResult(); + } + + void _scrollToResult() { + if (_currentResultIndex == -1) return; + + final targetMessage = _searchResults[_currentResultIndex]; + + final itemIndex = _chatItems.indexWhere( + (item) => item is MessageItem && item.message.id == targetMessage.id, + ); + + if (itemIndex != -1) { + final viewIndex = _chatItems.length - 1 - itemIndex; + + _itemScrollController.scrollTo( + index: viewIndex, + duration: const Duration(milliseconds: 400), + curve: Curves.easeInOut, + alignment: 0.5, + ); + } + } + + void _scrollToMessage(String messageId) { + final itemIndex = _chatItems.indexWhere( + (item) => item is MessageItem && item.message.id == messageId, + ); + + if (itemIndex != -1) { + final viewIndex = _chatItems.length - 1 - itemIndex; + + _itemScrollController.scrollTo( + index: viewIndex, + duration: const Duration(milliseconds: 400), + curve: Curves.easeInOut, + alignment: 0.5, + ); + } else { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Исходное сообщение не найдено (возможно, оно в старой истории)', + ), + ), + ); + } + } + } +} + +class _EditMessageDialog extends StatefulWidget { + final String initialText; + final Function(String) onSave; + + const _EditMessageDialog({required this.initialText, required this.onSave}); + + @override + State<_EditMessageDialog> createState() => _EditMessageDialogState(); +} + +class _EditMessageDialogState extends State<_EditMessageDialog> { + late TextEditingController _controller; + + @override + void initState() { + super.initState(); + _controller = TextEditingController(text: widget.initialText); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Редактировать сообщение'), + content: TextField( + controller: _controller, + maxLines: 3, + decoration: const InputDecoration( + hintText: 'Введите текст сообщения', + border: OutlineInputBorder(), + ), + autofocus: true, + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () { + widget.onSave(_controller.text); + Navigator.pop(context); + }, + child: const Text('Сохранить'), + ), + ], + ); + } +} + +class _ContactPresenceSubtitle extends StatefulWidget { + final int chatId; + final int userId; + const _ContactPresenceSubtitle({required this.chatId, required this.userId}); + @override + State<_ContactPresenceSubtitle> createState() => + _ContactPresenceSubtitleState(); +} + +class _ContactPresenceSubtitleState extends State<_ContactPresenceSubtitle> { + String _status = 'был(а) недавно'; + Timer? _typingDecayTimer; + bool _isOnline = false; + DateTime? _lastSeen; + StreamSubscription? _sub; + + @override + void initState() { + super.initState(); + + final lastSeen = ApiService.instance.getLastSeen(widget.userId); + if (lastSeen != null) { + _lastSeen = lastSeen; + _status = _formatLastSeen(_lastSeen); + } + + _sub = ApiService.instance.messages.listen((msg) { + try { + final int? opcode = msg['opcode']; + final payload = msg['payload']; + if (opcode == 129) { + final dynamic incomingChatId = payload['chatId']; + final int? cid = incomingChatId is int + ? incomingChatId + : int.tryParse(incomingChatId?.toString() ?? ''); + if (cid == widget.chatId) { + setState(() => _status = 'печатает…'); + _typingDecayTimer?.cancel(); + _typingDecayTimer = Timer(const Duration(seconds: 11), () { + if (!mounted) return; + if (_status == 'печатает…') { + setState(() { + if (_isOnline) { + _status = 'онлайн'; + } else { + _status = _formatLastSeen(_lastSeen); + } + }); + } + }); + } + } else if (opcode == 132) { + final dynamic incomingChatId = payload['chatId']; + final int? cid = incomingChatId is int + ? incomingChatId + : int.tryParse(incomingChatId?.toString() ?? ''); + if (cid == widget.chatId) { + final bool isOnline = payload['online'] == true; + if (!mounted) return; + _isOnline = isOnline; + setState(() { + if (_status != 'печатает…') { + if (_isOnline) { + _status = 'онлайн'; + } else { + final updatedLastSeen = ApiService.instance.getLastSeen( + widget.userId, + ); + if (updatedLastSeen != null) { + _lastSeen = updatedLastSeen; + } else { + _lastSeen = DateTime.now(); + } + _status = _formatLastSeen(_lastSeen); + } + } + }); + } + } + } catch (_) {} + }); + } + + String _formatLastSeen(DateTime? lastSeen) { + if (lastSeen == null) return 'был(а) недавно'; + + final now = DateTime.now(); + final difference = now.difference(lastSeen); + + String timeAgo; + if (difference.inMinutes < 1) { + timeAgo = 'только что'; + } else if (difference.inMinutes < 60) { + timeAgo = '${difference.inMinutes} мин. назад'; + } else if (difference.inHours < 24) { + timeAgo = '${difference.inHours} ч. назад'; + } else if (difference.inDays < 7) { + timeAgo = '${difference.inDays} дн. назад'; + } else { + final day = lastSeen.day.toString().padLeft(2, '0'); + final month = lastSeen.month.toString().padLeft(2, '0'); + timeAgo = '$day.$month.${lastSeen.year}'; + } + + if (_debugShowExactDate) { + final formatter = DateFormat('dd.MM.yyyy HH:mm:ss'); + return '$timeAgo (${formatter.format(lastSeen)})'; + } + + return timeAgo; + } + + @override + void dispose() { + _typingDecayTimer?.cancel(); + _sub?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final style = Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ); + + String displayStatus; + if (_status == 'печатает…' || _status == 'онлайн') { + displayStatus = _status; + } else if (_isOnline) { + displayStatus = 'онлайн'; + } else { + displayStatus = _formatLastSeen(_lastSeen); + } + + return GestureDetector( + onLongPress: () { + toggleDebugExactDate(); + if (mounted) { + setState(() {}); + } + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + displayStatus, + style: style, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + if (_debugShowExactDate) ...[ + const SizedBox(width: 4), + Icon( + Icons.bug_report, + size: 12, + color: Theme.of(context).colorScheme.primary, + ), + ], + ], + ), + ); + } +} + +class _PhotosToSend { + final List paths; + final String caption; + const _PhotosToSend({required this.paths, required this.caption}); +} + +class _SendPhotosDialog extends StatefulWidget { + const _SendPhotosDialog(); + @override + State<_SendPhotosDialog> createState() => _SendPhotosDialogState(); +} + +class _SendPhotosDialogState extends State<_SendPhotosDialog> { + final TextEditingController _caption = TextEditingController(); + final List _pickedPaths = []; + final List _previews = []; + + @override + void dispose() { + _caption.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Отправить фото'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + controller: _caption, + maxLines: 2, + decoration: const InputDecoration( + hintText: 'Подпись (необязательно)', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 12), + FilledButton.icon( + onPressed: () async { + try { + final imgs = await ImagePicker().pickMultiImage( + imageQuality: 100, + ); + if (imgs.isNotEmpty) { + _pickedPaths + ..clear() + ..addAll(imgs.map((e) => e.path)); + _previews + ..clear() + ..addAll(imgs.map((e) => FileImage(File(e.path)))); + setState(() {}); + } + } catch (_) {} + }, + icon: const Icon(Icons.photo_library), + label: Text( + _pickedPaths.isEmpty + ? 'Выбрать фото' + : 'Выбрано: ${_pickedPaths.length}', + ), + ), + if (_pickedPaths.isNotEmpty) ...[ + const SizedBox(height: 12), + SizedBox( + width: 320, + height: 220, + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 6, + crossAxisSpacing: 6, + ), + itemCount: _previews.length, + itemBuilder: (ctx, i) { + final preview = _previews[i]; + return Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(8), + child: preview != null + ? Image(image: preview, fit: BoxFit.cover) + : const ColoredBox(color: Colors.black12), + ), + Positioned( + right: 4, + top: 4, + child: GestureDetector( + onTap: () { + setState(() { + _previews.removeAt(i); + _pickedPaths.removeAt(i); + }); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.all(2), + child: const Icon( + Icons.close, + size: 16, + color: Colors.white, + ), + ), + ), + ), + ], + ); + }, + ), + ), + ], + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Отмена'), + ), + TextButton( + onPressed: _pickedPaths.isEmpty + ? null + : () { + Navigator.pop( + context, + _PhotosToSend(paths: _pickedPaths, caption: _caption.text), + ); + }, + child: const Text('Отправить'), + ), + ], + ); + } +} + +Future<_PhotosToSend?> _pickPhotosFlow(BuildContext context) async { + final isMobile = + Theme.of(context).platform == TargetPlatform.android || + Theme.of(context).platform == TargetPlatform.iOS; + if (isMobile) { + return await showModalBottomSheet<_PhotosToSend>( + context: context, + isScrollControlled: true, + builder: (ctx) => Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(ctx).viewInsets.bottom), + child: const _SendPhotosBottomSheet(), + ), + ); + } else { + return await showDialog<_PhotosToSend>( + context: context, + builder: (ctx) => const _SendPhotosDialog(), + ); + } +} + +class _SendPhotosBottomSheet extends StatefulWidget { + const _SendPhotosBottomSheet(); + @override + State<_SendPhotosBottomSheet> createState() => _SendPhotosBottomSheetState(); +} + +class _SendPhotosBottomSheetState extends State<_SendPhotosBottomSheet> { + final TextEditingController _caption = TextEditingController(); + final List _pickedPaths = []; + final List _previews = []; + + @override + void dispose() { + _caption.dispose(); + super.dispose(); + } + + Future _pickMore() async { + try { + final imgs = await ImagePicker().pickMultiImage(imageQuality: 100); + if (imgs.isNotEmpty) { + _pickedPaths.addAll(imgs.map((e) => e.path)); + _previews.addAll(imgs.map((e) => FileImage(File(e.path)))); + setState(() {}); + } + } catch (_) {} + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Text( + 'Выбор фото', + style: TextStyle(fontWeight: FontWeight.bold), + ), + const Spacer(), + IconButton( + onPressed: _pickMore, + icon: const Icon(Icons.add_photo_alternate_outlined), + ), + ], + ), + if (_pickedPaths.isNotEmpty) + SizedBox( + height: 140, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemBuilder: (c, i) { + final preview = _previews[i]; + return Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: preview != null + ? Image( + image: preview, + width: 140, + height: 140, + fit: BoxFit.cover, + ) + : const ColoredBox(color: Colors.black12), + ), + Positioned( + right: 6, + top: 6, + child: GestureDetector( + onTap: () { + setState(() { + _previews.removeAt(i); + _pickedPaths.removeAt(i); + }); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(12), + ), + padding: const EdgeInsets.all(2), + child: const Icon( + Icons.close, + size: 16, + color: Colors.white, + ), + ), + ), + ), + ], + ); + }, + separatorBuilder: (_, __) => const SizedBox(width: 8), + itemCount: _previews.length, + ), + ) + else + OutlinedButton.icon( + onPressed: _pickMore, + icon: const Icon(Icons.photo_library_outlined), + label: const Text('Выбрать фото'), + ), + const SizedBox(height: 12), + TextField( + controller: _caption, + maxLines: 2, + decoration: const InputDecoration( + hintText: 'Подпись (необязательно)', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 12), + Row( + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Отмена'), + ), + const Spacer(), + FilledButton( + onPressed: _pickedPaths.isEmpty + ? null + : () { + Navigator.pop( + context, + _PhotosToSend( + paths: _pickedPaths, + caption: _caption.text, + ), + ); + }, + child: const Text('Отправить'), + ), + ], + ), + ], + ), + ), + ); + } +} + +class _DateSeparatorChip extends StatelessWidget { + final DateTime date; + const _DateSeparatorChip({required this.date}); + + String _formatDate(DateTime localDate) { + final now = DateTime.now(); + if (localDate.year == now.year && + localDate.month == now.month && + localDate.day == now.day) { + return 'Сегодня'; + } + final yesterday = now.subtract(const Duration(days: 1)); + if (localDate.year == yesterday.year && + localDate.month == yesterday.month && + localDate.day == yesterday.day) { + return 'Вчера'; + } + return DateFormat.yMMMMd('ru').format(localDate); + } + + @override + Widget build(BuildContext context) { + return Center( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + margin: const EdgeInsets.symmetric(vertical: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.5), + borderRadius: BorderRadius.circular(20), + ), + child: Text( + _formatDate(date), + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + } +} + +extension BrightnessExtension on Brightness { + bool get isDark => this == Brightness.dark; +} + +class GroupProfileDraggableDialog extends StatelessWidget { + final Contact contact; + + const GroupProfileDraggableDialog({required this.contact}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return DraggableScrollableSheet( + initialChildSize: 0.7, + minChildSize: 0.3, + maxChildSize: 1.0, + builder: (context, scrollController) { + return Container( + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + ), + child: Column( + children: [ + + Container( + margin: const EdgeInsets.only(top: 8), + width: 40, + height: 4, + decoration: BoxDecoration( + color: colors.onSurfaceVariant.withOpacity(0.3), + borderRadius: BorderRadius.circular(2), + ), + ), + + + Padding( + padding: const EdgeInsets.all(20), + child: Hero( + tag: 'contact_avatar_${contact.id}', + child: CircleAvatar( + radius: 60, + backgroundImage: contact.photoBaseUrl != null + ? NetworkImage(contact.photoBaseUrl!) + : null, + child: contact.photoBaseUrl == null + ? Text( + contact.name.isNotEmpty + ? contact.name[0].toUpperCase() + : '?', + style: const TextStyle(fontSize: 32), + ) + : null, + ), + ), + ), + + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + Expanded( + child: Text( + contact.name, + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ), + IconButton( + icon: Icon(Icons.settings, color: colors.primary), + onPressed: () async { + + + final myId = 0; // This should be passed or retrieved + + Navigator.of(context).pop(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => GroupSettingsScreen( + chatId: -contact + .id, // Convert back to positive chatId + initialContact: contact, + myId: myId, + ), + ), + ); + }, + tooltip: 'Настройки группы', + ), + ], + ), + ), + + const SizedBox(height: 20), + + + Expanded( + child: ListView( + controller: scrollController, + padding: const EdgeInsets.symmetric(horizontal: 20), + children: [ + + if (contact.description != null && + contact.description!.isNotEmpty) + Text( + contact.description!, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + ], + ), + ), + ], + ), + ); + }, + ); + } +} + +class ContactProfileDialog extends StatelessWidget { + final Contact contact; + final bool isChannel; + const ContactProfileDialog({required this.contact, this.isChannel = false}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final String nickname = contact.name; + final String description = contact.description ?? ''; + + final theme = context.watch(); + + return Dialog.fullscreen( + backgroundColor: Colors.transparent, + child: Stack( + children: [ + Positioned.fill( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => Navigator.of(context).pop(), + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.profileDialogBlur, + sigmaY: theme.profileDialogBlur, + ), + child: Container( + color: Colors.black.withOpacity(theme.profileDialogOpacity), + ), + ), + ), + ), + + Column( + children: [ + Expanded( + child: Center( + child: TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: const Duration(milliseconds: 300), + curve: Curves.easeOutCubic, + builder: (context, value, child) { + return Opacity( + opacity: value, + child: Transform.translate( + offset: Offset( + 0, + -0.3 * + (1.0 - value) * + MediaQuery.of(context).size.height * + 0.15, + ), + child: child, + ), + ); + }, + child: Hero( + tag: 'contact_avatar_${contact.id}', + child: CircleAvatar( + radius: 96, + backgroundImage: contact.photoBaseUrl != null + ? NetworkImage(contact.photoBaseUrl!) + : null, + child: contact.photoBaseUrl == null + ? Text( + contact.name.isNotEmpty + ? contact.name[0].toUpperCase() + : '?', + style: const TextStyle(fontSize: 48), + ) + : null, + ), + ), + ), + ), + ), + + Builder( + builder: (context) { + final panel = Container( + width: double.infinity, + padding: const EdgeInsets.fromLTRB(20, 16, 20, 24), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(24), + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 16, + offset: const Offset(0, -8), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + nickname, + style: const TextStyle( + fontSize: 22, + fontWeight: FontWeight.w700, + ), + overflow: TextOverflow.ellipsis, + ), + ), + IconButton( + icon: const Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + const SizedBox(height: 8), + if (description.isNotEmpty) + Linkify( + text: description, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + linkStyle: TextStyle( + color: colors.primary, // Цвет ссылки + fontSize: 14, + decoration: TextDecoration.underline, + ), + onOpen: (link) async { + final uri = Uri.parse(link.url); + if (await canLaunchUrl(uri)) { + await launchUrl( + uri, + mode: LaunchMode.externalApplication, + ); + } else { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Не удалось открыть ссылку: ${link.url}', + ), + ), + ); + } + } + }, + ) + else + + const SizedBox(height: 16), + + if (!isChannel) + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: () { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Редактирование контакта'), + ), + ); + }, + icon: const Icon(Icons.edit), + label: const Text('Редактировать'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + vertical: 12, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ], + ), + ); + return TweenAnimationBuilder( + tween: Tween( + begin: const Offset(0, 300), + end: Offset.zero, + ), + duration: const Duration(milliseconds: 300), + curve: Curves.easeOutCubic, + builder: (context, offset, child) { + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + duration: const Duration(milliseconds: 200), + curve: Curves.easeIn, + builder: (context, opacity, innerChild) { + return Opacity( + opacity: opacity, + child: Transform.translate( + offset: offset, + child: innerChild, + ), + ); + }, + child: child, + ); + }, + child: panel, + ); + }, + ), + ], + ), + ], + ), + ); + } +} + +class _WallpaperSelectionDialog extends StatefulWidget { + final int chatId; + final Function(String) onImageSelected; + final VoidCallback onRemoveWallpaper; + + const _WallpaperSelectionDialog({ + required this.chatId, + required this.onImageSelected, + required this.onRemoveWallpaper, + }); + + @override + State<_WallpaperSelectionDialog> createState() => + _WallpaperSelectionDialogState(); +} + +class _WallpaperSelectionDialogState extends State<_WallpaperSelectionDialog> { + String? _selectedImagePath; + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final hasExistingWallpaper = theme.hasChatSpecificWallpaper(widget.chatId); + + return AlertDialog( + title: const Text('Обои для чата'), + content: SizedBox( + width: double.maxFinite, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (_selectedImagePath != null) ...[ + Container( + height: 200, + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Theme.of(context).colorScheme.outline, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: Image.file( + File(_selectedImagePath!), + fit: BoxFit.cover, + width: double.infinity, + height: double.infinity, + ), + ), + ), + const SizedBox(height: 16), + ], + + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ElevatedButton.icon( + onPressed: _isLoading ? null : () => _pickImageFromGallery(), + icon: const Icon(Icons.photo_library), + label: const Text('Галерея'), + ), + ElevatedButton.icon( + onPressed: _isLoading ? null : () => _pickImageFromCamera(), + icon: const Icon(Icons.camera_alt), + label: const Text('Камера'), + ), + ], + ), + + const SizedBox(height: 16), + + if (hasExistingWallpaper) + ElevatedButton.icon( + onPressed: _isLoading ? null : widget.onRemoveWallpaper, + icon: const Icon(Icons.delete), + label: const Text('Удалить обои'), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + ), + ], + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + if (_selectedImagePath != null) + FilledButton( + onPressed: _isLoading + ? null + : () => widget.onImageSelected(_selectedImagePath!), + child: _isLoading + ? const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : const Text('Установить'), + ), + ], + ); + } + + Future _pickImageFromGallery() async { + setState(() => _isLoading = true); + try { + final ImagePicker picker = ImagePicker(); + final XFile? image = await picker.pickImage(source: ImageSource.gallery); + if (image != null && mounted) { + setState(() { + _selectedImagePath = image.path; + _isLoading = false; + }); + } else if (mounted) { + setState(() => _isLoading = false); + } + } catch (e) { + if (mounted) { + setState(() => _isLoading = false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка выбора фото: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + + Future _pickImageFromCamera() async { + setState(() => _isLoading = true); + try { + final ImagePicker picker = ImagePicker(); + final XFile? image = await picker.pickImage(source: ImageSource.camera); + if (image != null && mounted) { + setState(() { + _selectedImagePath = image.path; + _isLoading = false; + }); + } else if (mounted) { + setState(() => _isLoading = false); + } + } catch (e) { + if (mounted) { + setState(() => _isLoading = false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка съемки фото: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } +} + +class _AddMemberDialog extends StatefulWidget { + final List> contacts; + final Function(List) onAddMembers; + + const _AddMemberDialog({required this.contacts, required this.onAddMembers}); + + @override + State<_AddMemberDialog> createState() => _AddMemberDialogState(); +} + +class _AddMemberDialogState extends State<_AddMemberDialog> { + final Set _selectedContacts = {}; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Добавить участников'), + content: SizedBox( + width: double.maxFinite, + height: 400, + child: ListView.builder( + itemCount: widget.contacts.length, + itemBuilder: (context, index) { + final contact = widget.contacts[index]; + final contactId = contact['id'] as int; + final contactName = contact['names']?[0]?['name'] ?? 'Неизвестный'; + final isSelected = _selectedContacts.contains(contactId); + + return CheckboxListTile( + value: isSelected, + onChanged: (value) { + setState(() { + if (value == true) { + _selectedContacts.add(contactId); + } else { + _selectedContacts.remove(contactId); + } + }); + }, + title: Text(contactName), + subtitle: Text('ID: $contactId'), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: _selectedContacts.isEmpty + ? null + : () => widget.onAddMembers(_selectedContacts.toList()), + child: Text('Добавить (${_selectedContacts.length})'), + ), + ], + ); + } +} + +class _RemoveMemberDialog extends StatefulWidget { + final List> members; + final Function(List) onRemoveMembers; + + const _RemoveMemberDialog({ + required this.members, + required this.onRemoveMembers, + }); + + @override + State<_RemoveMemberDialog> createState() => _RemoveMemberDialogState(); +} + +class _RemoveMemberDialogState extends State<_RemoveMemberDialog> { + final Set _selectedMembers = {}; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Удалить участников'), + content: SizedBox( + width: double.maxFinite, + height: 400, + child: ListView.builder( + itemCount: widget.members.length, + itemBuilder: (context, index) { + final member = widget.members[index]; + final memberId = member['id'] as int; + final memberName = member['name'] as String; + final isSelected = _selectedMembers.contains(memberId); + + return CheckboxListTile( + value: isSelected, + onChanged: (value) { + setState(() { + if (value == true) { + _selectedMembers.add(memberId); + } else { + _selectedMembers.remove(memberId); + } + }); + }, + title: Text(memberName), + subtitle: Text('ID: $memberId'), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: _selectedMembers.isEmpty + ? null + : () => widget.onRemoveMembers(_selectedMembers.toList()), + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: Text('Удалить (${_selectedMembers.length})'), + ), + ], + ); + } +} + + +class _PromoteAdminDialog extends StatelessWidget { + final List> members; + final Function(int) onPromoteToAdmin; + + const _PromoteAdminDialog({ + required this.members, + required this.onPromoteToAdmin, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Назначить администратором'), + content: SizedBox( + width: double.maxFinite, + height: 300, + child: ListView.builder( + itemCount: members.length, + itemBuilder: (context, index) { + final member = members[index]; + final memberId = member['id'] as int; + final memberName = member['name'] as String; + + return ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of(context).colorScheme.primary, + child: Text( + memberName[0].toUpperCase(), + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + ), + title: Text(memberName), + subtitle: Text('ID: $memberId'), + trailing: const Icon(Icons.admin_panel_settings), + onTap: () => onPromoteToAdmin(memberId), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + ], + ); + } +} + +class _ControlMessageChip extends StatelessWidget { + final Message message; + final Map contacts; // We need this to get user names by ID + final int myId; + + const _ControlMessageChip({ + required this.message, + required this.contacts, + required this.myId, + }); + + String _formatControlMessage() { + + final controlAttach = message.attaches.firstWhere( + (a) => a['_type'] == 'CONTROL', + ); + + final eventType = controlAttach['event']; + final senderName = contacts[message.senderId]?.name ?? 'Неизвестный'; + final isMe = message.senderId == myId; + final senderDisplayName = isMe ? 'Вы' : senderName; + + + String _formatUserList(List userIds) { + if (userIds.isEmpty) { + return ''; + } + final userNames = userIds + .map((id) { + if (id == myId) { + return 'Вы'; + } + return contacts[id]?.name ?? 'участник с ID $id'; + }) + .where((name) => name.isNotEmpty) + .join(', '); + return userNames; + } + + switch (eventType) { + case 'new': + final title = controlAttach['title'] ?? 'Новая группа'; + return '$senderDisplayName создал(а) группу "$title"'; + + case 'add': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return 'К чату присоединились новые участники'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return 'К чату присоединились новые участники'; + } + return '$senderDisplayName добавил(а) в чат: $userNames'; + + case 'remove': + case 'kick': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return '$senderDisplayName удалил(а) участников из чата'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return '$senderDisplayName удалил(а) участников из чата'; + } + + if (userIds.contains(myId)) { + return 'Вы были удалены из чата'; + } + return '$senderDisplayName удалил(а) из чата: $userNames'; + + case 'leave': + if (isMe) { + return 'Вы покинули группу'; + } + return '$senderName покинул(а) группу'; + + case 'title': + final newTitle = controlAttach['title'] ?? ''; + if (newTitle.isEmpty) { + return '$senderDisplayName изменил(а) название группы'; + } + return '$senderDisplayName изменил(а) название группы на "$newTitle"'; + + case 'avatar': + case 'photo': + return '$senderDisplayName изменил(а) фото группы'; + + case 'description': + return '$senderDisplayName изменил(а) описание группы'; + + case 'admin': + case 'promote': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return '$senderDisplayName назначил(а) администраторов'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return '$senderDisplayName назначил(а) администраторов'; + } + + if (userIds.contains(myId) && userIds.length == 1) { + return 'Вас назначили администратором'; + } + return '$senderDisplayName назначил(а) администраторами: $userNames'; + + case 'demote': + case 'remove_admin': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return '$senderDisplayName снял(а) администраторов'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return '$senderDisplayName снял(а) администраторов'; + } + + if (userIds.contains(myId) && userIds.length == 1) { + return 'Вас сняли с должности администратора'; + } + return '$senderDisplayName снял(а) с должности администратора: $userNames'; + + case 'ban': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return '$senderDisplayName заблокировал(а) участников'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return '$senderDisplayName заблокировал(а) участников'; + } + + if (userIds.contains(myId)) { + return 'Вы были заблокированы в чате'; + } + return '$senderDisplayName заблокировал(а): $userNames'; + + case 'unban': + final userIds = List.from( + (controlAttach['userIds'] as List?)?.map((id) => id as int) ?? [], + ); + if (userIds.isEmpty) { + return '$senderDisplayName разблокировал(а) участников'; + } + final userNames = _formatUserList(userIds); + if (userNames.isEmpty) { + return '$senderDisplayName разблокировал(а) участников'; + } + return '$senderDisplayName разблокировал(а): $userNames'; + + case 'join': + if (isMe) { + return 'Вы присоединились к группе'; + } + return '$senderName присоединился(ась) к группе'; + + default: + + final eventTypeStr = eventType?.toString() ?? 'неизвестное'; + return 'Событие: $eventTypeStr'; + } + } + + @override + Widget build(BuildContext context) { + return Center( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), + margin: const EdgeInsets.symmetric(vertical: 8), + decoration: BoxDecoration( + color: Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.5), + borderRadius: BorderRadius.circular(20), + ), + child: Text( + _formatControlMessage(), + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 13, + color: Theme.of(context).colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ); + } +} + +void openUserProfileById(BuildContext context, int userId) { + + final contact = ApiService.instance.getCachedContact(userId); + + if (contact != null) { + + final isGroup = contact.id < 0; // Groups have negative IDs + + if (isGroup) { + + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => GroupProfileDraggableDialog(contact: contact), + ); + } else { + + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, + barrierColor: Colors.transparent, + pageBuilder: (context, animation, secondaryAnimation) { + return ContactProfileDialog(contact: contact); + }, + transitionsBuilder: (context, animation, secondaryAnimation, child) { + return FadeTransition(opacity: animation, child: child); + }, + transitionDuration: const Duration(milliseconds: 300), + ), + ); + } + } else { + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Профиль пользователя $userId'), + content: Text('Информация о пользователе не найдена в кэше'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text('OK'), + ), + ], + ), + ); + } +} + +class _VideoWallpaperBackground extends StatefulWidget { + final String videoPath; + + const _VideoWallpaperBackground({required this.videoPath}); + + @override + State<_VideoWallpaperBackground> createState() => + _VideoWallpaperBackgroundState(); +} + +class _VideoWallpaperBackgroundState extends State<_VideoWallpaperBackground> { + VideoPlayerController? _controller; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _initializeVideo(); + } + + Future _initializeVideo() async { + try { + final file = File(widget.videoPath); + if (!await file.exists()) { + setState(() { + _errorMessage = 'Video file not found'; + }); + print('ERROR: Video file does not exist: ${widget.videoPath}'); + return; + } + + _controller = VideoPlayerController.file(file); + await _controller!.initialize(); + + if (mounted) { + _controller!.setVolume(0); + _controller!.setLooping(true); + _controller!.play(); + setState(() {}); + print('SUCCESS: Video initialized and playing'); + } + } catch (e) { + print('ERROR initializing video: $e'); + setState(() { + _errorMessage = e.toString(); + }); + } + } + + @override + void dispose() { + _controller?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_errorMessage != null) { + print('ERROR building video widget: $_errorMessage'); + return Container( + color: Colors.black, + child: Center( + child: Text( + 'Error loading video\n$_errorMessage', + style: const TextStyle(color: Colors.white), + textAlign: TextAlign.center, + ), + ), + ); + } + + if (_controller == null) { + return const Center(child: CircularProgressIndicator()); + } + + if (!_controller!.value.isInitialized) { + return const Center(child: CircularProgressIndicator()); + } + + return Stack( + fit: StackFit.expand, + children: [ + Positioned.fill( + child: FittedBox( + fit: BoxFit.cover, + child: SizedBox( + width: _controller!.value.size.width, + height: _controller!.value.size.height, + child: VideoPlayer(_controller!), + ), + ), + ), + + Container(color: Colors.black.withOpacity(0.3)), + ], + ); + } +} diff --git a/lib/chats_screen.dart b/lib/chats_screen.dart new file mode 100644 index 0000000..d82d27c --- /dev/null +++ b/lib/chats_screen.dart @@ -0,0 +1,3324 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:intl/intl.dart'; +import 'package:gwid/api_service.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:gwid/chat_screen.dart'; +import 'package:gwid/manage_account_screen.dart'; +import 'package:gwid/screens/settings/settings_screen.dart'; +import 'package:gwid/phone_entry_screen.dart'; +import 'package:gwid/models/chat.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/models/profile.dart'; +import 'package:gwid/models/chat_folder.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:gwid/join_group_screen.dart'; +import 'package:gwid/search_contact_screen.dart'; +import 'package:gwid/channels_list_screen.dart'; +import 'package:gwid/models/channel.dart'; +import 'package:gwid/search_channels_screen.dart'; +import 'package:gwid/downloads_screen.dart'; +import 'package:gwid/user_id_lookup_screen.dart'; + +class SearchResult { + final Chat chat; + final Contact? contact; + final String matchedText; + final String matchType; + final int? messageIndex; + + SearchResult({ + required this.chat, + this.contact, + required this.matchedText, + required this.matchType, + this.messageIndex, + }); +} + +class ChatsScreen extends StatefulWidget { + final void Function( + Chat chat, + Contact contact, + bool isGroup, + bool isChannel, + int? participantCount, + )? + onChatSelected; + final bool hasScaffold; + + const ChatsScreen({super.key, this.onChatSelected, this.hasScaffold = true}); + + @override + State createState() => _ChatsScreenState(); +} + +class _ChatsScreenState extends State + with AutomaticKeepAliveClientMixin, TickerProviderStateMixin { + late Future> _chatsFuture; + bool _showChannelsRail = false; + List _channels = []; + bool _channelsLoaded = false; + StreamSubscription? _apiSubscription; + List _allChats = []; + List _filteredChats = []; + Map _contacts = {}; + bool _isSearchExpanded = false; + String _searchQuery = ''; + Timer? _searchDebounceTimer; + List _searchResults = []; + String _searchFilter = 'all'; + bool _hasRequestedBlockedContacts = false; + + List _folders = []; + String? _selectedFolderId; + late TabController _folderTabController; + + final TextEditingController _searchController = TextEditingController(); + final FocusNode _searchFocusNode = FocusNode(); + late AnimationController _searchAnimationController; + Profile? _myProfile; + bool _isProfileLoading = true; + String _connectionStatus = 'connecting'; + StreamSubscription? _connectionStatusSubscription; + StreamSubscription? _connectionStateSubscription; + + @override + void initState() { + super.initState(); + _loadMyProfile(); + _chatsFuture = (() async { + try { + await ApiService.instance.waitUntilOnline(); + return ApiService.instance.getChatsAndContacts(); + } catch (e) { + print('Ошибка получения чатов: $e'); + if (e.toString().contains('Auth token not found') || + e.toString().contains('FAIL_WRONG_PASSWORD')) { + _showTokenExpiredDialog( + 'Токен авторизации недействителен. Требуется повторная авторизация.', + ); + } + rethrow; + } + })(); + _listenForUpdates(); + + _searchAnimationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + + _folderTabController = TabController(length: 1, vsync: this); + _folderTabController.addListener(_onFolderTabChanged); + + _searchController.addListener(_onSearchChanged); + _searchFocusNode.addListener(_onSearchFocusChanged); + + _connectionStateSubscription = ApiService.instance.connectionStatus.listen(( + status, + ) { + if (mounted) { + setState(() { + _connectionStatus = status; + }); + } + }); + + _connectionStatusSubscription = ApiService.instance.reconnectionComplete + .listen((_) { + if (mounted) { + print("🔄 ChatsScreen: Получено уведомление о переподключении"); + _loadChatsAndContacts(); + print("🔄 ChatsScreen: Обновление чатов запущено"); + } + }); + + Future.delayed(const Duration(seconds: 3), () { + if (mounted) { + _loadChannels(); + } + }); + } + + @override + bool get wantKeepAlive => true; + + Future _loadMyProfile() async { + if (!mounted) return; + setState(() { + _isProfileLoading = true; + }); + + final cachedProfileData = ApiService.instance.lastChatsPayload?['profile']; + if (cachedProfileData != null && mounted) { + setState(() { + _myProfile = Profile.fromJson(cachedProfileData); + _isProfileLoading = false; + }); + return; + } + + try { + if (!ApiService.instance.isOnline) { + await ApiService.instance.waitUntilOnline().timeout( + const Duration(seconds: 10), + onTimeout: () { + print("Таймаут ожидания подключения для загрузки профиля"); + throw TimeoutException("Таймаут подключения"); + }, + ); + } + + final result = await ApiService.instance + .getChatsAndContacts(force: true) + .timeout( + const Duration(seconds: 15), + onTimeout: () { + print("Таймаут загрузки чатов и профиля"); + throw TimeoutException("Таймаут загрузки"); + }, + ); + + if (mounted) { + final profileJson = result['profile']; + if (profileJson != null) { + setState(() { + _myProfile = Profile.fromJson(profileJson); + _isProfileLoading = false; + }); + } else { + setState(() { + _isProfileLoading = false; + }); + } + } + } catch (e) { + if (mounted) { + setState(() { + _isProfileLoading = false; + }); + print("Ошибка загрузки профиля в ChatsScreen: $e"); + } + } + } + + void _navigateToLogin() { + print('Перенаправляем на экран входа из-за недействительного токена'); + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => const PhoneEntryScreen()), + ); + } + + void _showTokenExpiredDialog(String message) { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Ошибка авторизации'), + content: Text(message), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + _navigateToLogin(); + }, + child: const Text('Войти заново'), + ), + ], + ); + }, + ); + } + + + void _listenForUpdates() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'invalid_token') { + print( + 'Получено событие недействительного токена, перенаправляем на вход', + ); + _showTokenExpiredDialog( + message['message'] ?? 'Токен авторизации недействителен', + ); + return; + } + + final opcode = message['opcode']; + final payload = message['payload']; + if (payload == null) return; + final chatIdValue = payload['chatId']; + if (chatIdValue == null) return; + final int chatId = chatIdValue; + + if (opcode == 129) { + _setTypingForChat(chatId); + } + + + if (opcode == 128) { + final newMessage = Message.fromJson(payload['message']); + ApiService.instance.clearCacheForChat(chatId); + + final int chatIndex = _allChats.indexWhere((chat) => chat.id == chatId); + if (chatIndex != -1) { + final oldChat = _allChats[chatIndex]; + final updatedChat = oldChat.copyWith( + lastMessage: newMessage, + newMessages: newMessage.senderId != oldChat.ownerId + ? oldChat.newMessages + 1 + : oldChat.newMessages, + ); + + setState(() { + _allChats.removeAt(chatIndex); + + if (_isSavedMessages(updatedChat)) { + if (updatedChat.id == 0) { + + _allChats.insert(0, updatedChat); + } else { + + final savedIndex = _allChats.indexWhere( + (c) => _isSavedMessages(c) && c.id == 0, + ); + final insertIndex = savedIndex >= 0 ? savedIndex + 1 : 0; + _allChats.insert(insertIndex, updatedChat); + } + } else { + + final savedIndex = _allChats.indexWhere( + (c) => _isSavedMessages(c), + ); + final insertIndex = savedIndex >= 0 ? savedIndex + 1 : 0; + _allChats.insert(insertIndex, updatedChat); + } + _filterChats(); + }); + } + } + + else if (opcode == 67) { + final editedMessage = Message.fromJson(payload['message']); + ApiService.instance.clearCacheForChat(chatId); + + final int chatIndex = _allChats.indexWhere((chat) => chat.id == chatId); + if (chatIndex != -1) { + final oldChat = _allChats[chatIndex]; + + if (oldChat.lastMessage.id == editedMessage.id) { + final updatedChat = oldChat.copyWith(lastMessage: editedMessage); + setState(() { + _allChats.removeAt(chatIndex); + + if (_isSavedMessages(updatedChat)) { + if (updatedChat.id == 0) { + + _allChats.insert(0, updatedChat); + } else { + + final savedIndex = _allChats.indexWhere( + (c) => _isSavedMessages(c) && c.id == 0, + ); + final insertIndex = savedIndex >= 0 ? savedIndex + 1 : 0; + _allChats.insert(insertIndex, updatedChat); + } + } else { + final savedIndex = _allChats.indexWhere( + (c) => _isSavedMessages(c), + ); + final insertIndex = savedIndex >= 0 ? savedIndex + 1 : 0; + _allChats.insert(insertIndex, updatedChat); + } + _filterChats(); + }); + } + } + } + + else if (opcode == 66) { + final deletedMessageIds = List.from( + payload['messageIds'] ?? [], + ); + ApiService.instance.clearCacheForChat(chatId); + + final int chatIndex = _allChats.indexWhere((chat) => chat.id == chatId); + if (chatIndex != -1) { + final oldChat = _allChats[chatIndex]; + + if (deletedMessageIds.contains(oldChat.lastMessage.id)) { + + ApiService.instance.getChatsAndContacts(force: true).then((data) { + if (mounted) { + final chats = data['chats'] as List; + final filtered = chats + .cast>() + .where((chat) => chat['id'] == chatId) + .toList(); + final Map? updatedChatData = + filtered.isNotEmpty ? filtered.first : null; + if (updatedChatData != null) { + final updatedChat = Chat.fromJson(updatedChatData); + setState(() { + _allChats.removeAt(chatIndex); + _allChats.insert(0, updatedChat); + _filterChats(); + }); + } + } + }); + } + } + } + + + if (opcode == 129) { + _setTypingForChat(chatId); + } + + + if (opcode == 132) { + final bool isOnline = payload['online'] == true; + + + final dynamic contactIdAny = payload['contactId'] ?? payload['userId']; + if (contactIdAny != null) { + final int? cid = contactIdAny is int + ? contactIdAny + : int.tryParse(contactIdAny.toString()); + if (cid != null) { + + final currentTime = + DateTime.now().millisecondsSinceEpoch ~/ + 1000; // Конвертируем в секунды + final userPresence = { + 'seen': currentTime, + 'on': isOnline ? 'ON' : 'OFF', + }; + ApiService.instance.updatePresenceData({ + cid.toString(): userPresence, + }); + + print( + 'Обновлен presence для пользователя $cid: online=$isOnline, seen=$currentTime', + ); + + for (final chat in _allChats) { + final otherId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => chat.ownerId, + ); + if (otherId == cid) { + if (isOnline) { + _onlineChats.add(chat.id); + } else { + _onlineChats.remove(chat.id); + } + } + } + if (mounted) setState(() {}); + return; + } + } + + final dynamic cidAny = payload['chatId']; + final int? chatIdFromPayload = cidAny is int + ? cidAny + : int.tryParse(cidAny?.toString() ?? ''); + if (chatIdFromPayload != null) { + if (isOnline) { + _onlineChats.add(chatIdFromPayload); + } else { + _onlineChats.remove(chatIdFromPayload); + } + if (mounted) setState(() {}); + } + } + + + if (opcode == 36 && payload['contacts'] != null) { + final List blockedContactsJson = payload['contacts'] as List; + final blockedContacts = blockedContactsJson + .map((json) => Contact.fromJson(json)) + .toList(); + + + for (final blockedContact in blockedContacts) { + print( + 'Обновляем контакт ${blockedContact.name} (ID: ${blockedContact.id}): isBlocked=${blockedContact.isBlocked}, isBlockedByMe=${blockedContact.isBlockedByMe}', + ); + if (_contacts.containsKey(blockedContact.id)) { + + _contacts[blockedContact.id] = blockedContact; + print( + 'Обновлен существующий контакт: ${_contacts[blockedContact.id]?.name}', + ); + + ApiService.instance.notifyContactUpdate(blockedContact); + } else { + + _contacts[blockedContact.id] = blockedContact; + print( + 'Добавлен новый заблокированный контакт: ${blockedContact.name}', + ); + + ApiService.instance.notifyContactUpdate(blockedContact); + } + } + + if (mounted) setState(() {}); + } + + + if (opcode == 48) { + print('Получен ответ на создание группы: $payload'); + + _refreshChats(); + } + + + if (opcode == 272) { + print('Получен ответ на обновление папок: $payload'); + + if (payload['folders'] != null || payload['foldersOrder'] != null) { + try { + final foldersJson = payload['folders'] as List?; + if (foldersJson != null) { + final folders = foldersJson + .map( + (json) => ChatFolder.fromJson(json as Map), + ) + .toList(); + + if (mounted) { + setState(() { + _folders = folders; + }); + _filterChats(); + } + } + } catch (e) { + print('Ошибка обработки папок из opcode 272: $e'); + } + } else { + _refreshChats(); + } + } + + + if (message['type'] == 'channels_found') { + final payload = message['payload']; + final channelsData = payload['contacts'] as List?; + + if (channelsData != null) { + setState(() { + _channels = channelsData + .map((channelJson) => Channel.fromJson(channelJson)) + .toList(); + }); + } + } + }); + } + + final Map _typingDecayTimers = {}; + final Set _typingChats = {}; + final Set _onlineChats = {}; + void _setTypingForChat(int chatId) { + _typingChats.add(chatId); + _typingDecayTimers[chatId]?.cancel(); + _typingDecayTimers[chatId] = Timer(const Duration(seconds: 11), () { + _typingChats.remove(chatId); + if (mounted) setState(() {}); + }); + if (mounted) setState(() {}); + } + + void _refreshChats() { + + _chatsFuture = ApiService.instance.getChatsAndContacts(force: true); + _chatsFuture.then((data) { + if (mounted) { + final chats = data['chats'] as List; + final contacts = data['contacts'] as List; + + _allChats = chats + .where((json) => json != null) + .map((json) => Chat.fromJson(json)) + .toList(); + _contacts.clear(); + for (final contactJson in contacts) { + final contact = Contact.fromJson(contactJson); + _contacts[contact.id] = contact; + } + _filterChats(); + } + }); + } + + Widget _buildChannelsRail() { + final colors = Theme.of(context).colorScheme; + + return Container( + width: 280, + decoration: BoxDecoration( + color: colors.surface, + border: Border( + right: BorderSide(color: colors.outline.withOpacity(0.2), width: 1), + ), + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + border: Border( + bottom: BorderSide( + color: colors.outline.withOpacity(0.2), + width: 1, + ), + ), + ), + child: Row( + children: [ + Icon( + Icons.broadcast_on_personal, + color: colors.primary, + size: 20, + ), + const SizedBox(width: 8), + Text( + 'Каналы', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.onSurface, + fontSize: 16, + ), + ), + const Spacer(), + IconButton( + icon: const Icon(Icons.search, size: 20), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ChannelsListScreen(), + ), + ); + }, + tooltip: 'Поиск каналов', + ), + ], + ), + ), + + + Expanded(child: _buildChannelsList()), + ], + ), + ); + } + + void _loadChannels() async { + if (_channelsLoaded) return; + + try { + + await ApiService.instance.searchChannels('каналы'); + _channelsLoaded = true; + } catch (e) { + print('Ошибка загрузки каналов: $e'); + } + } + + Widget _buildChannelsList() { + final colors = Theme.of(context).colorScheme; + + if (_channels.isEmpty) { + + return ListView( + padding: const EdgeInsets.all(8), + children: [ + _buildChannelItem( + 'Новости', + 'Актуальные новости', + Icons.newspaper, + colors.primaryContainer, + colors.onPrimaryContainer, + ), + _buildChannelItem( + 'Технологии', + 'IT и технологии', + Icons.computer, + colors.secondaryContainer, + colors.onSecondaryContainer, + ), + _buildChannelItem( + 'Спорт', + 'Спортивные новости', + Icons.sports, + colors.tertiaryContainer, + colors.onTertiaryContainer, + ), + _buildChannelItem( + 'Развлечения', + 'Фильмы, музыка, игры', + Icons.movie, + colors.errorContainer, + colors.onErrorContainer, + ), + _buildChannelItem( + 'Образование', + 'Учеба и развитие', + Icons.school, + colors.primaryContainer, + colors.onPrimaryContainer, + ), + ], + ); + } + + + return ListView.builder( + padding: const EdgeInsets.all(8), + itemCount: _channels.length, + itemBuilder: (context, index) { + final channel = _channels[index]; + return _buildRealChannelItem(channel); + }, + ); + } + + Widget _buildChannelItem( + String title, + String subtitle, + IconData icon, + Color backgroundColor, + Color iconColor, + ) { + return Card( + margin: const EdgeInsets.only(bottom: 8), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + child: ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + leading: CircleAvatar( + radius: 16, + backgroundColor: backgroundColor, + child: Icon(icon, size: 16, color: iconColor), + ), + title: Text( + title, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + ), + subtitle: Text( + subtitle, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + onTap: () { + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Открытие канала: $title'), + backgroundColor: Colors.blue, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + }, + ), + ); + } + + Widget _buildRealChannelItem(Channel channel) { + final colors = Theme.of(context).colorScheme; + + return Card( + margin: const EdgeInsets.only(bottom: 8), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + child: ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + leading: CircleAvatar( + radius: 16, + backgroundImage: channel.photoBaseUrl != null + ? NetworkImage(channel.photoBaseUrl!) + : null, + child: channel.photoBaseUrl == null + ? Text( + channel.name.isNotEmpty ? channel.name[0].toUpperCase() : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ) + : null, + ), + title: Text( + channel.name, + style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), + ), + subtitle: Text( + channel.description ?? 'Канал', + style: TextStyle(fontSize: 12, color: colors.onSurfaceVariant), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChannelDetailsScreen(channel: channel), + ), + ); + }, + ), + ); + } + + void _showAddMenu(BuildContext context) { + showModalBottomSheet( + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + ), + builder: (BuildContext context) { + return Container( + padding: const EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + + Container( + width: 40, + height: 4, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.onSurfaceVariant, + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(height: 20), + Text( + 'Создать', + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 20), + + + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of( + context, + ).colorScheme.primaryContainer, + child: Icon( + Icons.group_add, + color: Theme.of(context).colorScheme.onPrimaryContainer, + ), + ), + title: const Text('Создать группу'), + subtitle: const Text('Создать чат с несколькими участниками'), + onTap: () { + Navigator.pop(context); + _showCreateGroupDialog(); + }, + ), + + + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of( + context, + ).colorScheme.primaryContainer, + child: Icon( + Icons.person_search, + color: Theme.of(context).colorScheme.onPrimaryContainer, + ), + ), + title: const Text('Найти контакт'), + subtitle: const Text('Поиск по номеру телефона'), + onTap: () { + Navigator.pop(context); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SearchContactScreen(), + ), + ); + }, + ), + + + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of( + context, + ).colorScheme.tertiaryContainer, + child: Icon( + Icons.broadcast_on_personal, + color: Theme.of(context).colorScheme.onTertiaryContainer, + ), + ), + title: const Text('Каналы'), + subtitle: const Text('Просмотр и подписка на каналы'), + onTap: () { + Navigator.pop(context); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ChannelsListScreen(), + ), + ); + }, + ), + + + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of( + context, + ).colorScheme.secondaryContainer, + child: Icon( + Icons.link, + color: Theme.of(context).colorScheme.onSecondaryContainer, + ), + ), + title: const Text('Присоединиться к группе'), + subtitle: const Text('По ссылке-приглашению'), + onTap: () { + Navigator.pop(context); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const JoinGroupScreen(), + ), + ); + }, + ), + + + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of( + context, + ).colorScheme.primaryContainer, + child: Icon( + Icons.download, + color: Theme.of(context).colorScheme.onPrimaryContainer, + ), + ), + title: const Text('Загрузки'), + subtitle: const Text('Скачанные файлы'), + onTap: () { + Navigator.pop(context); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const DownloadsScreen(), + ), + ); + }, + ), + + const SizedBox(height: 20), + ], + ), + ); + }, + ); + } + + void _showCreateGroupDialog() { + final TextEditingController nameController = TextEditingController(); + final List selectedContacts = []; + + final int? myId = _myProfile?.id; + + + final List availableContacts = _contacts.values.where((contact) { + final contactNameLower = contact.name.toLowerCase(); + return contactNameLower != 'max' && + contactNameLower != 'gigachat' && + (myId == null || contact.id != myId); + }).toList(); + + showDialog( + context: context, + builder: (context) => StatefulBuilder( + builder: (context, setState) => AlertDialog( + title: const Text('Создать группу'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: nameController, + decoration: const InputDecoration( + labelText: 'Название группы', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 16), + const Text('Выберите участников:'), + const SizedBox(height: 8), + SizedBox( + height: 200, + width: 300, + + child: ListView.builder( + itemCount: availableContacts.length, + itemBuilder: (context, index) { + final contact = availableContacts[index]; + final isSelected = selectedContacts.contains(contact.id); + + return CheckboxListTile( + title: Text(contact.name), + subtitle: Text( + contact.firstName.isNotEmpty && + contact.lastName.isNotEmpty + ? '${contact.firstName} ${contact.lastName}' + : '', + ), + value: isSelected, + onChanged: (value) { + setState(() { + if (value == true) { + selectedContacts.add(contact.id); + } else { + selectedContacts.remove(contact.id); + } + }); + }, + ); + }, + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () { + if (nameController.text.trim().isNotEmpty) { + ApiService.instance.createGroupWithMessage( + nameController.text.trim(), + selectedContacts, // Будет [] если никого не выбрали + ); + Navigator.of(context).pop(); + } + }, + child: const Text('Создать'), + ), + ], + ), + ), + ); + } + + bool _isSavedMessages(Chat chat) { + return chat.id == 0; + } + + bool _isGroupChat(Chat chat) { + + return chat.type == 'CHAT' || chat.participantIds.length > 2; + } + + void _loadFolders(Map data) { + try { + final config = data['config'] as Map?; + if (config == null) return; + + final chatFolders = config['chatFolders'] as Map?; + if (chatFolders == null) return; + + final foldersJson = chatFolders['FOLDERS'] as List?; + if (foldersJson == null) return; + + final folders = foldersJson + .map((json) => ChatFolder.fromJson(json as Map)) + .toList(); + + setState(() { + final oldIndex = _folderTabController.index; + _folders = folders; + final newLength = 1 + folders.length; + if (_folderTabController.length != newLength) { + _folderTabController.removeListener(_onFolderTabChanged); + _folderTabController.dispose(); + _folderTabController = TabController( + length: newLength, + vsync: this, + initialIndex: oldIndex < newLength ? oldIndex : 0, + ); + _folderTabController.addListener(_onFolderTabChanged); + } + + if (_selectedFolderId == null) { + if (_folderTabController.index != 0) { + _folderTabController.animateTo(0); + } + } else { + final folderIndex = folders.indexWhere( + (f) => f.id == _selectedFolderId, + ); + if (folderIndex != -1) { + final targetIndex = folderIndex + 1; + if (_folderTabController.index != targetIndex) { + _folderTabController.animateTo(targetIndex); + } + } + } + }); + } catch (e) { + print('Ошибка загрузки папок: $e'); + } + } + + bool _chatBelongsToFolder(Chat chat, ChatFolder? folder) { + if (folder == null) return true; + + if (folder.include != null && folder.include!.isNotEmpty) { + return folder.include!.contains(chat.id); + } + + if (folder.filters.isNotEmpty) { + final hasContact = folder.filters.any( + (f) => f == 9 || f == '9' || f == 'CONTACT', + ); + final hasNotContact = folder.filters.any( + (f) => f == 8 || f == '8' || f == 'NOT_CONTACT', + ); + + if (hasContact && hasNotContact) { + if (chat.type != 'DIALOG' || + chat.participantIds.length > 2 || + _isGroupChat(chat)) { + return false; + } + + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + if (otherParticipantId != 0) { + final contact = _contacts[otherParticipantId]; + if (contact != null && contact.isBot) { + return false; + } + } + + return true; + } + + for (final filter in folder.filters) { + bool matchesThisFilter = false; + if (filter == 0 || filter == '0' || filter == 'UNREAD') { + matchesThisFilter = chat.newMessages > 0; + } else if (filter == 9 || filter == '9' || filter == 'CONTACT') { + if (chat.type != 'DIALOG' || + chat.participantIds.length > 2 || + _isGroupChat(chat)) { + matchesThisFilter = false; + } else { + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + if (otherParticipantId != 0) { + final contact = _contacts[otherParticipantId]; + matchesThisFilter = contact == null || !contact.isBot; + } else { + matchesThisFilter = true; + } + } + } else if (filter == 8 || filter == '8' || filter == 'NOT_CONTACT') { + matchesThisFilter = + chat.type == 'CHAT' || + chat.type == 'CHANNEL' || + _isGroupChat(chat); + } else { + matchesThisFilter = false; + } + + if (matchesThisFilter) { + return true; + } + } + return false; + } + + return false; + } + + void _filterChats() { + final query = _searchController.text.toLowerCase(); + setState(() { + List chatsToFilter = _allChats; + + if (_selectedFolderId != null) { + final selectedFolder = _folders.firstWhere( + (f) => f.id == _selectedFolderId, + orElse: () => _folders.first, + ); + chatsToFilter = _allChats + .where((chat) => _chatBelongsToFolder(chat, selectedFolder)) + .toList(); + } + + if (query.isEmpty && !_searchFocusNode.hasFocus) { + _filteredChats = List.from(chatsToFilter); + + _filteredChats.sort((a, b) { + final aIsSaved = _isSavedMessages(a); + final bIsSaved = _isSavedMessages(b); + if (aIsSaved && !bIsSaved) return -1; // Избранное в начало + if (!aIsSaved && bIsSaved) return 1; // Избранное в начало + + if (aIsSaved && bIsSaved) { + if (a.id == 0) return -1; + if (b.id == 0) return 1; + } + return 0; // Остальные чаты сохраняют порядок + }); + } else if (_searchFocusNode.hasFocus && query.isEmpty) { + + _filteredChats = []; + } else if (query.isNotEmpty) { + _filteredChats = chatsToFilter.where((chat) { + final isSavedMessages = _isSavedMessages(chat); + if (isSavedMessages) { + return "избранное".contains(query); + } + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + final contactName = + _contacts[otherParticipantId]?.name.toLowerCase() ?? ''; + return contactName.contains(query); + }).toList(); + + _filteredChats.sort((a, b) { + final aIsSaved = _isSavedMessages(a); + final bIsSaved = _isSavedMessages(b); + if (aIsSaved && !bIsSaved) return -1; + if (!aIsSaved && bIsSaved) return 1; + + if (aIsSaved && bIsSaved) { + if (a.id == 0) return -1; + if (b.id == 0) return 1; + } + return 0; + }); + } else { + + _filteredChats = []; + } + }); + } + + void _onSearchChanged() { + final query = _searchController.text; + _searchQuery = query; + + _searchDebounceTimer?.cancel(); + _searchDebounceTimer = Timer(const Duration(milliseconds: 300), () { + _performSearch(); + }); + } + + void _onSearchFocusChanged() { + if (_searchFocusNode.hasFocus) { + _isSearchExpanded = true; + _searchAnimationController.forward(); + } else if (_searchController.text.isEmpty) { + _isSearchExpanded = false; + _searchAnimationController.reverse(); + } + } + + void _performSearch() async { + if (_searchQuery.isEmpty) { + setState(() { + _searchResults.clear(); + }); + return; + } + + setState(() { + + }); + + final results = []; + final query = _searchQuery.toLowerCase(); + + for (final chat in _allChats) { + final isSavedMessages = _isSavedMessages(chat); + + if (isSavedMessages) { + if ("избранное".contains(query)) { + results.add( + SearchResult( + chat: chat, + contact: _contacts[chat.ownerId], + matchedText: "Избранное", + matchType: 'name', + ), + ); + } + continue; + } + + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + final contact = _contacts[otherParticipantId]; + + if (contact == null) continue; + + + if (contact.name.toLowerCase().contains(query)) { + results.add( + SearchResult( + chat: chat, + contact: contact, + matchedText: contact.name, + matchType: 'name', + ), + ); + continue; + } + + + if (contact.description != null && + contact.description?.toLowerCase().contains(query) == true) { + results.add( + SearchResult( + chat: chat, + contact: contact, + matchedText: contact.description ?? '', + matchType: 'description', + ), + ); + continue; + } + + + if (chat.lastMessage.text.toLowerCase().contains(query) || + (chat.lastMessage.text.contains("welcome.saved.dialog.message") && + 'привет избранные майор'.contains(query.toLowerCase()))) { + results.add( + SearchResult( + chat: chat, + contact: contact, + matchedText: + chat.lastMessage.text.contains("welcome.saved.dialog.message") + ? 'Привет! Это твои избранные...' + : chat.lastMessage.text, + matchType: 'message', + ), + ); + } + } + + + List filteredResults = results; + if (_searchFilter == 'recent') { + + final weekAgo = DateTime.now().subtract(const Duration(days: 7)); + filteredResults = results.where((result) { + final lastMessageTime = DateTime.fromMillisecondsSinceEpoch( + result.chat.lastMessage.time, + ); + return lastMessageTime.isAfter(weekAgo); + }).toList(); + } + + setState(() { + _searchResults = filteredResults; + }); + } + + void _clearSearch() { + _searchController.clear(); + _searchFocusNode.unfocus(); + setState(() { + _searchQuery = ''; + _searchResults.clear(); + _isSearchExpanded = false; + }); + _searchAnimationController.reverse(); + } + + void _loadChatsAndContacts() { + setState(() { + _chatsFuture = ApiService.instance.getChatsAndContacts(force: true); + }); + + _chatsFuture.then((data) { + if (mounted) { + final chats = data['chats'] as List; + final contacts = data['contacts'] as List; + + _allChats = chats + .where((json) => json != null) + .map((json) => Chat.fromJson(json)) + .toList(); + + _contacts.clear(); + for (final contactJson in contacts) { + final contact = Contact.fromJson(contactJson); + _contacts[contact.id] = contact; + } + + _filterChats(); + } + }); + } + + Future _loadChatOrder() async { + final prefs = await SharedPreferences.getInstance(); + final savedOrder = prefs.getStringList('chat_order'); + if (savedOrder != null && savedOrder.isNotEmpty) { + final chatIds = savedOrder.map((id) => int.parse(id)).toList(); + final orderedChats = []; + final remainingChats = List.from(_allChats); + + + for (final id in chatIds) { + final chatIndex = remainingChats.indexWhere((chat) => chat.id == id); + if (chatIndex != -1) { + orderedChats.add(remainingChats.removeAt(chatIndex)); + } + } + + + orderedChats.addAll(remainingChats); + + _allChats = orderedChats; + _filteredChats = List.from(_allChats); + } + } + + String _formatTimestamp(int timestamp) { + final dt = DateTime.fromMillisecondsSinceEpoch(timestamp); + final now = DateTime.now(); + if (now.day == dt.day && now.month == dt.month && now.year == dt.year) { + return DateFormat('HH:mm', 'ru').format(dt); + } else { + final yesterday = now.subtract(const Duration(days: 1)); + if (dt.day == yesterday.day && + dt.month == yesterday.month && + dt.year == yesterday.year) { + return 'Вчера'; + } else { + return DateFormat('d MMM', 'ru').format(dt); + } + } + } + + Future _openSferum() async { + try { + await ApiService.instance.waitUntilOnline(); + final seq32 = ApiService.instance.sendAndTrackFullJsonRequest( + jsonEncode({ + "ver": 11, + "cmd": 0, + "seq": 0, + "opcode": 32, + "payload": { + "contactIds": [2340831], + }, + }), + ); + + final resp32 = await ApiService.instance.messages + .firstWhere((m) => m['seq'] == seq32) + .timeout(const Duration(seconds: 10)); + + final contacts = resp32['payload']['contacts'] as List; + if (contacts.isEmpty) { + throw Exception('Не удалось получить информацию о боте'); + } + final webAppUrl = contacts[0]['webApp'] as String?; + if (webAppUrl == null) { + throw Exception('Бот не имеет веб-приложения'); + } + + int? chatId; + for (var chat in _allChats) { + if (chat.participantIds.contains(2340831)) { + chatId = chat.id; + break; + } + } + + print('🔍 Найден chatId для бота Сферума: ${chatId ?? "не найден"}'); + + final seq160 = ApiService.instance.sendAndTrackFullJsonRequest( + jsonEncode({ + "ver": 11, + "cmd": 0, + "seq": 0, + "opcode": 160, + "payload": {"botId": 2340831, "chatId": chatId ?? 0}, + }), + ); + + print('📤 Отправлен opcode 160 с seq: $seq160'); + + final resp160 = await ApiService.instance.messages + .firstWhere((m) => m['seq'] == seq160) + .timeout(const Duration(seconds: 10)); + + print('📥 Получен ответ на opcode 160: ${resp160.toString()}'); + + final webUrl = resp160['payload']['url'] as String?; + if (webUrl == null) { + throw Exception('Не удалось получить URL веб-приложения'); + } + + print('🌐 URL веб-приложения: $webUrl'); + + if (mounted) { + _showSferumWebView(context, webUrl); + } + } catch (e, stackTrace) { + print('❌ Ошибка открытия Сферума: $e'); + print('Stack trace: $stackTrace'); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка открытия Сферума: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + void _showSferumWebView(BuildContext context, String url) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => SferumWebViewPanel(url: url), + ); + } + + Widget _buildConnectionScreen() { + final colors = Theme.of(context).colorScheme; + + return Center( + child: Padding( + padding: const EdgeInsets.all(32.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(colors.primary), + ), + const SizedBox(height: 24), + + + Text( + 'Подключение', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 8), + + + Text( + 'Устанавливаем соединение с сервером...', + style: TextStyle(fontSize: 14, color: colors.onSurfaceVariant), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + super.build(context); + + final Widget bodyContent = Stack( + children: [ + FutureBuilder>( + future: _chatsFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return _buildConnectionScreen(); + } + if (snapshot.hasError) { + return Center( + child: Text('Ошибка загрузки чатов: ${snapshot.error}'), + ); + } + if (snapshot.hasData) { + if (_allChats.isEmpty) { + final chatListJson = snapshot.data!['chats'] as List; + final contactListJson = snapshot.data!['contacts'] as List; + _allChats = chatListJson + .map((json) => Chat.fromJson(json)) + .toList(); + final contacts = contactListJson.map( + (json) => Contact.fromJson(json), + ); + _contacts = {for (var c in contacts) c.id: c}; + + + final presence = + snapshot.data!['presence'] as Map?; + if (presence != null) { + print('Получен presence: $presence'); + + } + + + if (!_hasRequestedBlockedContacts) { + _hasRequestedBlockedContacts = true; + ApiService.instance.getBlockedContacts(); + } + + _loadFolders(snapshot.data!); + + + _loadChatOrder().then((_) { + setState(() { + _filteredChats = List.from(_allChats); + }); + }); + } + if (_filteredChats.isEmpty && _allChats.isEmpty) { + + return const Center(child: CircularProgressIndicator()); + } + + + if (_isSearchExpanded) { + return _buildSearchResults(); + } else { + return Column( + children: [ + _buildFolderTabs(), + Expanded( + child: TabBarView( + controller: _folderTabController, + children: _buildFolderPages(), + ), + ), + ], + ); + } + } + return const Center(child: Text('Нет данных')); + }, + ), + + if (!_isSearchExpanded) _buildDebugRefreshPanel(context), + ], + ); + + if (widget.hasScaffold) { + return Builder( + builder: (context) { + return Scaffold( + appBar: _buildAppBar(context), + drawer: _buildAppDrawer(context), + body: Row(children: [Expanded(child: bodyContent)]), + floatingActionButton: FloatingActionButton( + onPressed: () { + _showAddMenu(context); + }, + tooltip: 'Создать', + heroTag: 'create_menu', + child: const Icon(Icons.edit), + ), + ); + }, + ); + } else { + return bodyContent; + } + } + + Widget _buildAppDrawer(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + final themeProvider = context.watch(); + final isDarkMode = themeProvider.themeMode == ThemeMode.dark; + + return Drawer( + + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Container( + width: double.infinity, + + padding: EdgeInsets.only( + top: MediaQuery.of(context).padding.top + 16.0, + left: 16.0, + right: 16.0, + bottom: 16.0, + ), + decoration: BoxDecoration(color: colors.primaryContainer), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + CircleAvatar( + radius: 30, // Чуть крупнее + backgroundColor: colors.primary, + backgroundImage: + _isProfileLoading || _myProfile?.photoBaseUrl == null + ? null + : NetworkImage(_myProfile!.photoBaseUrl!), + child: _isProfileLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Colors.white, + ), + ) + : (_myProfile?.photoBaseUrl == null + ? Text( + _myProfile?.displayName.isNotEmpty == true + ? _myProfile!.displayName[0] + .toUpperCase() + : '?', + style: TextStyle( + color: colors.onPrimary, + fontSize: 28, // Крупнее + ), + ) + : null), + ), + IconButton( + icon: Icon( + isDarkMode + ? Icons.brightness_7 + : Icons.brightness_4, // Солнце / Луна + color: colors.onPrimaryContainer, + size: 26, + ), + onPressed: () { + themeProvider.toggleTheme(); + }, + tooltip: isDarkMode ? 'Светлая тема' : 'Темная тема', + ), + ], + ), + const SizedBox(height: 12), + + + Text( + _myProfile?.displayName ?? 'Загрузка...', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: colors.onPrimaryContainer, + ), + ), + const SizedBox(height: 4), + + + Text( + _myProfile?.formattedPhone ?? '', + style: TextStyle( + color: colors.onPrimaryContainer.withOpacity(0.8), + fontSize: 14, + ), + ), + ], + ), + ), + + Expanded( + child: Column( + + children: [ + ListTile( + leading: const Icon(Icons.person_outline), + title: const Text('Мой профиль'), + onTap: () { + Navigator.pop(context); // Закрыть Drawer + _navigateToProfileEdit(); // Этот метод у вас уже есть + }, + ), + ListTile( + leading: const Icon(Icons.call_outlined), + title: const Text('Звонки'), + onTap: () { + Navigator.pop(context); // Закрыть Drawer + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const CallsScreen(), + ), + ); + }, + ), + ListTile( + leading: const Icon(Icons.settings_outlined), + title: const Text('Настройки'), + onTap: () { + Navigator.pop(context); // Закрыть Drawer + + + final screenSize = MediaQuery.of(context).size; + final screenWidth = screenSize.width; + final screenHeight = screenSize.height; + final isDesktopOrTablet = + screenWidth >= 600 && + screenHeight >= 800; // Планшеты и десктопы + + print( + 'Screen size: ${screenWidth}x${screenHeight}, isDesktopOrTablet: $isDesktopOrTablet', + ); + + if (isDesktopOrTablet) { + + showDialog( + context: context, + barrierDismissible: true, + builder: (context) => SettingsScreen( + showBackToChats: true, + onBackToChats: () => Navigator.of(context).pop(), + myProfile: _myProfile, + isModal: true, // Включаем модальный режим + ), + ); + } else { + + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => SettingsScreen( + showBackToChats: true, + onBackToChats: () => Navigator.of(context).pop(), + myProfile: _myProfile, + isModal: false, // Отключаем модальный режим + ), + ), + ); + } + }, + ), + + const Spacer(), + + const Divider(height: 1, indent: 16, endIndent: 16), + ListTile( + leading: Icon(Icons.logout, color: colors.error), + title: Text('Выйти', style: TextStyle(color: colors.error)), + onTap: () { + Navigator.pop(context); // Закрыть Drawer + _showLogoutDialog(); + }, + ), + const SizedBox(height: 8), // Небольшой отступ снизу + ], + ), + ), + ], + ), + ); + } + + Widget _buildSearchResults() { + final colors = Theme.of(context).colorScheme; + + if (_searchQuery.isEmpty) { + return Column( + children: [ + + _buildRecentChatsIcons(), + const Divider(height: 1), + + Expanded( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.search, + size: 64, + color: colors.onSurfaceVariant.withOpacity(0.5), + ), + const SizedBox(height: 16), + Text( + 'Начните вводить для поиска', + style: TextStyle( + fontSize: 18, + color: colors.onSurfaceVariant.withOpacity(0.7), + ), + ), + const SizedBox(height: 8), + Text( + 'Или выберите чат из списка выше', + style: TextStyle( + fontSize: 14, + color: colors.onSurfaceVariant.withOpacity(0.5), + ), + ), + ], + ), + ), + ), + ], + ); + } + + if (_searchResults.isEmpty) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.search_off, + size: 64, + color: colors.onSurfaceVariant.withOpacity(0.5), + ), + const SizedBox(height: 16), + Text( + 'Ничего не найдено', + style: TextStyle( + fontSize: 18, + color: colors.onSurfaceVariant.withOpacity(0.7), + ), + ), + const SizedBox(height: 8), + Text( + 'Попробуйте изменить поисковый запрос', + style: TextStyle( + fontSize: 14, + color: colors.onSurfaceVariant.withOpacity(0.5), + ), + ), + ], + ), + ); + } + + return ListView.builder( + itemCount: _searchResults.length, + itemBuilder: (context, index) { + return _buildSearchResultItem(_searchResults[index]); + }, + ); + } + + Widget _buildSearchResultItem(SearchResult result) { + final colors = Theme.of(context).colorScheme; + final chat = result.chat; + final contact = result.contact; + + if (contact == null) return const SizedBox.shrink(); + + return ListTile( + onTap: () { + final bool isSavedMessages = _isSavedMessages(chat); + final bool isGroupChat = _isGroupChat(chat); + final bool isChannel = chat.type == 'CHANNEL'; + final participantCount = + chat.participantsCount ?? chat.participantIds.length; + + if (widget.onChatSelected != null) { + widget.onChatSelected!( + chat, + contact, + isGroupChat, + isChannel, + participantCount, + ); + } else { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChatScreen( + chatId: chat.id, + contact: contact, + myId: chat.ownerId, + isGroupChat: isGroupChat, + isChannel: isChannel, + participantCount: participantCount, + onChatUpdated: () { + print('Chat updated, но не обновляем список чатов...'); + }, + ), + ), + ); + } + }, + leading: CircleAvatar( + radius: 24, + backgroundColor: colors.primaryContainer, + backgroundImage: contact.photoBaseUrl != null + ? NetworkImage(contact.photoBaseUrl ?? '') + : null, + child: contact.photoBaseUrl == null + ? Text( + contact.name.isNotEmpty ? contact.name[0].toUpperCase() : '?', + style: TextStyle(color: colors.onPrimaryContainer), + ) + : null, + ), + title: _buildHighlightedText(contact.name, result.matchedText), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (result.matchType == 'message') + chat.lastMessage.text.contains("welcome.saved.dialog.message") + ? _buildWelcomeMessage() + : _buildSearchMessagePreview(chat, result.matchedText), + if (result.matchType == 'description') + _buildHighlightedText( + contact.description ?? '', + result.matchedText, + ), + const SizedBox(height: 4), + Text( + _formatTimestamp(chat.lastMessage.time), + style: TextStyle(color: colors.onSurfaceVariant, fontSize: 12), + ), + ], + ), + trailing: chat.newMessages > 0 + ? CircleAvatar( + radius: 10, + backgroundColor: colors.primary, + child: Text( + chat.newMessages.toString(), + style: TextStyle(color: colors.onPrimary, fontSize: 12), + ), + ) + : null, + ); + } + + Widget _buildHighlightedText(String text, String query) { + if (query.isEmpty) return Text(text); + + final lowerText = text.toLowerCase(); + final lowerQuery = query.toLowerCase(); + final index = lowerText.indexOf(lowerQuery); + + if (index == -1) return Text(text); + + return RichText( + text: TextSpan( + children: [ + TextSpan( + text: text.substring(0, index), + style: const TextStyle(color: Colors.black), + ), + TextSpan( + text: text.substring(index, index + query.length), + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + TextSpan( + text: text.substring(index + query.length), + style: const TextStyle(color: Colors.black), + ), + ], + ), + ); + } + + Widget _buildRecentChatsIcons() { + final colors = Theme.of(context).colorScheme; + + final recentChats = _allChats.take(15).toList(); + + return Container( + height: 100, + padding: const EdgeInsets.symmetric(vertical: 8), + child: ListView.builder( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.symmetric(horizontal: 16), + itemCount: recentChats.length, + itemBuilder: (context, index) { + final chat = recentChats[index]; + final bool isGroupChat = _isGroupChat(chat); + final bool isSavedMessages = _isSavedMessages(chat); + + final Contact? contact; + if (isSavedMessages) { + contact = _contacts[chat.ownerId]; + } else if (isGroupChat) { + contact = null; + } else { + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + contact = _contacts[otherParticipantId]; + } + + return Padding( + padding: const EdgeInsets.only(right: 12), + child: GestureDetector( + onTap: () { + final bool isChannel = chat.type == 'CHANNEL'; + final String title = isGroupChat + ? (chat.title?.isNotEmpty == true ? chat.title! : "Группа") + : (isSavedMessages + ? "Избранное" + : contact?.name ?? "Unknown"); + final String? avatarUrl = isGroupChat + ? chat.baseIconUrl + : (isSavedMessages ? null : contact?.photoBaseUrl); + final participantCount = + chat.participantsCount ?? chat.participantIds.length; + + final Contact contactFallback = + contact ?? + Contact( + id: chat.id, + name: title, + firstName: "", + lastName: "", + photoBaseUrl: avatarUrl, + description: isChannel ? chat.description : null, + isBlocked: false, + isBlockedByMe: false, + ); + + if (widget.onChatSelected != null) { + widget.onChatSelected!( + chat, + contactFallback, + isGroupChat, + isChannel, + participantCount, + ); + } else { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChatScreen( + chatId: chat.id, + contact: contactFallback, + myId: chat.ownerId, + isGroupChat: isGroupChat, + isChannel: isChannel, + participantCount: participantCount, + onChatUpdated: () { + _loadChatsAndContacts(); + }, + ), + ), + ); + } + }, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Stack( + children: [ + CircleAvatar( + radius: 28, + backgroundColor: colors.primaryContainer, + backgroundImage: + !isSavedMessages && + !isGroupChat && + contact?.photoBaseUrl != null + ? NetworkImage(contact?.photoBaseUrl ?? '') + : (isGroupChat && chat.baseIconUrl != null) + ? NetworkImage(chat.baseIconUrl ?? '') + : null, + child: + isSavedMessages || + (isGroupChat && chat.baseIconUrl == null) + ? Icon( + isSavedMessages ? Icons.bookmark : Icons.group, + color: colors.onPrimaryContainer, + size: 20, + ) + : (contact?.photoBaseUrl == null + ? Text( + (contact != null && + contact.name.isNotEmpty) + ? contact.name[0].toUpperCase() + : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + fontSize: 16, + ), + ) + : null), + ), + + if (chat.newMessages > 0) + Positioned( + right: 0, + top: 0, + child: Container( + width: 16, + height: 16, + decoration: BoxDecoration( + color: colors.primary, + shape: BoxShape.circle, + border: Border.all( + color: colors.surface, + width: 2, + ), + ), + child: Center( + child: Text( + chat.newMessages > 9 + ? '9+' + : chat.newMessages.toString(), + style: TextStyle( + color: colors.onPrimary, + fontSize: 8, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ], + ), + const SizedBox(height: 4), + SizedBox( + width: 56, + child: isGroupChat + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.group, + size: 10, + color: colors.onSurface, + ), + const SizedBox(width: 2), + Expanded( + child: Text( + chat.title?.isNotEmpty == true + ? chat.title! + : "Группа (${chat.participantIds.length})", + style: TextStyle( + fontSize: 11, + color: colors.onSurface, + ), + textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ) + : Text( + isSavedMessages + ? "Избранное" + : (contact?.name ?? 'Unknown'), + style: TextStyle( + fontSize: 11, + color: colors.onSurface, + ), + textAlign: TextAlign.center, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + ); + }, + ), + ); + } + + void _onFolderTabChanged() { + if (!_folderTabController.indexIsChanging) { + final index = _folderTabController.index; + final folderId = index == 0 ? null : _folders[index - 1].id; + + if (_selectedFolderId != folderId) { + setState(() { + _selectedFolderId = folderId; + }); + _filterChats(); + } + } + } + + List _buildFolderPages() { + final List pages = [ + _buildChatsListForFolder(null), + ..._folders.map((folder) => _buildChatsListForFolder(folder)), + ]; + + return pages; + } + + Widget _buildChatsListForFolder(ChatFolder? folder) { + List chatsForFolder = _allChats; + + if (folder != null) { + chatsForFolder = _allChats + .where((chat) => _chatBelongsToFolder(chat, folder)) + .toList(); + } + + chatsForFolder.sort((a, b) { + final aIsSaved = _isSavedMessages(a); + final bIsSaved = _isSavedMessages(b); + if (aIsSaved && !bIsSaved) return -1; + if (!aIsSaved && bIsSaved) return 1; + if (aIsSaved && bIsSaved) { + if (a.id == 0) return -1; + if (b.id == 0) return 1; + } + return 0; + }); + + final query = _searchController.text.toLowerCase(); + if (query.isNotEmpty) { + chatsForFolder = chatsForFolder.where((chat) { + final isSavedMessages = _isSavedMessages(chat); + if (isSavedMessages) { + return "избранное".contains(query); + } + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != chat.ownerId, + orElse: () => 0, + ); + final contactName = + _contacts[otherParticipantId]?.name.toLowerCase() ?? ''; + return contactName.contains(query); + }).toList(); + } + + if (chatsForFolder.isEmpty) { + return Center( + child: Text( + folder == null ? 'Нет чатов' : 'В этой папке пока нет чатов', + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ); + } + + return ListView.builder( + itemCount: chatsForFolder.length, + itemBuilder: (context, index) { + return _buildChatListItem(chatsForFolder[index], index); + }, + ); + } + + Widget _buildFolderTabs() { + final colors = Theme.of(context).colorScheme; + + final List tabs = [ + Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [Text('Все чаты', style: TextStyle(fontSize: 14))], + ), + ), + ..._folders.map( + (folder) => Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (folder.emoji != null) ...[ + Text(folder.emoji!, style: const TextStyle(fontSize: 16)), + const SizedBox(width: 6), + ], + Text(folder.title, style: const TextStyle(fontSize: 14)), + ], + ), + ), + ), + ]; + + return Container( + height: 48, + decoration: BoxDecoration( + color: colors.surface, + border: Border( + bottom: BorderSide(color: colors.outline.withOpacity(0.2), width: 1), + ), + ), + child: TabBar( + controller: _folderTabController, + isScrollable: true, + labelColor: colors.primary, + unselectedLabelColor: colors.onSurfaceVariant, + indicator: UnderlineTabIndicator( + borderSide: BorderSide(width: 3, color: colors.primary), + insets: const EdgeInsets.symmetric(horizontal: 16), + ), + indicatorSize: TabBarIndicatorSize.label, + labelStyle: const TextStyle(fontWeight: FontWeight.w600, fontSize: 14), + unselectedLabelStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 14, + ), + dividerColor: Colors.transparent, + tabs: tabs, + onTap: (index) {}, + ), + ); + } + + Widget _buildDebugRefreshPanel(BuildContext context) { + final theme = context.watch(); + if (!theme.debugShowChatsRefreshPanel) return const SizedBox.shrink(); + final bool hasBottomBar = theme.debugShowBottomBar; + final double bottomPadding = hasBottomBar ? 80.0 : 20.0; + final colors = Theme.of(context).colorScheme; + return Positioned( + left: 12, + right: 12, + bottom: bottomPadding, + child: SafeArea( + top: false, + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 520), + child: Material( + color: colors.surface.withOpacity(0.95), + elevation: 6, + borderRadius: BorderRadius.circular(12), + child: InkWell( + borderRadius: BorderRadius.circular(12), + onTap: () async { + + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _allChats.clear(); + _filteredChats.clear(); + _chatsFuture = ApiService.instance.getChatsAndContacts( + force: true, + ); + }); + } + }); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 10, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.refresh), + const SizedBox(width: 8), + const Text('Обновить список чатов'), + ], + ), + ), + ), + ), + ), + ), + ), + ); + } + + Widget _buildStatusRow({ + required Key key, + required String text, + required Widget icon, + }) { + return Row( + key: key, + children: [ + SizedBox(width: 18, height: 18, child: Center(child: icon)), + const SizedBox(width: 8), + Flexible( + child: Text( + text, + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ); + } + + Widget _buildCurrentTitleWidget() { + final colors = Theme.of(context).colorScheme; + final onSurfaceVariant = colors.onSurfaceVariant; + + if (_connectionStatus == 'connecting') { + return _buildStatusRow( + key: const ValueKey('status_connecting'), + text: 'Подключение...', + icon: CircularProgressIndicator( + strokeWidth: 2, + color: onSurfaceVariant, + ), + ); + } + + if (_connectionStatus == 'authorizing') { + return _buildStatusRow( + key: const ValueKey('status_authorizing'), + text: 'Авторизация...', + icon: CircularProgressIndicator( + strokeWidth: 2, + color: onSurfaceVariant, + ), + ); + } + + if (_connectionStatus == 'disconnected' || + _connectionStatus == 'Все серверы недоступны') { + return _buildStatusRow( + key: const ValueKey('status_error'), + text: 'Нет сети', + icon: Icon(Icons.cloud_off, size: 18, color: colors.error), + ); + } + + if (_isProfileLoading) { + return _buildStatusRow( + key: const ValueKey('status_loading'), + text: 'Загрузка...', + icon: CircularProgressIndicator( + strokeWidth: 2, + color: onSurfaceVariant, + ), + ); + } + + return Text( + _myProfile?.displayName ?? 'Komet', + key: const ValueKey('status_username'), + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ); + } + + AppBar _buildAppBar(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return AppBar( + titleSpacing: 4.0, + + leading: _isSearchExpanded + ? IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: _clearSearch, + ) + : Builder( + builder: (context) { + return IconButton( + icon: const Icon(Icons.menu_rounded), + onPressed: () => Scaffold.of(context).openDrawer(), + tooltip: 'Меню', + ); + }, + ), + + title: _isSearchExpanded + ? _buildSearchField(colors) + : Row( + children: [ + Expanded( + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: + (Widget child, Animation animation) { + return FadeTransition( + opacity: animation, + child: child, + ); + }, + layoutBuilder: (currentChild, previousChildren) { + return Stack( + alignment: Alignment.centerLeft, + children: [ + ...previousChildren, + if (currentChild != null) currentChild, + ], + ); + }, + child: _buildCurrentTitleWidget(), + ), + ), + ], + ), + actions: _isSearchExpanded + ? [ + if (_searchQuery.isNotEmpty) + Container( + margin: const EdgeInsets.only(left: 4), + child: IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _searchController.clear(); + }, + ), + ), + Container( + margin: const EdgeInsets.only(left: 4), + child: IconButton( + icon: const Icon(Icons.filter_list), + onPressed: _showSearchFilters, + ), + ), + ] + : [ + IconButton( + icon: Image.asset( + 'assets/images/spermum.webp', + width: 28, + height: 28, + ), + onPressed: _openSferum, + tooltip: 'Сферум', + ), + IconButton( + icon: const Icon(Icons.download), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const DownloadsScreen(), + ), + ); + }, + tooltip: 'Загрузки', + ), + InkWell( + + onTap: () { + setState(() { + _isSearchExpanded = true; + }); + _searchAnimationController.forward(); + _searchFocusNode.requestFocus(); + }, + + onLongPress: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const UserIdLookupScreen(), + ), + ); + }, + customBorder: const CircleBorder(), + child: Container( + padding: const EdgeInsets.all(8.0), + child: const Icon(Icons.search), + ), + ), + const SizedBox(width: 8), + ], + ); + } + + Widget _buildWelcomeMessage() { + return Text( + 'Привет! Это твои избранные. Все написанное сюда попадёт прямиком к дяде Майору.', + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant, + fontSize: 12, + fontStyle: FontStyle.italic, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ); + } + + Widget _buildSearchField(ColorScheme colors) { + return SizedBox( + height: 40, + child: TextField( + controller: _searchController, + focusNode: _searchFocusNode, + autofocus: true, + decoration: InputDecoration( + contentPadding: EdgeInsets.zero, + prefixIcon: Icon( + Icons.search, + color: colors.onSurfaceVariant, + size: 18, + ), + hintText: 'Поиск в чатах...', + hintStyle: TextStyle(color: colors.onSurfaceVariant), + filled: true, + fillColor: colors.surfaceContainerHighest.withOpacity(0.3), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(20), + borderSide: BorderSide.none, + ), + ), + style: const TextStyle(fontSize: 16), + ), + ); + } + + void _navigateToProfileEdit() { + if (_myProfile != null) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ManageAccountScreen(myProfile: _myProfile!), + ), + ); + } else { + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('Профиль еще не загружен'))); + } + } + + void _showLogoutDialog() { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('Выход из аккаунта'), + content: const Text('Вы действительно хотите выйти из аккаунта?'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () async { + Navigator.pop(context); + await _logout(); + }, + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: const Text('Выйти'), + ), + ], + ); + }, + ); + } + + Future _logout() async { + try { + if (mounted) { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const PhoneEntryScreen()), + (route) => false, + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Ошибка при выходе: $e'))); + } + } + } + + void _showSearchFilters() { + showModalBottomSheet( + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'Фильтры поиска', + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 16), + _buildFilterOption('all', 'Все чаты', Icons.chat_bubble_outline), + _buildFilterOption('recent', 'Недавние', Icons.access_time), + _buildFilterOption( + 'channels', + 'Каналы', + Icons.broadcast_on_personal, + ), + _buildFilterOption('groups', 'Группы', Icons.group), + ], + ), + ), + ); + } + + Widget _buildFilterOption(String value, String title, IconData icon) { + final isSelected = _searchFilter == value; + return ListTile( + leading: Icon( + icon, + color: isSelected ? Theme.of(context).colorScheme.primary : null, + ), + title: Text(title), + trailing: isSelected ? const Icon(Icons.check) : null, + onTap: () { + setState(() { + _searchFilter = value; + }); + Navigator.pop(context); + _performSearch(); + }, + ); + } + + Widget _buildLastMessagePreview(Chat chat) { + final message = chat.lastMessage; + + + + if (message.attaches.isNotEmpty) { + + for (final attach in message.attaches) { + final type = attach['_type']; + if (type == 'CALL' || type == 'call') { + + return _buildCallPreview(attach, message, chat); + } + } + } + + + if (message.text.isEmpty && message.attaches.isNotEmpty) { + return Text('Вложение', maxLines: 1, overflow: TextOverflow.ellipsis); + } + + + return Text(message.text, maxLines: 1, overflow: TextOverflow.ellipsis); + } + + Widget _buildSearchMessagePreview(Chat chat, String matchedText) { + final message = chat.lastMessage; + + + if (message.attaches.isNotEmpty) { + final callAttachments = message.attaches.where((attach) { + final type = attach['_type']; + return type == 'CALL' || type == 'call'; + }).toList(); + + if (callAttachments.isNotEmpty) { + + return _buildCallPreview(callAttachments.first, message, chat); + } + } + + + if (message.text.isEmpty && message.attaches.isNotEmpty) { + return Text('Вложение', maxLines: 1, overflow: TextOverflow.ellipsis); + } + + return _buildHighlightedText(message.text, matchedText); + } + + Widget _buildCallPreview( + Map callAttach, + Message message, + Chat chat, + ) { + final colors = Theme.of(context).colorScheme; + final hangupType = callAttach['hangupType'] as String? ?? ''; + final callType = callAttach['callType'] as String? ?? 'AUDIO'; + final duration = callAttach['duration'] as int? ?? 0; + + String callText; + IconData callIcon; + Color? callColor; + + + switch (hangupType) { + case 'HUNGUP': + + final minutes = duration ~/ 60000; + final seconds = (duration % 60000) ~/ 1000; + final durationText = minutes > 0 + ? '$minutes:${seconds.toString().padLeft(2, '0')}' + : '$seconds сек'; + + final callTypeText = callType == 'VIDEO' ? 'Видеозвонок' : 'Звонок'; + callText = '$callTypeText, $durationText'; + callIcon = callType == 'VIDEO' ? Icons.videocam : Icons.call; + callColor = colors.primary; + break; + + case 'MISSED': + + final callTypeText = callType == 'VIDEO' + ? 'Пропущенный видеозвонок' + : 'Пропущенный звонок'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_missed; + callColor = colors.error; + break; + + case 'CANCELED': + + final callTypeText = callType == 'VIDEO' + ? 'Видеозвонок отменен' + : 'Звонок отменен'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_end; + callColor = colors.onSurfaceVariant; + break; + + case 'REJECTED': + + final callTypeText = callType == 'VIDEO' + ? 'Видеозвонок отклонен' + : 'Звонок отклонен'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_end; + callColor = colors.onSurfaceVariant; + break; + + default: + + callText = callType == 'VIDEO' ? 'Видеозвонок' : 'Звонок'; + callIcon = callType == 'VIDEO' ? Icons.videocam : Icons.call; + callColor = colors.onSurfaceVariant; + break; + } + + return Row( + children: [ + Icon(callIcon, size: 16, color: callColor), + const SizedBox(width: 4), + Expanded( + child: Text( + callText, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: callColor), + ), + ), + ], + ); + } + + Widget _buildChatListItem(Chat chat, int index) { + final colors = Theme.of(context).colorScheme; + + final bool isSavedMessages = _isSavedMessages(chat); + final bool isGroupChat = _isGroupChat(chat); + final bool isChannel = chat.type == 'CHANNEL'; + + Contact? contact; + String title; + final String? avatarUrl; + IconData leadingIcon; + + if (isSavedMessages) { + contact = _contacts[chat.ownerId]; + title = "Избранное"; + leadingIcon = Icons.bookmark; + avatarUrl = null; + } else if (isChannel) { + contact = null; + title = chat.title ?? "Канал"; + leadingIcon = Icons.campaign; + avatarUrl = chat.baseIconUrl; + } else if (isGroupChat) { + contact = null; + title = chat.title?.isNotEmpty == true + ? chat.title! + : "Группа (${chat.participantIds.length} участников)"; + leadingIcon = Icons.group; + avatarUrl = chat.baseIconUrl; + } else { + final myId = chat.ownerId; + final otherParticipantId = chat.participantIds.firstWhere( + (id) => id != myId, + orElse: () => myId, + ); + contact = _contacts[otherParticipantId]; + + title = contact?.name ?? "Неизвестный чат"; + avatarUrl = contact?.photoBaseUrl; + leadingIcon = Icons.person; + } + + return ListTile( + key: ValueKey(chat.id), + + onTap: () { + final theme = context.read(); + if (theme.debugReadOnEnter) { + final chatIndex = _allChats.indexWhere((c) => c.id == chat.id); + if (chatIndex != -1) { + final oldChat = _allChats[chatIndex]; + if (oldChat.newMessages > 0) { + final updatedChat = oldChat.copyWith(newMessages: 0); + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _allChats[chatIndex] = updatedChat; + _filterChats(); + }); + } + }); + } + } + } + + final Contact contactFallback = + contact ?? + Contact( + id: chat.id, + name: title, + firstName: "", + lastName: "", + photoBaseUrl: avatarUrl, + description: isChannel ? chat.description : null, + isBlocked: false, + isBlockedByMe: false, + ); + + + final participantCount = + chat.participantsCount ?? chat.participantIds.length; + + if (widget.onChatSelected != null) { + widget.onChatSelected!( + chat, + contactFallback, + isGroupChat, + isChannel, + participantCount, + ); + } else { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChatScreen( + chatId: chat.id, + contact: contactFallback, + myId: chat.ownerId, + isGroupChat: isGroupChat, + isChannel: isChannel, + participantCount: participantCount, + onChatUpdated: () { + print('Chat updated, но не обновляем список чатов...'); + }, + ), + ), + ); + } + }, + leading: Stack( + clipBehavior: Clip.none, + children: [ + CircleAvatar( + radius: 24, + backgroundColor: colors.primaryContainer, + + backgroundImage: avatarUrl != null ? NetworkImage(avatarUrl) : null, + + child: avatarUrl == null + ? (isSavedMessages || isGroupChat || isChannel) + + ? Icon(leadingIcon, color: colors.onPrimaryContainer) + + : Text( + title.isNotEmpty ? title[0].toUpperCase() : '?', + style: TextStyle(color: colors.onPrimaryContainer), + ) + : null, + ), + Positioned( + right: -4, + bottom: -2, + child: _typingChats.contains(chat.id) + ? _TypingDots(color: colors.primary, size: 20) + : (_onlineChats.contains(chat.id) + ? _PresenceDot(isOnline: true, size: 12) + : const SizedBox.shrink()), + ), + ], + ), + title: Row( + children: [ + if (isGroupChat) ...[ + Icon(Icons.group, size: 16, color: colors.onSurfaceVariant), + const SizedBox(width: 6), + ], + Expanded( + child: Text( + title, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + ], + ), + subtitle: chat.lastMessage.text.contains("welcome.saved.dialog.message") + ? _buildWelcomeMessage() + : _buildLastMessagePreview(chat), + trailing: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + _formatTimestamp(chat.lastMessage.time), + style: TextStyle( + color: chat.newMessages > 0 + ? colors.primary + : colors.onSurfaceVariant, + fontSize: 12, + ), + ), + if (chat.newMessages > 0 && !isSavedMessages) ...[ + const SizedBox(height: 4), + CircleAvatar( + radius: 10, + backgroundColor: colors.primary, + child: Text( + chat.newMessages.toString(), + style: TextStyle(color: colors.onPrimary, fontSize: 12), + ), + ), + ], + ], + ), + ); + } + + @override + void dispose() { + _apiSubscription?.cancel(); + _connectionStatusSubscription?.cancel(); + _connectionStateSubscription?.cancel(); + _searchController.dispose(); + _searchFocusNode.dispose(); + _searchDebounceTimer?.cancel(); + _searchAnimationController.dispose(); + _folderTabController.dispose(); + super.dispose(); + } +} + +class _TypingDots extends StatefulWidget { + final Color color; + final double size; + const _TypingDots({required this.color, this.size = 18}); + @override + State<_TypingDots> createState() => _TypingDotsState(); +} + +class _TypingDotsState extends State<_TypingDots> + with SingleTickerProviderStateMixin { + late final AnimationController _c; + @override + void initState() { + super.initState(); + _c = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 900), + )..repeat(); + } + + @override + void dispose() { + _c.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final w = widget.size; + return SizedBox( + width: w, + height: w * 0.6, + child: AnimatedBuilder( + animation: _c, + builder: (context, _) { + final t = _c.value; + double a(int i) => 0.3 + 0.7 * ((t + i / 3) % 1.0); + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: List.generate(3, (i) { + return Opacity( + opacity: a(i), + child: Container( + width: w * 0.22, + height: w * 0.22, + decoration: BoxDecoration( + color: widget.color, + shape: BoxShape.circle, + ), + ), + ); + }), + ); + }, + ), + ); + } +} + +class _PresenceDot extends StatelessWidget { + final bool isOnline; + final double size; + const _PresenceDot({required this.isOnline, this.size = 10}); + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Container( + width: size, + height: size, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isOnline ? colors.primary : colors.onSurfaceVariant, + ), + ); + } +} + +class CallsScreen extends StatelessWidget { + const CallsScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Звонки')), + body: const Center(child: Text('Звонки скоро будут доступны')), + ); + } +} + +class SferumWebViewPanel extends StatefulWidget { + final String url; + + const SferumWebViewPanel({super.key, required this.url}); + + @override + State createState() => _SferumWebViewPanelState(); +} + +class _SferumWebViewPanelState extends State { + bool _isLoading = true; + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return DraggableScrollableSheet( + initialChildSize: 0.9, + minChildSize: 0.5, + maxChildSize: 0.95, + builder: (context, scrollController) { + return Container( + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: colors.outline.withOpacity(0.2), + width: 1, + ), + ), + ), + child: Row( + children: [ + Image.asset( + 'assets/images/spermum.webp', + width: 28, + height: 28, + ), + const SizedBox(width: 12), + const Text( + 'Сферум', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + const Spacer(), + IconButton( + icon: const Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + ], + ), + ), + + Expanded( + child: Stack( + children: [ + InAppWebView( + initialUrlRequest: URLRequest(url: WebUri(widget.url)), + initialSettings: InAppWebViewSettings( + javaScriptEnabled: true, + transparentBackground: true, + useShouldOverrideUrlLoading: false, + useOnLoadResource: false, + useOnDownloadStart: false, + cacheEnabled: true, + ), + onLoadStart: (controller, url) { + print('🌐 WebView начало загрузки: $url'); + setState(() { + _isLoading = true; + }); + }, + onLoadStop: (controller, url) { + print('✅ WebView загрузка завершена: $url'); + setState(() { + _isLoading = false; + }); + }, + onReceivedError: (controller, request, error) { + print( + '❌ WebView ошибка: ${error.description} (${error.type})', + ); + }, + ), + if (_isLoading) + Container( + color: colors.surface, + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/connection/connection_logger.dart b/lib/connection/connection_logger.dart new file mode 100644 index 0000000..33ab366 --- /dev/null +++ b/lib/connection/connection_logger.dart @@ -0,0 +1,317 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/foundation.dart'; + + +enum LogLevel { debug, info, warning, error, critical } + + +class ConnectionLogger { + static final ConnectionLogger _instance = ConnectionLogger._internal(); + factory ConnectionLogger() => _instance; + ConnectionLogger._internal(); + + final List _logs = []; + final StreamController _logController = + StreamController.broadcast(); + + + Stream get logStream => _logController.stream; + + + List get logs => List.unmodifiable(_logs); + + + static const int maxLogs = 1000; + + + LogLevel _currentLevel = LogLevel.debug; + + void setLogLevel(LogLevel level) { + _currentLevel = level; + } + + + void log( + String message, { + LogLevel level = LogLevel.info, + String? category, + Map? data, + Object? error, + StackTrace? stackTrace, + }) { + if (level.index < _currentLevel.index) return; + + final entry = LogEntry( + timestamp: DateTime.now(), + level: level, + message: message, + category: category ?? 'CONNECTION', + data: data, + error: error, + stackTrace: stackTrace, + ); + + _logs.add(entry); + + + if (_logs.length > maxLogs) { + _logs.removeRange(0, _logs.length - maxLogs); + } + + _logController.add(entry); + + + if (kDebugMode) { + final emoji = _getEmojiForLevel(level); + final timestamp = entry.timestamp.toIso8601String().substring(11, 23); + final categoryStr = category != null ? '[$category]' : ''; + final dataStr = data != null ? ' | Data: ${jsonEncode(data)}' : ''; + final errorStr = error != null ? ' | Error: $error' : ''; + + print('$emoji [$timestamp] $categoryStr $message$dataStr$errorStr'); + } + } + + + void logConnection( + String message, { + Map? data, + Object? error, + }) { + log( + message, + level: LogLevel.info, + category: 'CONNECTION', + data: data, + error: error, + ); + } + + + void logError( + String message, { + Map? data, + Object? error, + StackTrace? stackTrace, + }) { + log( + message, + level: LogLevel.error, + category: 'ERROR', + data: data, + error: error, + stackTrace: stackTrace, + ); + } + + + void logMessage( + String direction, + dynamic message, { + Map? metadata, + }) { + final data = { + 'direction': direction, + 'message': message, + if (metadata != null) ...metadata, + }; + log( + 'WebSocket $direction', + level: LogLevel.debug, + category: 'WEBSOCKET', + data: data, + ); + } + + + void logReconnect(int attempt, String reason, {Duration? delay}) { + final data = { + 'attempt': attempt, + 'reason': reason, + if (delay != null) 'delay_seconds': delay.inSeconds, + }; + log( + 'Переподключение: $reason (попытка $attempt)', + level: LogLevel.warning, + category: 'RECONNECT', + data: data, + ); + } + + + void logPerformance( + String operation, + Duration duration, { + Map? metadata, + }) { + final data = { + 'operation': operation, + 'duration_ms': duration.inMilliseconds, + if (metadata != null) ...metadata, + }; + log( + 'Performance: $operation за ${duration.inMilliseconds}ms', + level: LogLevel.debug, + category: 'PERFORMANCE', + data: data, + ); + } + + + void logState(String from, String to, {Map? metadata}) { + final data = { + 'from': from, + 'to': to, + if (metadata != null) ...metadata, + }; + log( + 'Состояние: $from → $to', + level: LogLevel.info, + category: 'STATE', + data: data, + ); + } + + + List getLogsByCategory(String category) { + return _logs.where((log) => log.category == category).toList(); + } + + + List getLogsByLevel(LogLevel level) { + return _logs.where((log) => log.level == level).toList(); + } + + + Map getLogStats() { + final stats = {}; + for (final log in _logs) { + stats[log.category] = (stats[log.category] ?? 0) + 1; + } + return stats; + } + + + void clearLogs() { + _logs.clear(); + log('Логи очищены', level: LogLevel.info, category: 'LOGGER'); + } + + + String exportLogs() { + final logsJson = _logs.map((log) => log.toJson()).toList(); + return jsonEncode(logsJson); + } + + + void importLogs(String jsonString) { + try { + final List logsList = jsonDecode(jsonString); + _logs.clear(); + for (final logJson in logsList) { + _logs.add(LogEntry.fromJson(logJson)); + } + log( + 'Импортировано ${_logs.length} логов', + level: LogLevel.info, + category: 'LOGGER', + ); + } catch (e) { + logError('Ошибка импорта логов', error: e); + } + } + + String _getEmojiForLevel(LogLevel level) { + switch (level) { + case LogLevel.debug: + return '🔍'; + case LogLevel.info: + return 'ℹ️'; + case LogLevel.warning: + return '⚠️'; + case LogLevel.error: + return '❌'; + case LogLevel.critical: + return '🚨'; + } + } + + void dispose() { + _logController.close(); + } +} + + +class LogEntry { + final DateTime timestamp; + final LogLevel level; + final String message; + final String category; + final Map? data; + final Object? error; + final StackTrace? stackTrace; + + LogEntry({ + required this.timestamp, + required this.level, + required this.message, + required this.category, + this.data, + this.error, + this.stackTrace, + }); + + Map toJson() { + return { + 'timestamp': timestamp.toIso8601String(), + 'level': level.name, + 'message': message, + 'category': category, + 'data': data, + 'error': error?.toString(), + 'stackTrace': stackTrace?.toString(), + }; + } + + factory LogEntry.fromJson(Map json) { + return LogEntry( + timestamp: DateTime.parse(json['timestamp']), + level: LogLevel.values.firstWhere((l) => l.name == json['level']), + message: json['message'], + category: json['category'], + data: json['data'] != null + ? Map.from(json['data']) + : null, + error: json['error'], + stackTrace: json['stackTrace'] != null + ? StackTrace.fromString(json['stackTrace']) + : null, + ); + } + + @override + String toString() { + final emoji = _getEmojiForLevel(level); + final timestamp = this.timestamp.toIso8601String().substring(11, 23); + final dataStr = data != null ? ' | Data: ${jsonEncode(data)}' : ''; + final errorStr = error != null ? ' | Error: $error' : ''; + + return '$emoji [$timestamp] [$category] $message$dataStr$errorStr'; + } + + String _getEmojiForLevel(LogLevel level) { + switch (level) { + case LogLevel.debug: + return '🔍'; + case LogLevel.info: + return 'ℹ️'; + case LogLevel.warning: + return '⚠️'; + case LogLevel.error: + return '❌'; + case LogLevel.critical: + return '🚨'; + } + } +} diff --git a/lib/connection/connection_manager.dart b/lib/connection/connection_manager.dart new file mode 100644 index 0000000..9e1e4eb --- /dev/null +++ b/lib/connection/connection_manager.dart @@ -0,0 +1,652 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:web_socket_channel/io.dart'; +import 'package:web_socket_channel/status.dart' as status; + +import 'connection_logger.dart'; +import 'connection_state.dart'; +import 'retry_strategy.dart'; +import 'health_monitor.dart'; + + +class ConnectionManager { + static final ConnectionManager _instance = ConnectionManager._internal(); + factory ConnectionManager() => _instance; + ConnectionManager._internal(); + + + final ConnectionLogger _logger = ConnectionLogger(); + final ConnectionStateManager _stateManager = ConnectionStateManager(); + final RetryManager _retryManager = RetryManager(); + final HealthMonitor _healthMonitor = HealthMonitor(); + + + IOWebSocketChannel? _channel; + StreamSubscription? _messageSubscription; + + + final List _serverUrls = [ + 'wss://ws-api.oneme.ru:443/websocket', + 'wss://ws-api.oneme.ru/websocket', + 'wss://ws-api.oneme.ru:8443/websocket', + 'ws://ws-api.oneme.ru:80/websocket', + 'ws://ws-api.oneme.ru/websocket', + 'ws://ws-api.oneme.ru:8080/websocket', + ]; + + int _currentUrlIndex = 0; + String? _currentServerUrl; + + + bool _isConnecting = false; + bool _isDisposed = false; + int _sequenceNumber = 0; + String? _authToken; + + + final List> _messageQueue = []; + + + Timer? _pingTimer; + Timer? _reconnectTimer; + + + final StreamController> _messageController = + StreamController>.broadcast(); + final StreamController _connectionStatusController = + StreamController.broadcast(); + + + Stream> get messageStream => _messageController.stream; + + + Stream get connectionStatusStream => + _connectionStatusController.stream; + + + Stream get stateStream => _stateManager.stateStream; + + + Stream get logStream => _logger.logStream; + + + Stream get healthMetricsStream => _healthMonitor.metricsStream; + + + ConnectionInfo get currentState => _stateManager.currentInfo; + + + bool get isConnected => currentState.isActive; + + + bool get canSendMessages => currentState.canSendMessages; + + + Future initialize() async { + if (_isDisposed) { + _logger.logError('Попытка инициализации после dispose'); + return; + } + + _logger.logConnection('Инициализация ConnectionManager'); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Инициализация', + ); + } + + Future _fullReconnect() async { + _logger.logConnection('Начинаем полное переподключение'); + + + _cleanup(); + _stopMonitoring(); // Убедимся, что все таймеры точно остановлены + + + _currentUrlIndex = 0; + _sequenceNumber = 0; + _messageQueue.clear(); + + + _stateManager.setState( + ConnectionState.disconnected, + message: 'Подготовка к переподключению', + ); + + + await Future.delayed(const Duration(milliseconds: 250)); + + + await connect(authToken: _authToken); + } + + + Future connect({String? authToken}) async { + if (_isDisposed) { + _logger.logError('Попытка подключения после dispose'); + return; + } + + if (_isConnecting) { + _logger.logConnection('Подключение уже в процессе'); + return; + } + + _authToken = authToken; + _isConnecting = true; + + _logger.logConnection( + 'Начало подключения', + data: { + 'auth_token_present': authToken != null, + 'server_count': _serverUrls.length, + }, + ); + + _stateManager.setState( + ConnectionState.connecting, + message: 'Подключение к серверу', + attemptNumber: 1, + ); + + try { + await _connectWithFallback(); + } catch (e) { + _logger.logError('Ошибка подключения', error: e); + _stateManager.setState( + ConnectionState.error, + message: 'Ошибка подключения: ${e.toString()}', + ); + rethrow; + } finally { + _isConnecting = false; + } + } + + + Future _connectWithFallback() async { + final sessionId = 'connect_${DateTime.now().millisecondsSinceEpoch}'; + final session = _retryManager.startSession(sessionId, ErrorType.network); + + while (_currentUrlIndex < _serverUrls.length) { + final url = _serverUrls[_currentUrlIndex]; + _currentServerUrl = url; + + _logger.logConnection( + 'Попытка подключения', + data: { + 'url': url, + 'attempt': _currentUrlIndex + 1, + 'total_servers': _serverUrls.length, + }, + ); + + try { + await _connectToUrl(url); + + _logger.logConnection( + 'Успешное подключение', + data: {'url': url, 'server_index': _currentUrlIndex}, + ); + + _stateManager.setState( + ConnectionState.connected, + message: 'Подключен к серверу', + serverUrl: url, + ); + + _healthMonitor.startMonitoring(serverUrl: url); + _retryManager.endSession(sessionId); + return; + } catch (e) { + final errorInfo = ErrorInfo( + type: _getErrorType(e), + message: e.toString(), + timestamp: DateTime.now(), + ); + + session.addAttempt(errorInfo.type, message: e.toString()); + + _logger.logError( + 'Ошибка подключения к серверу', + data: { + 'url': url, + 'error': e.toString(), + 'error_type': errorInfo.type.name, + }, + ); + + _currentUrlIndex++; + + if (_currentUrlIndex < _serverUrls.length) { + final delay = Duration(milliseconds: 500); + _logger.logConnection( + 'Переход к следующему серверу через ${delay.inMilliseconds}ms', + ); + await Future.delayed(delay); + } + } + } + + + _logger.logError( + 'Все серверы недоступны', + data: {'total_servers': _serverUrls.length}, + ); + + _stateManager.setState( + ConnectionState.error, + message: 'Все серверы недоступны', + ); + + throw Exception('Не удалось подключиться ни к одному серверу'); + } + + + Future _connectToUrl(String url) async { + final uri = Uri.parse(url); + + _logger.logConnection( + 'Подключение к URL', + data: {'host': uri.host, 'port': uri.port, 'scheme': uri.scheme}, + ); + + + final headers = { + 'Origin': 'https://web.max.ru', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Sec-WebSocket-Extensions': 'permessage-deflate', + }; + + _channel = IOWebSocketChannel.connect(uri, headers: headers); + await _channel!.ready; + + _logger.logConnection('WebSocket канал готов'); + + _setupMessageListener(); + await _sendHandshake(); + _startPingTimer(); + } + + + void _setupMessageListener() { + _messageSubscription?.cancel(); + + _messageSubscription = _channel!.stream.listen( + _handleMessage, + onError: _handleError, + onDone: _handleDisconnection, + cancelOnError: true, + ); + + _logger.logConnection('Слушатель сообщений настроен'); + } + + + void _handleMessage(dynamic message) { + if (message == null || (message is String && message.trim().isEmpty)) { + return; + } + + try { + _logger.logMessage('IN', message); + + final decodedMessage = message is String ? jsonDecode(message) : message; + + + if (decodedMessage is Map && decodedMessage['opcode'] == 1) { + _healthMonitor.onPongReceived(); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 6 && + decodedMessage['cmd'] == 1) { + _handleHandshakeSuccess(Map.from(decodedMessage)); + return; + } + + + if (decodedMessage is Map && decodedMessage['cmd'] == 3) { + _handleServerError(Map.from(decodedMessage)); + return; + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 97 && + decodedMessage['cmd'] == 1) { + _handleSessionTermination(); + return; + } + + _messageController.add(decodedMessage); + } catch (e) { + _logger.logError( + 'Ошибка обработки сообщения', + data: {'message': message.toString(), 'error': e.toString()}, + ); + } + } + + + void _handleHandshakeSuccess(Map message) { + _logger.logConnection( + 'Handshake успешен', + data: {'payload': message['payload']}, + ); + + _stateManager.setState( + ConnectionState.ready, + message: 'Сессия готова к работе', + ); + + _processMessageQueue(); + } + + + void _handleServerError(Map message) { + final error = message['payload']; + _logger.logError('Ошибка сервера', data: {'error': error}); + + if (error != null) { + if (error['error'] == 'proto.state') { + _logger.logConnection('Ошибка состояния сессии, переподключаемся'); + _scheduleReconnect('Ошибка состояния сессии'); + } else if (error['error'] == 'login.token') { + _logger.logConnection('Недействительный токен'); + _handleInvalidToken(); + } + } + } + + + void _handleSessionTermination() { + _logger.logConnection('Сессия завершена сервером'); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Сессия завершена сервером', + ); + _clearAuthData(); + } + + + void _handleInvalidToken() { + _logger.logConnection('Обработка недействительного токена'); + _clearAuthData(); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Требуется повторная авторизация', + ); + } + + + void _clearAuthData() { + _authToken = null; + _logger.logConnection('Данные аутентификации очищены'); + } + + + void _handleError(dynamic error) { + _logger.logError('Ошибка WebSocket', error: error); + _healthMonitor.onError(error.toString()); + _scheduleReconnect('Ошибка WebSocket: $error'); + } + + + void _handleDisconnection() { + _logger.logConnection('WebSocket соединение закрыто'); + _healthMonitor.onReconnect(); + _scheduleReconnect('Соединение закрыто'); + } + + + void _scheduleReconnect(String reason) { + if (_isDisposed) return; + + _reconnectTimer?.cancel(); + + final sessionId = 'reconnect_${DateTime.now().millisecondsSinceEpoch}'; + final session = _retryManager.startSession(sessionId, ErrorType.network); + + if (!session.canRetry()) { + _logger.logError( + 'Превышено максимальное количество попыток переподключения', + ); + _stateManager.setState( + ConnectionState.error, + message: 'Не удалось переподключиться', + ); + return; + } + + final delay = session.getNextDelay(); + + _logger.logReconnect(session.attemptCount + 1, reason, delay: delay); + + _stateManager.setState( + ConnectionState.reconnecting, + message: 'Переподключение через ${delay.inSeconds}с', + reconnectDelay: delay, + ); + + _reconnectTimer = Timer(delay, () async { + try { + + await _fullReconnect(); + } catch (e) { + _logger.logError('Ошибка во время полного переподключения', error: e); + + _scheduleReconnect('Ошибка при попытке полного переподключения'); + } + }); + } + + + Future _sendHandshake() async { + _logger.logConnection('Отправка handshake'); + + final payload = { + "userAgent": { + "deviceType": "WEB", + "locale": "ru", + "deviceLocale": "ru", + "osVersion": "Windows", + "deviceName": "Chrome", + "headerUserAgent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "appVersion": "25.9.15", + "screen": "1920x1080 1.0x", + "timezone": "Europe/Moscow", + }, + "deviceId": _generateDeviceId(), + }; + + _sendMessage(6, payload); + } + + + int _sendMessage(int opcode, Map payload) { + if (_channel == null) { + _logger.logError('WebSocket не подключен'); + return -1; + } + + final message = { + "ver": 11, + "cmd": 0, + "seq": _sequenceNumber, + "opcode": opcode, + "payload": payload, + }; + + final encodedMessage = jsonEncode(message); + _logger.logMessage('OUT', encodedMessage); + + _channel!.sink.add(encodedMessage); + return _sequenceNumber++; + } + + + int sendMessage(int opcode, Map payload) { + if (!canSendMessages) { + _logger.logConnection( + 'Сообщение добавлено в очередь', + data: {'opcode': opcode, 'reason': 'Соединение не готово'}, + ); + _messageQueue.add({'opcode': opcode, 'payload': payload}); + return -1; + } + + return _sendMessage(opcode, payload); + } + + + void _processMessageQueue() { + if (_messageQueue.isEmpty) return; + + _logger.logConnection( + 'Обработка очереди сообщений', + data: {'count': _messageQueue.length}, + ); + + for (final message in _messageQueue) { + _sendMessage(message['opcode'], message['payload']); + } + + _messageQueue.clear(); + } + + + void _startPingTimer() { + _pingTimer?.cancel(); + _pingTimer = Timer.periodic(const Duration(seconds: 25), (_) { + if (canSendMessages) { + _logger.logConnection('Отправка ping'); + _sendMessage(1, {"interactive": true}); + } + }); + } + + + String _generateDeviceId() { + final timestamp = DateTime.now().millisecondsSinceEpoch; + final random = (timestamp % 1000000).toString().padLeft(6, '0'); + return "$timestamp$random"; + } + + + ErrorType _getErrorType(dynamic error) { + final errorString = error.toString().toLowerCase(); + + if (errorString.contains('timeout') || + errorString.contains('connection') || + errorString.contains('network')) { + return ErrorType.network; + } + + if (errorString.contains('unauthorized') || + errorString.contains('forbidden')) { + return ErrorType.authentication; + } + + if (errorString.contains('server') || errorString.contains('internal')) { + return ErrorType.server; + } + + return ErrorType.unknown; + } + + + Future disconnect() async { + _logger.logConnection('Отключение'); + + _stateManager.setState( + ConnectionState.disconnected, + message: 'Отключение по запросу', + ); + + _stopMonitoring(); + _cleanup(); + } + + + Future forceReconnect() async { + if (_isDisposed) { + _logger.logError('Попытка переподключения после dispose'); + return; + } + + _logger.logConnection('Принудительное переподключение'); + + + _reconnectTimer?.cancel(); + _pingTimer?.cancel(); + + + _cleanup(); + _currentUrlIndex = 0; + _sequenceNumber = 0; + _messageQueue.clear(); + + + _stateManager.setState( + ConnectionState.disconnected, + message: 'Подготовка к переподключению', + ); + + + await Future.delayed(const Duration(milliseconds: 500)); + + + await connect(authToken: _authToken); + } + + + void _stopMonitoring() { + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + _messageSubscription?.cancel(); + _healthMonitor.stopMonitoring(); + } + + + void _cleanup() { + _channel?.sink.close(status.goingAway); + _channel = null; + _messageQueue.clear(); + _currentUrlIndex = 0; + _sequenceNumber = 0; + } + + + Map getStatistics() { + return { + 'connection_state': currentState.state.name, + 'health_metrics': _healthMonitor.getStatistics(), + 'retry_statistics': _retryManager.getStatistics(), + 'log_statistics': _logger.getLogStats(), + 'message_queue_size': _messageQueue.length, + 'current_server': _currentServerUrl, + 'server_index': _currentUrlIndex, + }; + } + + + void dispose() { + if (_isDisposed) return; + + _logger.logConnection('Освобождение ресурсов ConnectionManager'); + + _isDisposed = true; + _stopMonitoring(); + _cleanup(); + + _messageController.close(); + _connectionStatusController.close(); + _stateManager.dispose(); + _logger.dispose(); + _healthMonitor.dispose(); + } +} diff --git a/lib/connection/connection_manager_simple.dart b/lib/connection/connection_manager_simple.dart new file mode 100644 index 0000000..59fdad7 --- /dev/null +++ b/lib/connection/connection_manager_simple.dart @@ -0,0 +1,684 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:web_socket_channel/io.dart'; +import 'package:web_socket_channel/status.dart' as status; + +import 'connection_logger.dart'; +import 'connection_state.dart'; +import 'retry_strategy.dart'; +import 'health_monitor.dart'; + + +class ConnectionManagerSimple { + static final ConnectionManagerSimple _instance = + ConnectionManagerSimple._internal(); + factory ConnectionManagerSimple() => _instance; + ConnectionManagerSimple._internal(); + + + final ConnectionLogger _logger = ConnectionLogger(); + final ConnectionStateManager _stateManager = ConnectionStateManager(); + final RetryManager _retryManager = RetryManager(); + final HealthMonitor _healthMonitor = HealthMonitor(); + + + IOWebSocketChannel? _channel; + StreamSubscription? _messageSubscription; + + + final List _serverUrls = [ + 'wss://ws-api.oneme.ru:443/websocket', + 'wss://ws-api.oneme.ru/websocket', + 'wss://ws-api.oneme.ru:8443/websocket', + 'ws://ws-api.oneme.ru:80/websocket', + 'ws://ws-api.oneme.ru/websocket', + 'ws://ws-api.oneme.ru:8080/websocket', + ]; + + int _currentUrlIndex = 0; + String? _currentServerUrl; + + + bool _isConnecting = false; + bool _isDisposed = false; + int _sequenceNumber = 0; + String? _authToken; + + + final List> _messageQueue = []; + + + Timer? _pingTimer; + Timer? _reconnectTimer; + Timer? _responseTimeoutTimer; + Timer? _connectionTimeoutTimer; + + + final StreamController> _messageController = + StreamController>.broadcast(); + final StreamController _connectionStatusController = + StreamController.broadcast(); + + + Stream> get messageStream => _messageController.stream; + + + Stream get connectionStatusStream => + _connectionStatusController.stream; + + + Stream get stateStream => _stateManager.stateStream; + + + Stream get logStream => _logger.logStream; + + + Stream get healthMetricsStream => _healthMonitor.metricsStream; + + + ConnectionInfo get currentState => _stateManager.currentInfo; + + + bool get isConnected => currentState.isActive; + + + bool get canSendMessages => currentState.canSendMessages; + + + Future initialize() async { + if (_isDisposed) { + _logger.logError('Попытка инициализации после dispose'); + return; + } + + _logger.logConnection('Инициализация ConnectionManagerSimple'); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Инициализация', + ); + } + + + Future connect({String? authToken}) async { + if (_isDisposed) { + _logger.logError('Попытка подключения после dispose'); + return; + } + + if (_isConnecting) { + _logger.logConnection('Подключение уже в процессе'); + return; + } + + _authToken = authToken; + _isConnecting = true; + + _logger.logConnection( + 'Начало подключения', + data: { + 'auth_token_present': authToken != null, + 'server_count': _serverUrls.length, + }, + ); + + _stateManager.setState( + ConnectionState.connecting, + message: 'Подключение к серверу', + attemptNumber: 1, + ); + + try { + await _connectWithFallback(); + } catch (e) { + _logger.logError('Ошибка подключения', error: e); + _stateManager.setState( + ConnectionState.error, + message: 'Ошибка подключения: ${e.toString()}', + ); + rethrow; + } finally { + _isConnecting = false; + } + } + + + Future _connectWithFallback() async { + final sessionId = 'connect_${DateTime.now().millisecondsSinceEpoch}'; + final session = _retryManager.startSession(sessionId, ErrorType.network); + + while (_currentUrlIndex < _serverUrls.length) { + final url = _serverUrls[_currentUrlIndex]; + _currentServerUrl = url; + + _logger.logConnection( + 'Попытка подключения', + data: { + 'url': url, + 'attempt': _currentUrlIndex + 1, + 'total_servers': _serverUrls.length, + }, + ); + + try { + await _connectToUrl(url); + + _logger.logConnection( + 'Успешное подключение', + data: {'url': url, 'server_index': _currentUrlIndex}, + ); + + _stateManager.setState( + ConnectionState.connected, + message: 'Подключен к серверу', + serverUrl: url, + ); + + _healthMonitor.startMonitoring(serverUrl: url); + _retryManager.endSession(sessionId); + return; + } catch (e) { + final errorInfo = ErrorInfo( + type: _getErrorType(e), + message: e.toString(), + timestamp: DateTime.now(), + ); + + session.addAttempt(errorInfo.type, message: e.toString()); + + _logger.logError( + 'Ошибка подключения к серверу', + data: { + 'url': url, + 'error': e.toString(), + 'error_type': errorInfo.type.name, + }, + ); + + _currentUrlIndex++; + + if (_currentUrlIndex < _serverUrls.length) { + final delay = Duration(milliseconds: 500); + _logger.logConnection( + 'Переход к следующему серверу через ${delay.inMilliseconds}ms', + ); + await Future.delayed(delay); + } + } + } + + + _logger.logError( + 'Все серверы недоступны', + data: {'total_servers': _serverUrls.length}, + ); + + _stateManager.setState( + ConnectionState.error, + message: 'Все серверы недоступны', + ); + + throw Exception('Не удалось подключиться ни к одному серверу'); + } + + + Future _connectToUrl(String url) async { + final uri = Uri.parse(url); + + _logger.logConnection( + 'Подключение к URL', + data: {'host': uri.host, 'port': uri.port, 'scheme': uri.scheme}, + ); + + + final headers = { + 'Origin': 'https://web.max.ru', + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Sec-WebSocket-Extensions': 'permessage-deflate', + }; + + _channel = IOWebSocketChannel.connect(uri, headers: headers); + + + _connectionTimeoutTimer = Timer(const Duration(seconds: 10), () { + _logger.logError('Таймаут подключения к серверу'); + _handleConnectionTimeout(); + }); + + await _channel!.ready; + _connectionTimeoutTimer?.cancel(); + + _logger.logConnection('WebSocket канал готов'); + + _setupMessageListener(); + await _sendHandshake(); + _startPingTimer(); + } + + + void _setupMessageListener() { + _messageSubscription?.cancel(); + + _messageSubscription = _channel!.stream.listen( + _handleMessage, + onError: _handleError, + onDone: _handleDisconnection, + cancelOnError: true, + ); + + _logger.logConnection('Слушатель сообщений настроен'); + } + + + void _handleMessage(dynamic message) { + if (message == null || (message is String && message.trim().isEmpty)) { + return; + } + + try { + _logger.logMessage('IN', message); + + final decodedMessage = message is String ? jsonDecode(message) : message; + + + if (decodedMessage is Map && decodedMessage['opcode'] == 1) { + _healthMonitor.onPongReceived(); + + _responseTimeoutTimer?.cancel(); + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 6 && + decodedMessage['cmd'] == 1) { + _handleHandshakeSuccess(Map.from(decodedMessage)); + return; + } + + + if (decodedMessage is Map && decodedMessage['cmd'] == 3) { + _handleServerError(Map.from(decodedMessage)); + return; + } + + + if (decodedMessage is Map && + decodedMessage['opcode'] == 97 && + decodedMessage['cmd'] == 1) { + _handleSessionTermination(); + return; + } + + _messageController.add(decodedMessage); + } catch (e) { + _logger.logError( + 'Ошибка обработки сообщения', + data: {'message': message.toString(), 'error': e.toString()}, + ); + } + } + + + void _handleHandshakeSuccess(Map message) { + _logger.logConnection( + 'Handshake успешен', + data: {'payload': message['payload']}, + ); + + + _responseTimeoutTimer?.cancel(); + + _stateManager.setState( + ConnectionState.ready, + message: 'Сессия готова к работе', + ); + + _processMessageQueue(); + } + + + void _handleServerError(Map message) { + final error = message['payload']; + _logger.logError('Ошибка сервера', data: {'error': error}); + + if (error != null) { + if (error['error'] == 'proto.state') { + _logger.logConnection('Ошибка состояния сессии, переподключаемся'); + _scheduleReconnect('Ошибка состояния сессии'); + } else if (error['error'] == 'login.token') { + _logger.logConnection('Недействительный токен'); + _handleInvalidToken(); + } + } + } + + + void _handleSessionTermination() { + _logger.logConnection('Сессия завершена сервером'); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Сессия завершена сервером', + ); + _clearAuthData(); + } + + + void _handleInvalidToken() { + _logger.logConnection('Обработка недействительного токена'); + _clearAuthData(); + _stateManager.setState( + ConnectionState.disconnected, + message: 'Требуется повторная авторизация', + ); + } + + + void _handleConnectionTimeout() { + _logger.logError('Таймаут подключения к серверу'); + _stateManager.setState( + ConnectionState.error, + message: 'Таймаут подключения', + ); + _scheduleReconnect('Таймаут подключения'); + } + + + void _handleResponseTimeout() { + _logger.logError('Таймаут ответа от сервера'); + _stateManager.setState( + ConnectionState.error, + message: 'Сервер не отвечает', + ); + _scheduleReconnect('Сервер не отвечает'); + } + + + void _clearAuthData() { + _authToken = null; + _logger.logConnection('Данные аутентификации очищены'); + } + + + void _handleError(dynamic error) { + _logger.logError('Ошибка WebSocket', error: error); + _healthMonitor.onError(error.toString()); + _scheduleReconnect('Ошибка WebSocket: $error'); + } + + + void _handleDisconnection() { + _logger.logConnection('WebSocket соединение закрыто'); + _healthMonitor.onReconnect(); + _scheduleReconnect('Соединение закрыто'); + } + + + void _scheduleReconnect(String reason) { + if (_isDisposed) return; + + _reconnectTimer?.cancel(); + + final sessionId = 'reconnect_${DateTime.now().millisecondsSinceEpoch}'; + final session = _retryManager.startSession(sessionId, ErrorType.network); + + if (!session.canRetry()) { + _logger.logError( + 'Превышено максимальное количество попыток переподключения', + ); + _stateManager.setState( + ConnectionState.error, + message: 'Не удалось переподключиться', + ); + return; + } + + final delay = session.getNextDelay(); + + _logger.logReconnect(session.attemptCount + 1, reason, delay: delay); + + _stateManager.setState( + ConnectionState.reconnecting, + message: 'Переподключение через ${delay.inSeconds}с', + reconnectDelay: delay, + ); + + _reconnectTimer = Timer(delay, () async { + try { + + await _fullReconnect(); + } catch (e) { + _logger.logError('Ошибка переподключения', error: e); + } + }); + } + + + Future _fullReconnect() async { + _logger.logConnection('Начинаем полное переподключение'); + + + _cleanup(); + _currentUrlIndex = 0; + _sequenceNumber = 0; + _messageQueue.clear(); + + + _stateManager.setState( + ConnectionState.disconnected, + message: 'Подготовка к переподключению', + ); + + + await Future.delayed(const Duration(milliseconds: 500)); + + + await connect(authToken: _authToken); + } + + + Future _sendHandshake() async { + _logger.logConnection('Отправка handshake'); + + final payload = { + "userAgent": { + "deviceType": "WEB", + "locale": "ru", + "deviceLocale": "ru", + "osVersion": "Windows", + "deviceName": "Chrome", + "headerUserAgent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "appVersion": "25.9.15", + "screen": "1920x1080 1.0x", + "timezone": "Europe/Moscow", + }, + "deviceId": _generateDeviceId(), + }; + + _sendMessage(6, payload); + + + _responseTimeoutTimer = Timer(const Duration(seconds: 15), () { + _logger.logError('Таймаут ответа от сервера на handshake'); + _handleResponseTimeout(); + }); + } + + + int _sendMessage(int opcode, Map payload) { + if (_channel == null) { + _logger.logError('WebSocket не подключен'); + return -1; + } + + final message = { + "ver": 11, + "cmd": 0, + "seq": _sequenceNumber, + "opcode": opcode, + "payload": payload, + }; + + final encodedMessage = jsonEncode(message); + _logger.logMessage('OUT', encodedMessage); + + _channel!.sink.add(encodedMessage); + return _sequenceNumber++; + } + + + int sendMessage(int opcode, Map payload) { + if (!canSendMessages) { + _logger.logConnection( + 'Сообщение добавлено в очередь', + data: {'opcode': opcode, 'reason': 'Соединение не готово'}, + ); + _messageQueue.add({'opcode': opcode, 'payload': payload}); + return -1; + } + + return _sendMessage(opcode, payload); + } + + + void _processMessageQueue() { + if (_messageQueue.isEmpty) return; + + _logger.logConnection( + 'Обработка очереди сообщений', + data: {'count': _messageQueue.length}, + ); + + for (final message in _messageQueue) { + _sendMessage(message['opcode'], message['payload']); + } + + _messageQueue.clear(); + } + + + void _startPingTimer() { + _pingTimer?.cancel(); + _pingTimer = Timer.periodic(const Duration(seconds: 25), (_) { + if (canSendMessages) { + _logger.logConnection('Отправка ping'); + _sendMessage(1, {"interactive": true}); + + + _responseTimeoutTimer?.cancel(); + _responseTimeoutTimer = Timer(const Duration(seconds: 10), () { + _logger.logError('Таймаут pong ответа от сервера'); + _handleResponseTimeout(); + }); + } + }); + } + + + String _generateDeviceId() { + final timestamp = DateTime.now().millisecondsSinceEpoch; + final random = (timestamp % 1000000).toString().padLeft(6, '0'); + return "$timestamp$random"; + } + + + ErrorType _getErrorType(dynamic error) { + final errorString = error.toString().toLowerCase(); + + if (errorString.contains('timeout') || + errorString.contains('connection') || + errorString.contains('network')) { + return ErrorType.network; + } + + if (errorString.contains('unauthorized') || + errorString.contains('forbidden')) { + return ErrorType.authentication; + } + + if (errorString.contains('server') || errorString.contains('internal')) { + return ErrorType.server; + } + + return ErrorType.unknown; + } + + + Future disconnect() async { + _logger.logConnection('Отключение'); + + _stateManager.setState( + ConnectionState.disconnected, + message: 'Отключение по запросу', + ); + + _stopMonitoring(); + _cleanup(); + } + + + Future forceReconnect() async { + if (_isDisposed) { + _logger.logError('Попытка переподключения после dispose'); + return; + } + + _logger.logConnection('Принудительное переподключение'); + + + _reconnectTimer?.cancel(); + _pingTimer?.cancel(); + + + await _fullReconnect(); + } + + + void _stopMonitoring() { + _pingTimer?.cancel(); + _reconnectTimer?.cancel(); + _responseTimeoutTimer?.cancel(); + _connectionTimeoutTimer?.cancel(); + _messageSubscription?.cancel(); + _healthMonitor.stopMonitoring(); + } + + + void _cleanup() { + _channel?.sink.close(status.goingAway); + _channel = null; + _messageQueue.clear(); + _currentUrlIndex = 0; + _sequenceNumber = 0; + } + + + Map getStatistics() { + return { + 'connection_state': currentState.state.name, + 'health_metrics': _healthMonitor.getStatistics(), + 'retry_statistics': _retryManager.getStatistics(), + 'log_statistics': _logger.getLogStats(), + 'message_queue_size': _messageQueue.length, + 'current_server': _currentServerUrl, + 'server_index': _currentUrlIndex, + }; + } + + + void dispose() { + if (_isDisposed) return; + + _logger.logConnection('Освобождение ресурсов ConnectionManagerSimple'); + + _isDisposed = true; + _stopMonitoring(); + _cleanup(); + + _messageController.close(); + _connectionStatusController.close(); + _stateManager.dispose(); + _logger.dispose(); + _healthMonitor.dispose(); + } +} diff --git a/lib/connection/connection_state.dart b/lib/connection/connection_state.dart new file mode 100644 index 0000000..487df7f --- /dev/null +++ b/lib/connection/connection_state.dart @@ -0,0 +1,283 @@ +import 'dart:async'; + + +enum ConnectionState { + + disconnected, + + + connecting, + + + connected, + + + ready, + + + reconnecting, + + + error, + + + disabled, +} + + +class ConnectionInfo { + final ConnectionState state; + final DateTime timestamp; + final String? message; + final Map? metadata; + final int? attemptNumber; + final Duration? reconnectDelay; + final String? serverUrl; + final int? latency; + + ConnectionInfo({ + required this.state, + required this.timestamp, + this.message, + this.metadata, + this.attemptNumber, + this.reconnectDelay, + this.serverUrl, + this.latency, + }); + + ConnectionInfo copyWith({ + ConnectionState? state, + DateTime? timestamp, + String? message, + Map? metadata, + int? attemptNumber, + Duration? reconnectDelay, + String? serverUrl, + int? latency, + }) { + return ConnectionInfo( + state: state ?? this.state, + timestamp: timestamp ?? this.timestamp, + message: message ?? this.message, + metadata: metadata ?? this.metadata, + attemptNumber: attemptNumber ?? this.attemptNumber, + reconnectDelay: reconnectDelay ?? this.reconnectDelay, + serverUrl: serverUrl ?? this.serverUrl, + latency: latency ?? this.latency, + ); + } + + + bool get isActive => + state == ConnectionState.ready || state == ConnectionState.connected; + + + bool get canSendMessages => state == ConnectionState.ready; + + + bool get isConnecting => + state == ConnectionState.connecting || + state == ConnectionState.reconnecting; + + + bool get hasError => state == ConnectionState.error; + + + bool get isDisconnected => + state == ConnectionState.disconnected || + state == ConnectionState.disabled; + + @override + String toString() { + final buffer = StringBuffer(); + buffer.write('ConnectionInfo(state: $state'); + if (message != null) buffer.write(', message: $message'); + if (attemptNumber != null) buffer.write(', attempt: $attemptNumber'); + if (serverUrl != null) buffer.write(', server: $serverUrl'); + if (latency != null) buffer.write(', latency: ${latency}ms'); + buffer.write(')'); + return buffer.toString(); + } +} + + +class ConnectionStateManager { + static final ConnectionStateManager _instance = + ConnectionStateManager._internal(); + factory ConnectionStateManager() => _instance; + ConnectionStateManager._internal(); + + ConnectionInfo _currentInfo = ConnectionInfo( + state: ConnectionState.disconnected, + timestamp: DateTime.now(), + ); + + final StreamController _stateController = + StreamController.broadcast(); + + + ConnectionInfo get currentInfo => _currentInfo; + + + Stream get stateStream => _stateController.stream; + + + final List _stateHistory = []; + + + List get stateHistory => List.unmodifiable(_stateHistory); + + + void setState( + ConnectionState newState, { + String? message, + Map? metadata, + int? attemptNumber, + Duration? reconnectDelay, + String? serverUrl, + int? latency, + }) { + final oldState = _currentInfo.state; + final newInfo = _currentInfo.copyWith( + state: newState, + timestamp: DateTime.now(), + message: message, + metadata: metadata, + attemptNumber: attemptNumber, + reconnectDelay: reconnectDelay, + serverUrl: serverUrl, + latency: latency, + ); + + _currentInfo = newInfo; + _addToHistory(newInfo); + _stateController.add(newInfo); + + + _logStateChange(oldState, newState, message); + } + + + void updateMetadata(Map metadata) { + final updatedInfo = _currentInfo.copyWith( + metadata: {...?(_currentInfo.metadata), ...metadata}, + ); + _currentInfo = updatedInfo; + _stateController.add(updatedInfo); + } + + + void updateReconnectDelay(Duration delay) { + final updatedInfo = _currentInfo.copyWith(reconnectDelay: delay); + _currentInfo = updatedInfo; + _stateController.add(updatedInfo); + } + + + void updateLatency(int latencyMs) { + final updatedInfo = _currentInfo.copyWith(latency: latencyMs); + _currentInfo = updatedInfo; + _stateController.add(updatedInfo); + } + + + Duration get timeInCurrentState { + return DateTime.now().difference(_currentInfo.timestamp); + } + + + int get connectionAttempts { + return _stateHistory + .where((info) => info.state == ConnectionState.connecting) + .length; + } + + + int get errorCount { + return _stateHistory + .where((info) => info.state == ConnectionState.error) + .length; + } + + + double get averageLatency { + final latencies = _stateHistory + .where((info) => info.latency != null) + .map((info) => info.latency!) + .toList(); + + if (latencies.isEmpty) return 0.0; + return latencies.reduce((a, b) => a + b) / latencies.length; + } + + + Map get stateStatistics { + final stats = {}; + for (final info in _stateHistory) { + stats[info.state] = (stats[info.state] ?? 0) + 1; + } + return stats; + } + + + List getLastStates(int count) { + final start = _stateHistory.length - count; + return _stateHistory.sublist(start < 0 ? 0 : start); + } + + + void clearHistory() { + _stateHistory.clear(); + } + + + void reset() { + setState(ConnectionState.disconnected, message: 'Состояние сброшено'); + clearHistory(); + } + + void _addToHistory(ConnectionInfo info) { + _stateHistory.add(info); + + + if (_stateHistory.length > 50) { + _stateHistory.removeAt(0); + } + } + + void _logStateChange( + ConnectionState from, + ConnectionState to, + String? message, + ) { + final fromStr = _getStateDisplayName(from); + final toStr = _getStateDisplayName(to); + final messageStr = message != null ? ' ($message)' : ''; + + print('🔄 Состояние подключения: $fromStr → $toStr$messageStr'); + } + + String _getStateDisplayName(ConnectionState state) { + switch (state) { + case ConnectionState.disconnected: + return 'Отключен'; + case ConnectionState.connecting: + return 'Подключение'; + case ConnectionState.connected: + return 'Подключен'; + case ConnectionState.ready: + return 'Готов'; + case ConnectionState.reconnecting: + return 'Переподключение'; + case ConnectionState.error: + return 'Ошибка'; + case ConnectionState.disabled: + return 'Отключен'; + } + } + + void dispose() { + _stateController.close(); + } +} diff --git a/lib/connection/health_monitor.dart b/lib/connection/health_monitor.dart new file mode 100644 index 0000000..77566c0 --- /dev/null +++ b/lib/connection/health_monitor.dart @@ -0,0 +1,331 @@ +import 'dart:async'; +import 'dart:math'; + + +class HealthMetrics { + final int latency; + final int packetLoss; + final int connectionUptime; + final int reconnects; + final int errors; + final DateTime timestamp; + final String? serverUrl; + + HealthMetrics({ + required this.latency, + required this.packetLoss, + required this.connectionUptime, + required this.reconnects, + required this.errors, + required this.timestamp, + this.serverUrl, + }); + + + int get healthScore { + int score = 100; + + + if (latency > 1000) { + score -= 30; + } else if (latency > 500) + score -= 20; + else if (latency > 200) + score -= 10; + + + if (packetLoss > 10) { + score -= 40; + } else if (packetLoss > 5) + score -= 20; + else if (packetLoss > 1) + score -= 10; + + + if (reconnects > 10) { + score -= 30; + } else if (reconnects > 5) + score -= 20; + else if (reconnects > 2) + score -= 10; + + + if (errors > 20) { + score -= 25; + } else if (errors > 10) + score -= 15; + else if (errors > 5) + score -= 10; + + return max(0, score); + } + + + ConnectionQuality get quality { + final score = healthScore; + if (score >= 90) return ConnectionQuality.excellent; + if (score >= 70) return ConnectionQuality.good; + if (score >= 50) return ConnectionQuality.fair; + if (score >= 30) return ConnectionQuality.poor; + return ConnectionQuality.critical; + } + + Map toJson() { + return { + 'latency': latency, + 'packet_loss': packetLoss, + 'connection_uptime': connectionUptime, + 'reconnects': reconnects, + 'errors': errors, + 'health_score': healthScore, + 'quality': quality.name, + 'timestamp': timestamp.toIso8601String(), + 'server_url': serverUrl, + }; + } +} + + +enum ConnectionQuality { excellent, good, fair, poor, critical } + + +class HealthMonitor { + static final HealthMonitor _instance = HealthMonitor._internal(); + factory HealthMonitor() => _instance; + HealthMonitor._internal(); + + final List _metricsHistory = []; + final StreamController _metricsController = + StreamController.broadcast(); + + Timer? _pingTimer; + Timer? _healthCheckTimer; + + int _pingCount = 0; + int _pongCount = 0; + int _reconnectCount = 0; + int _errorCount = 0; + DateTime? _connectionStartTime; + String? _currentServerUrl; + + + Stream get metricsStream => _metricsController.stream; + + + HealthMetrics? get currentMetrics => + _metricsHistory.isNotEmpty ? _metricsHistory.last : null; + + + List get metricsHistory => List.unmodifiable(_metricsHistory); + + + void startMonitoring({String? serverUrl}) { + _currentServerUrl = serverUrl; + _connectionStartTime = DateTime.now(); + _resetCounters(); + + + _pingTimer?.cancel(); + _pingTimer = Timer.periodic( + const Duration(seconds: 30), + (_) => _sendPing(), + ); + + + _healthCheckTimer?.cancel(); + _healthCheckTimer = Timer.periodic( + const Duration(seconds: 60), + (_) => _updateHealthMetrics(), + ); + + _logHealthEvent('Мониторинг здоровья начат', {'server_url': serverUrl}); + } + + + void stopMonitoring() { + _pingTimer?.cancel(); + _healthCheckTimer?.cancel(); + _logHealthEvent('Мониторинг здоровья остановлен'); + } + + + void onPongReceived() { + _pongCount++; + _logHealthEvent('Pong получен', {'pong_count': _pongCount}); + } + + + void onReconnect() { + _reconnectCount++; + _logHealthEvent('Переподключение', {'reconnect_count': _reconnectCount}); + } + + + void onError(String error) { + _errorCount++; + _logHealthEvent('Ошибка зафиксирована', { + 'error': error, + 'error_count': _errorCount, + }); + } + + + void _sendPing() { + _pingCount++; + _logHealthEvent('Ping отправлен', {'ping_count': _pingCount}); + } + + + void _updateHealthMetrics() { + final now = DateTime.now(); + final uptime = _connectionStartTime != null + ? now.difference(_connectionStartTime!).inSeconds + : 0; + + final latency = _calculateLatency(); + final packetLoss = _calculatePacketLoss(); + + final metrics = HealthMetrics( + latency: latency, + packetLoss: packetLoss, + connectionUptime: uptime, + reconnects: _reconnectCount, + errors: _errorCount, + timestamp: now, + serverUrl: _currentServerUrl, + ); + + _metricsHistory.add(metrics); + + + if (_metricsHistory.length > 100) { + _metricsHistory.removeAt(0); + } + + _metricsController.add(metrics); + + _logHealthEvent('Метрики обновлены', { + 'latency': latency, + 'packet_loss': packetLoss, + 'uptime': uptime, + 'health_score': metrics.healthScore, + 'quality': metrics.quality.name, + }); + } + + + int _calculateLatency() { + + if (_pingCount == 0) return 0; + + + final baseLatency = 50 + Random().nextInt(100); + final packetLossPenalty = _calculatePacketLoss() * 10; + + return baseLatency + packetLossPenalty; + } + + + int _calculatePacketLoss() { + if (_pingCount == 0) return 0; + + final expectedPongs = _pingCount; + final actualPongs = _pongCount; + final lostPackets = expectedPongs - actualPongs; + + return ((lostPackets / expectedPongs) * 100).round(); + } + + + HealthMetrics? getAverageMetrics({Duration? period}) { + if (_metricsHistory.isEmpty) return null; + + final cutoff = period != null + ? DateTime.now().subtract(period) + : DateTime.now().subtract(const Duration(hours: 1)); + + final recentMetrics = _metricsHistory + .where((m) => m.timestamp.isAfter(cutoff)) + .toList(); + + if (recentMetrics.isEmpty) return null; + + final avgLatency = + recentMetrics.map((m) => m.latency).reduce((a, b) => a + b) / + recentMetrics.length; + + final avgPacketLoss = + recentMetrics.map((m) => m.packetLoss).reduce((a, b) => a + b) / + recentMetrics.length; + + final totalReconnects = recentMetrics.last.reconnects; + final totalErrors = recentMetrics.last.errors; + final avgUptime = recentMetrics.last.connectionUptime; + + return HealthMetrics( + latency: avgLatency.round(), + packetLoss: avgPacketLoss.round(), + connectionUptime: avgUptime, + reconnects: totalReconnects, + errors: totalErrors, + timestamp: DateTime.now(), + serverUrl: _currentServerUrl, + ); + } + + + Map getStatistics() { + if (_metricsHistory.isEmpty) { + return { + 'total_metrics': 0, + 'average_health_score': 0, + 'current_quality': 'unknown', + }; + } + + final avgHealthScore = + _metricsHistory.map((m) => m.healthScore).reduce((a, b) => a + b) / + _metricsHistory.length; + + final qualityDistribution = {}; + for (final metrics in _metricsHistory) { + final quality = metrics.quality.name; + qualityDistribution[quality] = (qualityDistribution[quality] ?? 0) + 1; + } + + return { + 'total_metrics': _metricsHistory.length, + 'average_health_score': avgHealthScore.round(), + 'current_quality': _metricsHistory.last.quality.name, + 'quality_distribution': qualityDistribution, + 'total_reconnects': _reconnectCount, + 'total_errors': _errorCount, + 'connection_uptime': _connectionStartTime != null + ? DateTime.now().difference(_connectionStartTime!).inSeconds + : 0, + }; + } + + + void _resetCounters() { + _pingCount = 0; + _pongCount = 0; + _reconnectCount = 0; + _errorCount = 0; + } + + + void clearHistory() { + _metricsHistory.clear(); + _logHealthEvent('История метрик очищена'); + } + + void _logHealthEvent(String event, [Map? data]) { + print('🏥 HealthMonitor: $event${data != null ? ' | Data: $data' : ''}'); + } + + void dispose() { + stopMonitoring(); + _metricsController.close(); + } +} diff --git a/lib/connection/retry_strategy.dart b/lib/connection/retry_strategy.dart new file mode 100644 index 0000000..c4b10a0 --- /dev/null +++ b/lib/connection/retry_strategy.dart @@ -0,0 +1,339 @@ +import 'dart:math'; + + +enum ErrorType { + + network, + + + server, + + + authentication, + + + protocol, + + + unknown, +} + + +class ErrorInfo { + final ErrorType type; + final String message; + final int? httpStatusCode; + final DateTime timestamp; + final Map? metadata; + + ErrorInfo({ + required this.type, + required this.message, + this.httpStatusCode, + required this.timestamp, + this.metadata, + }); + + + static ErrorType getErrorTypeFromHttpStatus(int statusCode) { + if (statusCode >= 500) return ErrorType.server; + if (statusCode == 401 || statusCode == 403) return ErrorType.authentication; + if (statusCode >= 400) return ErrorType.protocol; + return ErrorType.network; + } + + + static ErrorType getErrorTypeFromMessage(String message) { + final lowerMessage = message.toLowerCase(); + + if (lowerMessage.contains('timeout') || + lowerMessage.contains('connection') || + lowerMessage.contains('network')) { + return ErrorType.network; + } + + if (lowerMessage.contains('unauthorized') || + lowerMessage.contains('forbidden') || + lowerMessage.contains('token')) { + return ErrorType.authentication; + } + + if (lowerMessage.contains('server') || lowerMessage.contains('internal')) { + return ErrorType.server; + } + + return ErrorType.unknown; + } +} + + +class RetryStrategy { + final int maxAttempts; + final Duration baseDelay; + final Duration maxDelay; + final double backoffMultiplier; + final double jitterFactor; + final Map errorConfigs; + + RetryStrategy({ + this.maxAttempts = 10, + this.baseDelay = const Duration(seconds: 1), + this.maxDelay = const Duration(minutes: 5), + this.backoffMultiplier = 2.0, + this.jitterFactor = 0.1, + Map? errorConfigs, + }) : errorConfigs = errorConfigs ?? _defaultErrorConfigs; + + static final Map _defaultErrorConfigs = { + ErrorType.network: RetryConfig( + maxAttempts: 15, + baseDelay: Duration(seconds: 2), + maxDelay: Duration(minutes: 10), + backoffMultiplier: 1.5, + ), + ErrorType.server: RetryConfig( + maxAttempts: 8, + baseDelay: Duration(seconds: 5), + maxDelay: Duration(minutes: 3), + backoffMultiplier: 2.0, + ), + ErrorType.authentication: RetryConfig( + maxAttempts: 3, + baseDelay: Duration(seconds: 1), + maxDelay: Duration(seconds: 10), + backoffMultiplier: 1.0, + ), + ErrorType.protocol: RetryConfig( + maxAttempts: 5, + baseDelay: Duration(seconds: 2), + maxDelay: Duration(minutes: 2), + backoffMultiplier: 1.5, + ), + ErrorType.unknown: RetryConfig( + maxAttempts: 5, + baseDelay: Duration(seconds: 3), + maxDelay: Duration(minutes: 5), + backoffMultiplier: 2.0, + ), + }; + + + Duration calculateDelay(int attempt, ErrorType errorType) { + final config = errorConfigs[errorType] ?? errorConfigs[ErrorType.unknown]!; + + + final exponentialDelay = + config.baseDelay * pow(config.backoffMultiplier, attempt - 1); + final cappedDelay = exponentialDelay > config.maxDelay + ? config.maxDelay + : exponentialDelay; + + + final jitter = + cappedDelay.inMilliseconds * + jitterFactor * + (Random().nextDouble() * 2 - 1); + final finalDelay = Duration( + milliseconds: (cappedDelay.inMilliseconds + jitter).round(), + ); + + return finalDelay; + } + + + bool shouldRetry(int attempt, ErrorType errorType) { + final config = errorConfigs[errorType] ?? errorConfigs[ErrorType.unknown]!; + return attempt <= config.maxAttempts; + } + + + RetryConfig getConfigForError(ErrorType errorType) { + return errorConfigs[errorType] ?? errorConfigs[ErrorType.unknown]!; + } +} + + +class RetryConfig { + final int maxAttempts; + final Duration baseDelay; + final Duration maxDelay; + final double backoffMultiplier; + + RetryConfig({ + required this.maxAttempts, + required this.baseDelay, + required this.maxDelay, + required this.backoffMultiplier, + }); +} + + +class RetryManager { + final RetryStrategy _strategy; + final Map _sessions = {}; + + RetryManager({RetryStrategy? strategy}) + : _strategy = strategy ?? RetryStrategy(); + + + RetrySession startSession(String sessionId, ErrorType initialErrorType) { + final session = RetrySession( + id: sessionId, + strategy: _strategy, + initialErrorType: initialErrorType, + ); + _sessions[sessionId] = session; + return session; + } + + + RetrySession? getSession(String sessionId) { + return _sessions[sessionId]; + } + + + void endSession(String sessionId) { + _sessions.remove(sessionId); + } + + + void clearSessions() { + _sessions.clear(); + } + + + Map getStatistics() { + final totalSessions = _sessions.length; + final activeSessions = _sessions.values.where((s) => s.isActive).length; + final successfulSessions = _sessions.values + .where((s) => s.isSuccessful) + .length; + final failedSessions = _sessions.values.where((s) => s.isFailed).length; + + return { + 'total_sessions': totalSessions, + 'active_sessions': activeSessions, + 'successful_sessions': successfulSessions, + 'failed_sessions': failedSessions, + 'success_rate': totalSessions > 0 + ? successfulSessions / totalSessions + : 0.0, + }; + } +} + + +class RetrySession { + final String id; + final RetryStrategy strategy; + final ErrorType initialErrorType; + final DateTime startTime; + final List attempts = []; + + RetrySession({ + required this.id, + required this.strategy, + required this.initialErrorType, + }) : startTime = DateTime.now(); + + + void addAttempt( + ErrorType errorType, { + String? message, + Map? metadata, + }) { + final attempt = RetryAttempt( + number: attempts.length + 1, + errorType: errorType, + timestamp: DateTime.now(), + message: message, + metadata: metadata, + ); + attempts.add(attempt); + } + + + Duration getNextDelay() { + return strategy.calculateDelay(attempts.length + 1, currentErrorType); + } + + + bool canRetry() { + return strategy.shouldRetry(attempts.length + 1, currentErrorType); + } + + + ErrorType get currentErrorType { + if (attempts.isEmpty) return initialErrorType; + return attempts.last.errorType; + } + + + int get attemptCount => attempts.length; + + + bool get isActive => !isSuccessful && !isFailed && canRetry(); + + + bool get isSuccessful => attempts.isNotEmpty && attempts.last.isSuccessful; + + + bool get isFailed => !canRetry() && !isSuccessful; + + + Duration get duration => DateTime.now().difference(startTime); + + + RetryAttempt? get lastAttempt => attempts.isNotEmpty ? attempts.last : null; + + + Map getStatistics() { + final errorTypes = attempts.map((a) => a.errorType.name).toList(); + final errorTypeCounts = {}; + for (final type in errorTypes) { + errorTypeCounts[type] = (errorTypeCounts[type] ?? 0) + 1; + } + + return { + 'session_id': id, + 'start_time': startTime.toIso8601String(), + 'duration_seconds': duration.inSeconds, + 'attempt_count': attemptCount, + 'is_active': isActive, + 'is_successful': isSuccessful, + 'is_failed': isFailed, + 'error_types': errorTypeCounts, + 'last_attempt': lastAttempt?.toJson(), + }; + } +} + + +class RetryAttempt { + final int number; + final ErrorType errorType; + final DateTime timestamp; + final String? message; + final Map? metadata; + final bool isSuccessful; + + RetryAttempt({ + required this.number, + required this.errorType, + required this.timestamp, + this.message, + this.metadata, + this.isSuccessful = false, + }); + + Map toJson() { + return { + 'number': number, + 'error_type': errorType.name, + 'timestamp': timestamp.toIso8601String(), + 'message': message, + 'metadata': metadata, + 'is_successful': isSuccessful, + }; + } +} diff --git a/lib/connection_lifecycle_manager.dart b/lib/connection_lifecycle_manager.dart new file mode 100644 index 0000000..c9a22c9 --- /dev/null +++ b/lib/connection_lifecycle_manager.dart @@ -0,0 +1,138 @@ + + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'api_service.dart'; +import 'theme_provider.dart'; + +class ConnectionLifecycleManager extends StatefulWidget { + final Widget child; + + const ConnectionLifecycleManager({super.key, required this.child}); + + @override + _ConnectionLifecycleManagerState createState() => + _ConnectionLifecycleManagerState(); +} + +class _ConnectionLifecycleManagerState extends State + with WidgetsBindingObserver, SingleTickerProviderStateMixin { + bool _isReconnecting = false; + late AnimationController _animationController; + late Animation _slideAnimation; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + + _animationController = AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ); + + _slideAnimation = + Tween(begin: const Offset(0, -1), end: Offset.zero).animate( + CurvedAnimation(parent: _animationController, curve: Curves.easeOut), + ); + } + + @override + void dispose() { + _animationController.dispose(); + WidgetsBinding.instance.removeObserver(this); + super.dispose(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + super.didChangeAppLifecycleState(state); + switch (state) { + case AppLifecycleState.resumed: + print("✅ Приложение возобновлено."); + ApiService.instance.setAppInForeground(true); + ApiService.instance.sendNavEvent('WARM_START'); + _checkAndReconnectIfNeeded(); + break; + case AppLifecycleState.paused: + print("⏸️ Приложение свернуто."); + ApiService.instance.setAppInForeground(false); + ApiService.instance.sendNavEvent('GO', screenTo: 1, screenFrom: 150); + break; + default: + break; + } + } + + Future _checkAndReconnectIfNeeded() async { + final hasToken = await ApiService.instance.hasToken(); + if (!hasToken) { + print("🔒 Токен отсутствует, переподключение не требуется"); + return; + } + + await Future.delayed(const Duration(milliseconds: 500)); + final bool actuallyConnected = ApiService.instance.isActuallyConnected; + print("🔍 Проверка соединения:"); + print(" - isOnline: ${ApiService.instance.isOnline}"); + print(" - isActuallyConnected: $actuallyConnected"); + + if (!actuallyConnected) { + print("🔌 Соединение потеряно. Запускаем переподключение..."); + if (mounted) { + setState(() { + _isReconnecting = true; + }); + _animationController.forward(); + } + + try { + await ApiService.instance.performFullReconnection(); + print("✅ Переподключение выполнено успешно"); + if (mounted) { + await _animationController.reverse(); + setState(() { + _isReconnecting = false; + }); + } + } catch (e) { + print("❌ Ошибка при переподключении: $e"); + Future.delayed(const Duration(seconds: 3), () async { + if (!ApiService.instance.isActuallyConnected) { + print("🔁 Повторная попытка переподключения..."); + try { + await ApiService.instance.performFullReconnection(); + if (mounted) { + await _animationController.reverse(); + setState(() { + _isReconnecting = false; + }); + } + } catch (e) { + print("❌ Повторная попытка не удалась: $e"); + if (mounted) { + await _animationController.reverse(); + setState(() { + _isReconnecting = false; + }); + } + } + } + }); + } + } else { + print("✅ Соединение активно, переподключение не требуется"); + } + } + + @override + Widget build(BuildContext context) { + final theme = Provider.of(context); + final accentColor = theme.accentColor; + + return Directionality( + textDirection: TextDirection.ltr, + child: Stack(children: [widget.child]), + ); + } +} diff --git a/lib/custom_request_screen.dart b/lib/custom_request_screen.dart new file mode 100644 index 0000000..3dfacc2 --- /dev/null +++ b/lib/custom_request_screen.dart @@ -0,0 +1,317 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/api_service.dart'; + + +class RequestHistoryItem { + final String request; + final String response; + final DateTime timestamp; + + RequestHistoryItem({ + required this.request, + required this.response, + required this.timestamp, + }); +} + +class CustomRequestScreen extends StatefulWidget { + const CustomRequestScreen({super.key}); + + @override + State createState() => _CustomRequestScreenState(); +} + +class _CustomRequestScreenState extends State { + final _requestController = TextEditingController(); + final _scrollController = ScrollController(); + + String? _response; + String? _error; + bool _isLoading = false; + + final List _history = []; + + void _handleResponse(Map message, String originalRequest) { + const encoder = JsonEncoder.withIndent(' '); + final formattedResponse = encoder.convert(message); + + if (!mounted) return; // Убедимся, что виджет все еще существует + + setState(() { + _response = formattedResponse; + _isLoading = false; + _error = null; + + + _history.insert( + 0, + RequestHistoryItem( + request: originalRequest, // Используем переданный запрос + response: formattedResponse, + timestamp: DateTime.now(), + ), + ); + }); + } + + Future _sendRequest() async { + if (_isLoading) return; + FocusScope.of(context).unfocus(); + + final requestText = _requestController.text.isEmpty + ? '{}' + : _requestController.text; + Map requestJson; + + try { + requestJson = jsonDecode(requestText) as Map; + } catch (e) { + setState(() { + _error = 'Ошибка: Невалидный JSON в запросе.\n$e'; + }); + return; + } + + setState(() { + _isLoading = true; + _response = null; + _error = null; + }); + + StreamSubscription? subscription; + Timer? timeoutTimer; + + try { + final int sentSeq = ApiService.instance.sendAndTrackFullJsonRequest( + jsonEncode(requestJson), + ); + + + timeoutTimer = Timer(const Duration(seconds: 15), () { + subscription?.cancel(); // Прекращаем слушать стрим + if (mounted && _isLoading) { + setState(() { + _error = 'Ошибка: Превышено время ожидания ответа (15с).'; + _isLoading = false; + }); + } + }); + + + subscription = ApiService.instance.messages.listen((message) { + + if (message['seq'] == sentSeq) { + timeoutTimer?.cancel(); // Отменяем таймер + subscription?.cancel(); // Отменяем подписку + _handleResponse(message, requestText); // Обрабатываем ответ + } + }); + } catch (e) { + timeoutTimer?.cancel(); + subscription?.cancel(); + if (mounted) { + setState(() { + _error = 'Ошибка при отправке запроса: $e'; + _isLoading = false; + }); + } + } + } + + void _useHistoryItem(RequestHistoryItem item) { + + _requestController.text = item.request; + setState(() { + _response = item.response; + _error = null; + }); + _scrollController.animateTo( + 0, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Custom WebSocket Request')), + body: SingleChildScrollView( + controller: _scrollController, + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildRequestSection(), + const SizedBox(height: 24), + _buildResponseSection(), + const SizedBox(height: 24), + if (_history.isNotEmpty) _buildHistoryWidget(), + ], + ), + ), + ); + } + + Widget _buildRequestSection() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Запрос к серверу', style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 12), + TextField( + controller: _requestController, + decoration: const InputDecoration( + border: OutlineInputBorder(), + alignLabelWithHint: true, + hintText: 'Введите полный JSON запроса...', + ), + keyboardType: TextInputType.multiline, + maxLines: 12, + style: const TextStyle(fontFamily: 'monospace', fontSize: 14.0), + ), + const SizedBox(height: 16), + FilledButton.icon( + onPressed: _isLoading ? null : _sendRequest, + icon: _isLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Colors.white, + ), + ) + : const Icon(Icons.send), + label: Text(_isLoading ? 'Ожидание...' : 'Отправить запрос'), + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + minimumSize: const Size(double.infinity, 50), + ), + ), + ], + ); + } + + Widget _buildResponseSection() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Ответ от сервера', + style: Theme.of(context).textTheme.titleLarge, + ), + if (_response != null) + IconButton( + icon: const Icon(Icons.copy_all_outlined), + tooltip: 'Скопировать ответ', + onPressed: () { + Clipboard.setData(ClipboardData(text: _response!)); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Ответ скопирован в буфер обмена'), + backgroundColor: Colors.green, + ), + ); + }, + ), + ], + ), + const SizedBox(height: 12), + Container( + width: double.infinity, + constraints: const BoxConstraints(minHeight: 150), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainer, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of(context).colorScheme.outline.withOpacity(0.5), + ), + ), + child: _buildResponseContent(), + ), + ], + ); + } + + Widget _buildResponseContent() { + if (_isLoading) { + return const Center(child: CircularProgressIndicator()); + } + if (_error != null) { + return SelectableText( + _error!, + style: TextStyle( + color: Theme.of(context).colorScheme.error, + fontFamily: 'monospace', + ), + ); + } + if (_response != null) { + return SelectableText( + _response!, + style: const TextStyle(fontFamily: 'monospace', fontSize: 14), + ); + } + return Center( + child: Text( + 'Здесь появится ответ от сервера...', + style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant), + ), + ); + } + + Widget _buildHistoryWidget() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('История запросов', style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: 12), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: _history.length, + itemBuilder: (context, index) { + final item = _history[index]; + String opcode = 'N/A'; + try { + final decoded = jsonDecode(item.request); + opcode = decoded['opcode']?.toString() ?? 'N/A'; + } catch (_) {} + + return Card( + margin: const EdgeInsets.only(bottom: 8), + child: ListTile( + leading: CircleAvatar(child: Text(opcode)), + title: Text( + 'Request: ${item.request.replaceAll('\n', ' ').substring(0, (item.request.length > 50) ? 50 : item.request.length)}...', + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontFamily: 'monospace'), + ), + subtitle: Text( + '${item.timestamp.hour.toString().padLeft(2, '0')}:${item.timestamp.minute.toString().padLeft(2, '0')}:${item.timestamp.second.toString().padLeft(2, '0')}', + ), + onTap: () => _useHistoryItem(item), + ), + ); + }, + ), + ], + ); + } + + @override + void dispose() { + _requestController.dispose(); + _scrollController.dispose(); + super.dispose(); + } +} diff --git a/lib/debug_screen.dart b/lib/debug_screen.dart new file mode 100644 index 0000000..b16bc50 --- /dev/null +++ b/lib/debug_screen.dart @@ -0,0 +1,740 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:gwid/cache_management_screen.dart'; // Добавлен импорт +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/phone_entry_screen.dart'; +import 'package:gwid/custom_request_screen.dart'; +import 'dart:async'; + +class DebugScreen extends StatelessWidget { + const DebugScreen({super.key}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final theme = context.watch(); + + return Scaffold( + appBar: AppBar( + title: const Text('Debug Settings'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + ), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + "Performance Debug", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.speed), + title: const Text("Показать FPS overlay"), + subtitle: const Text("Отображение FPS и производительности"), + trailing: Switch( + value: theme.debugShowPerformanceOverlay, + onChanged: (value) => + theme.setDebugShowPerformanceOverlay(value), + ), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.refresh), + title: const Text("Показать панель обновления чатов"), + subtitle: const Text( + "Debug панель для обновления списка чатов", + ), + trailing: Switch( + value: theme.debugShowChatsRefreshPanel, + onChanged: (value) => + theme.setDebugShowChatsRefreshPanel(value), + ), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.message), + title: const Text("Показать счётчик сообщений"), + subtitle: const Text("Отладочная информация о сообщениях"), + trailing: Switch( + value: theme.debugShowMessageCount, + onChanged: (value) => theme.setDebugShowMessageCount(value), + ), + ), + ], + ), + ), + + const SizedBox(height: 16), + + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + "Инструменты разработчика", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.code), + title: const Text("Custom API Request"), + subtitle: const Text("Отправить сырой запрос на сервер"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const CustomRequestScreen(), + ), + ); + }, + ), + ], + ), + ), + + const SizedBox(height: 16), + + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + "Data Management", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.delete_forever), + title: const Text("Очистить все данные"), + subtitle: const Text("Полная очистка кэшей и данных"), + trailing: const Icon(Icons.chevron_right), + onTap: () => _showClearAllDataDialog(context), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.phone), + title: const Text("Показать ввод номера"), + subtitle: const Text("Открыть экран ввода номера без выхода"), + trailing: const Icon(Icons.chevron_right), + onTap: () => _showPhoneEntryScreen(context), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.traffic), + title: const Text("Статистика трафика"), + subtitle: const Text("Просмотр использованного трафика"), + trailing: const Icon(Icons.chevron_right), + onTap: () => _showTrafficStats(context), + ), + const SizedBox(height: 8), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.storage), + title: const Text("Использование памяти"), + subtitle: const Text("Просмотр статистики памяти"), + trailing: const Icon(Icons.chevron_right), + onTap: () => _showMemoryUsage(context), + ), + const SizedBox(height: 8), + + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.cached), + title: const Text("Управление кэшем"), + subtitle: const Text("Настройки кэширования и статистика"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const CacheManagementScreen(), + ), + ); + }, + ), + ], + ), + ), + ], + ), + ); + } + + void _showClearAllDataDialog(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Очистить все данные'), + content: const Text( + 'Это действие удалит ВСЕ данные приложения:\n\n' + '• Все кэши и сообщения\n' + '• Настройки и профиль\n' + '• Токен авторизации\n' + '• История чатов\n\n' + 'После очистки приложение будет закрыто.\n' + 'Вы уверены?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () async { + Navigator.of(context).pop(); + await _performFullDataClear(context); + }, + style: FilledButton.styleFrom( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + ), + child: const Text('Очистить и закрыть'), + ), + ], + ), + ); + } + + Future _performFullDataClear(BuildContext context) async { + try { + + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => const AlertDialog( + content: Row( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + SizedBox(width: 16), + Text('Очистка данных...'), + ], + ), + ), + ); + + + await ApiService.instance.clearAllData(); + + + if (context.mounted) { + Navigator.of(context).pop(); + } + + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Все данные очищены. Приложение будет закрыто.'), + backgroundColor: Colors.green, + duration: Duration(seconds: 2), + ), + ); + } + + + await Future.delayed(const Duration(seconds: 2)); + + + if (context.mounted) { + SystemNavigator.pop(); + } + } catch (e) { + + if (context.mounted) { + Navigator.of(context).pop(); + } + + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при очистке данных: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + void _showPhoneEntryScreen(BuildContext context) { + Navigator.of( + context, + ).push(MaterialPageRoute(builder: (context) => const PhoneEntryScreen())); + } + + void _showTrafficStats(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Статистика трафика'), + content: const Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('📊 Статистика использования данных:'), + SizedBox(height: 16), + Text('• Отправлено сообщений: 1,247'), + Text('• Получено сообщений: 3,891'), + Text('• Загружено фото: 156 MB'), + Text('• Загружено видео: 89 MB'), + Text('• Общий трафик: 2.1 GB'), + SizedBox(height: 16), + Text('📅 За последние 30 дней'), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Закрыть'), + ), + ], + ), + ); + } + + void _showMemoryUsage(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Использование памяти'), + content: const Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('💾 Использование памяти:'), + SizedBox(height: 16), + Text('• Кэш сообщений: 45.2 MB'), + Text('• Кэш контактов: 12.8 MB'), + Text('• Кэш чатов: 8.3 MB'), + Text('• Медиа файлы: 156.7 MB'), + Text('• Общее использование: 223.0 MB'), + SizedBox(height: 16), + Text('📱 Доступно памяти: 2.1 GB'), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Закрыть'), + ), + FilledButton( + onPressed: () { + Navigator.of(context).pop(); + ApiService.instance.clearAllCaches(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Кэш очищен'), + backgroundColor: Colors.green, + ), + ); + }, + child: const Text('Очистить кэш'), + ), + ], + ), + ); + } +} + +class _OutlinedSection extends StatelessWidget { + final Widget child; + + const _OutlinedSection({required this.child}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border.all(color: colors.outline.withOpacity(0.3)), + borderRadius: BorderRadius.circular(12), + ), + child: child, + ); + } +} + +class Session { + final String client; + final String location; + final bool current; + final int time; + final String info; + + Session({ + required this.client, + required this.location, + required this.current, + required this.time, + required this.info, + }); + + factory Session.fromJson(Map json) { + return Session( + client: json['client'] ?? '', + location: json['location'] ?? '', + current: json['current'] ?? false, + time: json['time'] ?? 0, + info: json['info'] ?? '', + ); + } +} + +class SessionsScreen extends StatefulWidget { + const SessionsScreen({super.key}); + + @override + State createState() => _SessionsScreenState(); +} + +class _SessionsScreenState extends State { + List _sessions = []; + bool _isLoading = true; + bool _isInitialLoad = true; + StreamSubscription? _apiSubscription; + + @override + void initState() { + super.initState(); + _listenToApi(); + + } + + void _loadSessions() { + + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _isLoading = true; + }); + } + }); + ApiService.instance.requestSessions(); + } + + void _terminateAllSessions() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Сбросить все сессии?'), + content: const Text( + 'Все остальные сессии будут завершены. ' + 'Текущая сессия останется активной.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + ), + child: const Text('Сбросить'), + ), + ], + ), + ); + + if (confirmed == true) { + + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _isLoading = true; + }); + } + }); + + ApiService.instance.terminateAllSessions(); + + + Future.delayed(const Duration(seconds: 2), () { + if (mounted) { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + _loadSessions(); + } + }); + } + }); + } + } + + void _listenToApi() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (message['opcode'] == 96 && mounted) { + + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + }); + + final payload = message['payload']; + if (payload != null && payload['sessions'] != null) { + final sessionsList = payload['sessions'] as List; + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() { + _sessions = sessionsList + .map((session) => Session.fromJson(session)) + .toList(); + }); + } + }); + } + } + }); + } + + String _formatTime(int timestamp) { + final date = DateTime.fromMillisecondsSinceEpoch(timestamp); + final now = DateTime.now(); + final difference = now.difference(date); + + String relativeTime; + if (difference.inDays > 0) { + relativeTime = '${difference.inDays} дн. назад'; + } else if (difference.inHours > 0) { + relativeTime = '${difference.inHours} ч. назад'; + } else if (difference.inMinutes > 0) { + relativeTime = '${difference.inMinutes} мин. назад'; + } else { + relativeTime = 'Только что'; + } + + + final exactTime = + '${date.day.toString().padLeft(2, '0')}.${date.month.toString().padLeft(2, '0')}.${date.year} ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}'; + + return '$relativeTime ($exactTime)'; + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + + if (_isInitialLoad && _sessions.isEmpty) { + _isInitialLoad = false; + _loadSessions(); + } + + return Scaffold( + appBar: AppBar( + title: const Text("Активные сессии"), + actions: [ + IconButton(onPressed: _loadSessions, icon: const Icon(Icons.refresh)), + ], + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _sessions.isEmpty + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.security, + size: 64, + color: colors.onSurfaceVariant, + ), + const SizedBox(height: 16), + Text( + "Нет активных сессий", + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 18, + ), + ), + ], + ), + ) + : Column( + children: [ + + if (_sessions.any((s) => !s.current)) + Container( + width: double.infinity, + margin: const EdgeInsets.all(16), + child: FilledButton.icon( + onPressed: _terminateAllSessions, + style: FilledButton.styleFrom( + backgroundColor: colors.error, + foregroundColor: colors.onError, + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 16, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + icon: const Icon(Icons.logout, size: 24), + label: const Text( + "Завершить все сессии кроме текущей", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + + Expanded( + child: ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: _sessions.length, + itemBuilder: (context, index) { + final session = _sessions[index]; + return Card( + margin: const EdgeInsets.only(bottom: 12), + child: ListTile( + leading: CircleAvatar( + backgroundColor: session.current + ? colors.primary + : colors.surfaceContainerHighest, + child: Icon( + session.current + ? Icons.phone_android + : Icons.computer, + color: session.current + ? colors.onPrimary + : colors.onSurfaceVariant, + ), + ), + title: Text( + session.current ? "Текущая сессия" : session.client, + style: TextStyle( + fontWeight: session.current + ? FontWeight.bold + : FontWeight.normal, + color: session.current + ? colors.primary + : colors.onSurface, + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 4), + Text( + session.location, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + const SizedBox(height: 2), + Text( + session.info, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 12, + ), + ), + const SizedBox(height: 2), + Text( + _formatTime(session.time), + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 12, + ), + ), + ], + ), + trailing: session.current + ? Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: colors.primary, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + "Активна", + style: TextStyle( + color: colors.onPrimary, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ) + : Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + "Неактивна", + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ); + }, + ), + ), + ], + ), + ); + } + + @override + void dispose() { + _apiSubscription?.cancel(); + super.dispose(); + } +} diff --git a/lib/device_presets.dart b/lib/device_presets.dart new file mode 100644 index 0000000..5d88061 --- /dev/null +++ b/lib/device_presets.dart @@ -0,0 +1,678 @@ + +class DevicePreset { + final String deviceType; + final String userAgent; + final String deviceName; + final String osVersion; + final String screen; + final String timezone; + final String locale; + + DevicePreset({ + required this.deviceType, + required this.userAgent, + required this.deviceName, + required this.osVersion, + required this.screen, + required this.timezone, + required this.locale, + }); +} + + +final List devicePresets = [ + + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; SM-S928B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36', + deviceName: 'Samsung Galaxy S24 Ultra', + osVersion: 'Android 14', + screen: '1440x3120 2.8x', + timezone: 'Europe/Berlin', + locale: 'de-DE', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; Pixel 8 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36', + deviceName: 'Google Pixel 8 Pro', + osVersion: 'Android 14', + screen: '1344x2992 2.7x', + timezone: 'America/New_York', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; 23021RAA2Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36', + deviceName: 'Xiaomi 13 Pro', + osVersion: 'Android 13', + screen: '1440x3200 2.9x', + timezone: 'Asia/Shanghai', + locale: 'zh-CN', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; CPH2521) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36', + deviceName: 'OnePlus 12', + osVersion: 'Android 14', + screen: '1440x3168 2.8x', + timezone: 'Asia/Kolkata', + locale: 'en-IN', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36', + deviceName: 'Samsung Galaxy S21 Ultra', + osVersion: 'Android 13', + screen: '1440x3200 2.9x', + timezone: 'Europe/London', + locale: 'en-GB', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36', + deviceName: 'Google Pixel 6', + osVersion: 'Android 12', + screen: '1080x2400 2.6x', + timezone: 'America/Chicago', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; RMX3371) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36', + deviceName: 'Realme GT Master Edition', + osVersion: 'Android 13', + screen: '1080x2400 2.5x', + timezone: 'Asia/Dubai', + locale: 'ar-AE', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 11; M2101K6G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36', + deviceName: 'Poco F3', + osVersion: 'Android 11', + screen: '1080x2400 2.6x', + timezone: 'Europe/Madrid', + locale: 'es-ES', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; SO-51D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36', + deviceName: 'Sony Xperia 1 V', + osVersion: 'Android 14', + screen: '1644x3840 3.5x', + timezone: 'Asia/Tokyo', + locale: 'ja-JP', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; XT2201-2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36', + deviceName: 'Motorola Edge 30 Pro', + osVersion: 'Android 13', + screen: '1080x2400 2.5x', + timezone: 'America/Sao_Paulo', + locale: 'pt-BR', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; SM-A546E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36', + deviceName: 'Samsung Galaxy A54', + osVersion: 'Android 14', + screen: '1080x2340 2.5x', + timezone: 'Australia/Sydney', + locale: 'en-AU', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 12; 2201116SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36', + deviceName: 'Redmi Note 11 Pro', + osVersion: 'Android 12', + screen: '1080x2400 2.6x', + timezone: 'Europe/Rome', + locale: 'it-IT', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; ZS676KS) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36', + deviceName: 'Asus ROG Phone 6', + osVersion: 'Android 13', + screen: '1080x2448 2.6x', + timezone: 'Asia/Taipei', + locale: 'zh-TW', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 10; TA-1021) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Mobile Safari/537.36', + deviceName: 'Nokia 8', + osVersion: 'Android 10', + screen: '1440x2560 2.4x', + timezone: 'Europe/Helsinki', + locale: 'fi-FI', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; PGT-N19) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36', + deviceName: 'Huawei P60 Pro', + osVersion: 'Android 13 (EMUI)', + screen: '1220x2700 2.7x', + timezone: 'Europe/Paris', + locale: 'fr-FR', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 9; LM-G710) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36', + deviceName: 'LG G7 ThinQ', + osVersion: 'Android 9', + screen: '1440x3120 2.8x', + timezone: 'Asia/Seoul', + locale: 'ko-KR', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; Nothing Phone (2)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36', + deviceName: 'Nothing Phone (2)', + osVersion: 'Android 14', + screen: '1080x2412 2.5x', + timezone: 'America/Toronto', + locale: 'en-CA', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 13; SM-F936U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36', + deviceName: 'Samsung Galaxy Z Fold 4', + osVersion: 'Android 13', + screen: '1812x2176 2.2x', + timezone: 'America/Denver', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 12; LE2113) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36', + deviceName: 'OnePlus 9', + osVersion: 'Android 12', + screen: '1080x2400 2.6x', + timezone: 'Europe/Stockholm', + locale: 'sv-SE', + ), + DevicePreset( + deviceType: 'ANDROID', + userAgent: + 'Mozilla/5.0 (Linux; Android 14; Pixel 7a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Mobile Safari/537.36', + deviceName: 'Google Pixel 7a', + osVersion: 'Android 14', + screen: '1080x2400 2.5x', + timezone: 'Europe/Amsterdam', + locale: 'nl-NL', + ), + + + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1', + deviceName: 'iPhone 15 Pro Max', + osVersion: 'iOS 17.5.1', + screen: '1290x2796 3.0x', + timezone: 'America/Los_Angeles', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1', + deviceName: 'iPhone 13', + osVersion: 'iOS 16.7', + screen: '1170x2532 3.0x', + timezone: 'Europe/London', + locale: 'en-GB', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPad; CPU OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/124.0.6367.88 Mobile/15E148 Safari/604.1', + deviceName: 'iPad Pro 11-inch', + osVersion: 'iPadOS 17.5', + screen: '1668x2388 2.0x', + timezone: 'Europe/Paris', + locale: 'fr-FR', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/125.0 Mobile/15E148', + deviceName: 'iPhone 14 Pro', + osVersion: 'iOS 17.4.1', + screen: '1179x2556 3.0x', + timezone: 'Europe/Berlin', + locale: 'de-DE', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.3 Mobile/15E148 Safari/604.1', + deviceName: 'iPhone SE (2020)', + osVersion: 'iOS 15.8', + screen: '750x1334 2.0x', + timezone: 'Australia/Melbourne', + locale: 'en-AU', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) OPR/55.0.2519.144889 Mobile/15E148', + deviceName: 'iPhone 15', + osVersion: 'iOS 17.1', + screen: '1179x2556 3.0x', + timezone: 'Asia/Tokyo', + locale: 'ja-JP', + ), + DevicePreset( + deviceType: 'IOS', + userAgent: + 'Mozilla/5.0 (iPad; CPU OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1', + deviceName: 'iPad Air 5th Gen', + osVersion: 'iPadOS 16.5', + screen: '1640x2360 2.0x', + timezone: 'America/Toronto', + locale: 'en-CA', + ), + + + DevicePreset( + deviceType: 'DESKTOP', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'Windows PC', + osVersion: 'Windows 11', + screen: '1920x1080 1.25x', + timezone: 'Europe/Moscow', + locale: 'ru-RU', + ), + DevicePreset( + deviceType: 'DESKTOP', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'MacBook Pro', + osVersion: 'macOS 14.5 Sonoma', + screen: '1728x1117 2.0x', + timezone: 'America/New_York', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'DESKTOP', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0', + deviceName: 'Linux PC', + osVersion: 'Ubuntu 24.04 LTS', + screen: '2560x1440 1.0x', + timezone: 'UTC', + locale: 'en-GB', + ), + DevicePreset( + deviceType: 'DESKTOP', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0', + deviceName: 'Windows PC (Firefox)', + osVersion: 'Windows 10', + screen: '1536x864 1.0x', + timezone: 'Europe/Paris', + locale: 'fr-FR', + ), + DevicePreset( + deviceType: 'DESKTOP', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15', + deviceName: 'iMac (Safari)', + osVersion: 'macOS 13.6 Ventura', + screen: '3840x2160 1.5x', + timezone: 'America/Los_Angeles', + locale: 'en-US', + ), + + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Windows ', + screen: '1920x1080', + timezone: 'Europe/Berlin', + locale: 'de-DE', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Windows', + screen: '2560x1440', + timezone: 'America/New_York', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.2420.97', + deviceName: 'Edge', + osVersion: 'Windows', + screen: '1536x864', + timezone: 'Europe/London', + locale: 'en-GB', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Windows', + screen: '1920x1200', + timezone: 'Europe/Paris', + locale: 'fr-FR', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Windows', + screen: '1366x768', + timezone: 'Europe/Madrid', + locale: 'es-ES', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0', + deviceName: 'Firefox', + osVersion: 'Windows', + screen: '1920x1080', + timezone: 'Europe/Rome', + locale: 'it-IT', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0', + deviceName: 'Firefox', + osVersion: 'Windows', + screen: '1440x900', + timezone: 'Europe/Amsterdam', + locale: 'nl-NL', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0', + deviceName: 'Firefox', + osVersion: 'Windows', + screen: '1600x900', + timezone: 'Europe/Warsaw', + locale: 'pl-PL', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.2535.51', + deviceName: 'Edge', + osVersion: 'Windows', + screen: '1920x1080', + timezone: 'America/Chicago', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.2478.109', + deviceName: 'Edge', + osVersion: 'Windows', + screen: '1366x768', + timezone: 'America/Sao_Paulo', + locale: 'pt-BR', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'macOS 14.5', + screen: '2560x1440', + timezone: 'America/Los_Angeles', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'macOS 13.6', + screen: '1440x900', + timezone: 'America/Toronto', + locale: 'en-CA', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_7_10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'macOS 11.7', + screen: '1728x1117', + timezone: 'Australia/Sydney', + locale: 'en-AU', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'macOS 12.5', + screen: '2048x1152', + timezone: 'Europe/London', + locale: 'en-GB', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:126.0) Gecko/20100101 Firefox/126.0', + deviceName: 'Firefox', + osVersion: 'macOS 14.5', + screen: '1920x1080', + timezone: 'America/New_York', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:125.0) Gecko/20100101 Firefox/125.0', + deviceName: 'Firefox', + osVersion: 'macOS 13.0', + screen: '1680x1050', + timezone: 'Europe/Berlin', + locale: 'de-DE', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15', + deviceName: 'Safari', + osVersion: 'macOS 14.5', + screen: '1440x900', + timezone: 'America/New_York', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15', + deviceName: 'Safari', + osVersion: 'macOS 13.6', + screen: '2560x1600', + timezone: 'Europe/Paris', + locale: 'fr-FR', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15', + deviceName: 'Safari', + osVersion: 'macOS 10.14', + screen: '1280x800', + timezone: 'Asia/Tokyo', + locale: 'ja-JP', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Linux', + screen: '1920x1080', + timezone: 'Europe/Moscow', + locale: 'ru-RU', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Linux', + screen: '1366x768', + timezone: 'Asia/Kolkata', + locale: 'en-IN', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Chrome OS', + screen: '1920x1080', + timezone: 'America/Mexico_City', + locale: 'es-MX', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Linux', + screen: '1600x900', + timezone: 'Asia/Shanghai', + locale: 'zh-CN', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:126.0) Gecko/20100101 Firefox/126.0', + deviceName: 'Firefox', + osVersion: 'Linux', + screen: '1920x1080', + timezone: 'UTC', + locale: 'en-GB', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0', + deviceName: 'Firefox', + osVersion: 'Linux', + screen: '2560x1440', + timezone: 'America/Denver', + locale: 'en-US', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0', + deviceName: 'Firefox', + osVersion: 'Linux', + screen: '1366x768', + timezone: 'Asia/Dubai', + locale: 'ar-AE', + ), + + + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 OPR/110.0.0.0', + deviceName: 'Opera', + osVersion: 'Windows', + screen: '1920x1080', + timezone: 'Europe/Oslo', + locale: 'no-NO', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Vivaldi/6.5.3206.63', + deviceName: 'Vivaldi', + osVersion: 'macOS 14.0', + screen: '1440x900', + timezone: 'Europe/Stockholm', + locale: 'sv-SE', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Windows NT 10.0; rv:102.0) Gecko/20100101 Firefox/102.0', + deviceName: 'Firefox', + osVersion: 'Windows', + screen: '1280x720', + timezone: 'Asia/Seoul', + locale: 'ko-KR', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', + deviceName: 'Chrome', + osVersion: 'Linux', + screen: '1920x1080', + timezone: 'Europe/Helsinki', + locale: 'fi-FI', + ), + DevicePreset( + deviceType: 'WEB', + userAgent: + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.2 Safari/605.1.15', + deviceName: 'Safari', + osVersion: 'macOS 10.13', + screen: '1280x800', + timezone: 'America/Vancouver', + locale: 'en-CA', + ), +]; diff --git a/lib/downloads_screen.dart b/lib/downloads_screen.dart new file mode 100644 index 0000000..181cc60 --- /dev/null +++ b/lib/downloads_screen.dart @@ -0,0 +1,348 @@ +import 'dart:io' as io; +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:intl/intl.dart'; +import 'package:open_file/open_file.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class DownloadsScreen extends StatefulWidget { + const DownloadsScreen({super.key}); + + @override + State createState() => _DownloadsScreenState(); +} + +class _DownloadsScreenState extends State { + List _files = []; + bool _isLoading = true; + String? _downloadsPath; + + @override + void initState() { + super.initState(); + _loadDownloads(); + } + + Future _loadDownloads() async { + setState(() { + _isLoading = true; + }); + + try { + io.Directory? downloadDir; + + if (io.Platform.isAndroid) { + downloadDir = await getExternalStorageDirectory(); + } else if (io.Platform.isIOS) { + final directory = await getApplicationDocumentsDirectory(); + downloadDir = directory; + } else if (io.Platform.isWindows || io.Platform.isLinux) { + final homeDir = + io.Platform.environment['HOME'] ?? + io.Platform.environment['USERPROFILE'] ?? + ''; + downloadDir = io.Directory('$homeDir/Downloads'); + } else { + downloadDir = await getApplicationDocumentsDirectory(); + } + + if (downloadDir != null && await downloadDir.exists()) { + _downloadsPath = downloadDir.path; + + + final prefs = await SharedPreferences.getInstance(); + final List downloadedFilePaths = + prefs.getStringList('downloaded_files') ?? []; + + + final files = + downloadedFilePaths + .map((path) => io.File(path)) + .where((file) => file.existsSync()) + .toList() + ..sort((a, b) { + final aStat = a.statSync(); + final bStat = b.statSync(); + return bStat.modified.compareTo(aStat.modified); + }); + + + final existingPaths = files.map((f) => f.path).toSet(); + final cleanPaths = downloadedFilePaths + .where((path) => existingPaths.contains(path)) + .toList(); + await prefs.setStringList('downloaded_files', cleanPaths); + + setState(() { + _files = files; + _isLoading = false; + }); + } else { + setState(() { + _isLoading = false; + }); + } + } catch (e) { + setState(() { + _isLoading = false; + }); + } + } + + String _formatFileSize(int bytes) { + if (bytes < 1024) { + return '$bytes B'; + } else if (bytes < 1024 * 1024) { + return '${(bytes / 1024).toStringAsFixed(1)} KB'; + } else if (bytes < 1024 * 1024 * 1024) { + return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; + } else { + return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; + } + } + + IconData _getFileIcon(String fileName) { + final extension = fileName.split('.').last.toLowerCase(); + switch (extension) { + case 'pdf': + return Icons.picture_as_pdf; + case 'doc': + case 'docx': + return Icons.description; + case 'xls': + case 'xlsx': + return Icons.table_chart; + case 'txt': + return Icons.text_snippet; + case 'zip': + case 'rar': + case '7z': + return Icons.archive; + case 'mp3': + case 'wav': + case 'flac': + return Icons.audiotrack; + case 'mp4': + case 'avi': + case 'mov': + return Icons.video_file; + case 'jpg': + case 'jpeg': + case 'png': + case 'gif': + return Icons.image; + default: + return Icons.insert_drive_file; + } + } + + Future _deleteFile(io.File file) async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Удалить файл?'), + content: Text( + 'Вы уверены, что хотите удалить ${file.path.split('/').last}?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, false), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () => Navigator.pop(context, true), + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: const Text('Удалить'), + ), + ], + ), + ); + + if (confirmed == true) { + try { + + final prefs = await SharedPreferences.getInstance(); + final List downloadedFilePaths = + prefs.getStringList('downloaded_files') ?? []; + downloadedFilePaths.remove(file.path); + await prefs.setStringList('downloaded_files', downloadedFilePaths); + + + await file.delete(); + + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('Файл удален'))); + _loadDownloads(); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при удалении файла: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final isDark = theme.brightness == Brightness.dark; + + return Scaffold( + appBar: AppBar( + title: const Text('Загрузки'), + actions: [ + IconButton( + icon: const Icon(Icons.refresh), + onPressed: _loadDownloads, + tooltip: 'Обновить', + ), + ], + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _files.isEmpty + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.download_outlined, + size: 64, + color: Colors.grey[400], + ), + const SizedBox(height: 16), + Text( + 'Нет скачанных файлов', + style: TextStyle(fontSize: 16, color: Colors.grey[600]), + ), + if (_downloadsPath != null) ...[ + const SizedBox(height: 8), + Text( + 'Файлы сохраняются в:\n$_downloadsPath', + textAlign: TextAlign.center, + style: TextStyle(fontSize: 12, color: Colors.grey[500]), + ), + ], + ], + ), + ) + : Column( + children: [ + if (_downloadsPath != null) + Container( + padding: const EdgeInsets.all(12), + color: isDark ? Colors.grey[850] : Colors.grey[200], + child: Row( + children: [ + const Icon(Icons.folder, size: 16), + const SizedBox(width: 8), + Expanded( + child: Text( + _downloadsPath!, + style: const TextStyle(fontSize: 12), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + Expanded( + child: ListView.builder( + itemCount: _files.length, + itemBuilder: (context, index) { + final file = _files[index]; + if (file is! io.File) return const SizedBox.shrink(); + + final fileName = file.path + .split(io.Platform.pathSeparator) + .last; + final fileStat = file.statSync(); + final fileSize = fileStat.size; + final modifiedDate = fileStat.modified; + + return ListTile( + leading: Container( + width: 48, + height: 48, + decoration: BoxDecoration( + color: theme.primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + _getFileIcon(fileName), + color: theme.primaryColor, + ), + ), + title: Text( + fileName, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_formatFileSize(fileSize)), + const SizedBox(height: 4), + Text( + DateFormat( + 'dd.MM.yyyy HH:mm', + ).format(modifiedDate), + style: TextStyle( + fontSize: 11, + color: Colors.grey[600], + ), + ), + ], + ), + trailing: IconButton( + icon: const Icon(Icons.more_vert), + onPressed: () { + showModalBottomSheet( + context: context, + builder: (context) => SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.open_in_new), + title: const Text('Открыть'), + onTap: () async { + Navigator.pop(context); + await OpenFile.open(file.path); + }, + ), + ListTile( + leading: const Icon( + Icons.delete, + color: Colors.red, + ), + title: const Text( + 'Удалить', + style: TextStyle(color: Colors.red), + ), + onTap: () { + Navigator.pop(context); + _deleteFile(file); + }, + ), + ], + ), + ), + ); + }, + ), + onTap: () async { + await OpenFile.open(file.path); + }, + ); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/example_usage.dart b/lib/example_usage.dart new file mode 100644 index 0000000..0456d3a --- /dev/null +++ b/lib/example_usage.dart @@ -0,0 +1,264 @@ +import 'package:flutter/material.dart'; +import 'api_service_simple.dart'; +import 'connection/connection_state.dart' as conn_state; + + +class ConnectionExample extends StatefulWidget { + const ConnectionExample({super.key}); + + @override + State createState() => _ConnectionExampleState(); +} + +class _ConnectionExampleState extends State { + final ApiServiceSimple _apiService = ApiServiceSimple.instance; + conn_state.ConnectionInfo? _currentState; + String _logs = ''; + + @override + void initState() { + super.initState(); + _initializeService(); + _setupListeners(); + } + + Future _initializeService() async { + try { + await _apiService.initialize(); + _addLog('✅ Сервис инициализирован'); + } catch (e) { + _addLog('❌ Ошибка инициализации: $e'); + } + } + + void _setupListeners() { + + _apiService.connectionState.listen((state) { + setState(() { + _currentState = state; + }); + _addLog('🔄 Состояние: ${_getStateText(state.state)}'); + }); + + + _apiService.logs.listen((log) { + _addLog('📝 ${log.toString()}'); + }); + + + _apiService.healthMetrics.listen((health) { + _addLog( + '🏥 Здоровье: ${health.healthScore}/100 (${health.quality.name})', + ); + }); + } + + void _addLog(String message) { + setState(() { + _logs += + '${DateTime.now().toIso8601String().substring(11, 23)} $message\n'; + }); + } + + String _getStateText(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.disconnected: + return 'Отключен'; + case conn_state.ConnectionState.connecting: + return 'Подключение...'; + case conn_state.ConnectionState.connected: + return 'Подключен'; + case conn_state.ConnectionState.ready: + return 'Готов'; + case conn_state.ConnectionState.reconnecting: + return 'Переподключение...'; + case conn_state.ConnectionState.error: + return 'Ошибка'; + case conn_state.ConnectionState.disabled: + return 'Отключен'; + } + } + + Color _getStateColor(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.ready: + return Colors.green; + case conn_state.ConnectionState.connected: + return Colors.blue; + case conn_state.ConnectionState.connecting: + case conn_state.ConnectionState.reconnecting: + return Colors.orange; + case conn_state.ConnectionState.error: + return Colors.red; + case conn_state.ConnectionState.disconnected: + case conn_state.ConnectionState.disabled: + return Colors.grey; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Пример подключения'), + backgroundColor: _currentState != null + ? _getStateColor(_currentState!.state) + : Colors.grey, + ), + body: Column( + children: [ + + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + color: _currentState != null + ? _getStateColor(_currentState!.state).withOpacity(0.1) + : Colors.grey.withOpacity(0.1), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Статус: ${_currentState != null ? _getStateText(_currentState!.state) : 'Неизвестно'}', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + if (_currentState?.message != null) ...[ + const SizedBox(height: 4), + Text('Сообщение: ${_currentState!.message}'), + ], + if (_currentState?.serverUrl != null) ...[ + const SizedBox(height: 4), + Text('Сервер: ${_currentState!.serverUrl}'), + ], + if (_currentState?.latency != null) ...[ + const SizedBox(height: 4), + Text('Задержка: ${_currentState!.latency}ms'), + ], + ], + ), + ), + + + Padding( + padding: const EdgeInsets.all(16), + child: Wrap( + spacing: 8, + runSpacing: 8, + children: [ + ElevatedButton( + onPressed: _connect, + child: const Text('Подключиться'), + ), + ElevatedButton( + onPressed: _disconnect, + child: const Text('Отключиться'), + ), + ElevatedButton( + onPressed: _reconnect, + child: const Text('Переподключиться'), + ), + ElevatedButton( + onPressed: _clearLogs, + child: const Text('Очистить логи'), + ), + ElevatedButton( + onPressed: _showStats, + child: const Text('Статистика'), + ), + ], + ), + ), + + + Expanded( + child: Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.grey[100], + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey[300]!), + ), + child: SingleChildScrollView( + child: Text( + _logs.isEmpty ? 'Логи появятся здесь...' : _logs, + style: const TextStyle(fontFamily: 'monospace', fontSize: 12), + ), + ), + ), + ), + ], + ), + ); + } + + Future _connect() async { + try { + _addLog('🔄 Попытка подключения...'); + await _apiService.connect(); + _addLog('✅ Подключение успешно'); + } catch (e) { + _addLog('❌ Ошибка подключения: $e'); + } + } + + Future _disconnect() async { + try { + _addLog('🔄 Отключение...'); + await _apiService.disconnect(); + _addLog('✅ Отключение успешно'); + } catch (e) { + _addLog('❌ Ошибка отключения: $e'); + } + } + + Future _reconnect() async { + try { + _addLog('🔄 Переподключение...'); + await _apiService.reconnect(); + _addLog('✅ Переподключение успешно'); + } catch (e) { + _addLog('❌ Ошибка переподключения: $e'); + } + } + + void _clearLogs() { + setState(() { + _logs = ''; + }); + _addLog('🧹 Логи очищены'); + } + + void _showStats() { + final stats = _apiService.getStatistics(); + _addLog('📊 Статистика: ${stats.toString()}'); + + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Статистика'), + content: SingleChildScrollView( + child: Text( + stats.toString(), + style: const TextStyle(fontFamily: 'monospace', fontSize: 12), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Закрыть'), + ), + ], + ), + ); + } + + @override + void dispose() { + _apiService.dispose(); + super.dispose(); + } +} diff --git a/lib/full_screen_video_player.dart b/lib/full_screen_video_player.dart new file mode 100644 index 0000000..b5ab958 --- /dev/null +++ b/lib/full_screen_video_player.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:video_player/video_player.dart'; +import 'package:chewie/chewie.dart'; + +class FullScreenVideoPlayer extends StatefulWidget { + final String videoUrl; + + const FullScreenVideoPlayer({Key? key, required this.videoUrl}) + : super(key: key); + + @override + State createState() => _FullScreenVideoPlayerState(); +} + +class _FullScreenVideoPlayerState extends State { + VideoPlayerController? _videoPlayerController; + ChewieController? _chewieController; + bool _isLoading = true; + bool _hasError = false; + + @override + void initState() { + super.initState(); + _initializePlayer(); + } + + Future _initializePlayer() async { + try { + _videoPlayerController = VideoPlayerController.networkUrl( + Uri.parse(widget.videoUrl), + httpHeaders: const { + + 'User-Agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + }, + ); + + await _videoPlayerController!.initialize(); + + _chewieController = ChewieController( + videoPlayerController: _videoPlayerController!, + aspectRatio: _videoPlayerController!.value.aspectRatio, + autoPlay: true, // Начинаем воспроизведение сразу + looping: false, // Не зацикливаем + showControls: true, // Показываем стандартные элементы управления Chewie + materialProgressColors: ChewieProgressColors( + playedColor: Colors.red, + handleColor: Colors.blueAccent, + backgroundColor: Colors.grey, + bufferedColor: Colors.white, + ), + + ); + + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } catch (e) { + print('❌ [FullScreenVideoPlayer] Error initializing Chewie player: $e'); + if (mounted) { + setState(() { + _hasError = true; + _isLoading = false; + }); + } + } + } + + @override + void dispose() { + _videoPlayerController?.dispose(); + _chewieController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, // Черный фон для полноэкранного видео + appBar: AppBar( + backgroundColor: Colors.black, + iconTheme: const IconThemeData(color: Colors.white), + title: const Text('Видео', style: TextStyle(color: Colors.white)), + ), + body: Center( + child: _isLoading + ? const CircularProgressIndicator(color: Colors.white) + : _hasError + ? const Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.error_outline, color: Colors.red, size: 50), + SizedBox(height: 10), + Text( + 'Не удалось загрузить видео.', + style: TextStyle(color: Colors.white, fontSize: 16), + ), + Text( + 'Проверьте интернет или попробуйте позже.', + style: TextStyle(color: Colors.white70, fontSize: 12), + ), + ], + ) + : _chewieController != null && + _chewieController!.videoPlayerController.value.isInitialized + ? Chewie(controller: _chewieController!) + : const Text( + 'Ошибка плеера', + style: TextStyle(color: Colors.white), + ), + ), + ); + } +} diff --git a/lib/home_screen.dart b/lib/home_screen.dart new file mode 100644 index 0000000..534077b --- /dev/null +++ b/lib/home_screen.dart @@ -0,0 +1,849 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/chats_screen.dart'; +import 'package:gwid/phone_entry_screen.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/screens/settings/reconnection_screen.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:gwid/services/version_checker.dart'; +import 'package:app_links/app_links.dart'; +import 'package:gwid/models/chat.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/models/profile.dart'; +import 'package:gwid/chat_screen.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; + +class HomeScreen extends StatefulWidget { + const HomeScreen({super.key}); + + @override + State createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State { + late Future> _chatsFuture; + Profile? _myProfile; + bool _isProfileLoading = true; + String? _connectionStatus; + StreamSubscription? _connectionSubscription; + StreamSubscription? _messageSubscription; + + late final AppLinks _appLinks; + StreamSubscription? _linkSubscription; + + Uri? _initialUri; + + @override + void initState() { + super.initState(); + + _loadMyProfile(); + _chatsFuture = (() async { + try { + await ApiService.instance.waitUntilOnline(); + return ApiService.instance.getChatsAndContacts(); + } catch (e) { + print('Ошибка получения чатов в HomeScreen: $e'); + if (e.toString().contains('Auth token not found') || + e.toString().contains('FAIL_WRONG_PASSWORD')) {} + rethrow; + } + })(); + + _checkVersionInBackground(); + _initDeepLinking(); + + + _connectionSubscription = ApiService.instance.connectionStatus.listen(( + status, + ) { + if (mounted) { + setState(() => _connectionStatus = status); + Future.delayed(const Duration(seconds: 3), () { + if (mounted) { + setState(() => _connectionStatus = null); + } + }); + } + }); + + + _messageSubscription = ApiService.instance.messages.listen((message) { + if (message['type'] == 'session_terminated' && mounted) { + _handleSessionTerminated(message['message']); + } else if (message['type'] == 'invalid_token' && mounted) { + _handleInvalidToken(message['message']); + } else if (message['type'] == 'group_join_success' && mounted) { + _handleGroupJoinSuccess(message); + } else if (message['cmd'] == 3 && message['opcode'] == 57 && mounted) { + _handleGroupJoinError(message); + } + }); + } + + Future _loadMyProfile() async { + if (!mounted) return; + setState(() => _isProfileLoading = true); + try { + + final cachedProfile = ApiService.instance.lastChatsPayload?['profile']; + if (cachedProfile != null) { + if (mounted) { + setState(() { + _myProfile = Profile.fromJson(cachedProfile); + _isProfileLoading = false; + }); + } + } else { + + final result = await ApiService.instance.getChatsAndContacts( + force: false, + ); + if (mounted) { + final profileJson = result['profile']; + if (profileJson != null) { + setState(() { + _myProfile = Profile.fromJson(profileJson); + _isProfileLoading = false; + }); + } else { + setState(() => _isProfileLoading = false); + } + } + } + } catch (e) { + if (mounted) setState(() => _isProfileLoading = false); + print("Ошибка загрузки профиля в _HomeScreenState: $e"); + } + } + + Future _showUpdateDialog( + BuildContext context, + String newVersion, + ) async { + await showDialog( + context: context, + barrierDismissible: false, // Пользователь должен сделать выбор + builder: (BuildContext dialogContext) { + return AlertDialog( + title: const Text('Доступно обновление'), + content: Text( + 'Найдена новая версия приложения: $newVersion. Рекомендуется обновить данные сессии, чтобы соответствовать последней версии.', + ), + actions: [ + TextButton( + child: const Text('Отменить'), + onPressed: () { + Navigator.of(dialogContext).pop(); // Просто закрыть диалог + }, + ), + FilledButton( + child: const Text('Обновить'), + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('spoof_appversion', newVersion); + + try { + await ApiService.instance.performFullReconnection(); + print("Переподключение выполнено успешно"); + } catch (e) { + print("Ошибка переподключения: $e"); + } + + + if (mounted) { + Navigator.of(dialogContext).pop(); + } + + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Версия сессии обновлена до $newVersion!'), + backgroundColor: Colors.green.shade700, + ), + ); + } + }, + ), + ], + ); + }, + ); + } + + Future _checkVersionInBackground() async { + try { + final prefs = await SharedPreferences.getInstance(); + + + final isWebVersionCheckEnabled = + prefs.getBool('enable_web_version_check') ?? false; + + + if (!isWebVersionCheckEnabled) { + print("Web version checking is disabled, skipping check"); + return; + } + + final isAutoUpdateEnabled = prefs.getBool('auto_update_enabled') ?? true; + final showUpdateNotification = + prefs.getBool('show_update_notification') ?? true; + + final currentVersion = prefs.getString('spoof_appversion') ?? '0.0.0'; + final latestVersion = await VersionChecker.getLatestVersion(); + + if (latestVersion != currentVersion) { + if (isAutoUpdateEnabled) { + + await prefs.setString('spoof_appversion', latestVersion); + print("Версия сессии автоматически обновлена до $latestVersion"); + + try { + await ApiService.instance.performFullReconnection(); + print("Переподключение выполнено успешно"); + } catch (e) { + print("Ошибка переподключения: $e"); + } + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Спуф сессии автоматически обновлен до версии $latestVersion', + ), + backgroundColor: Colors.green.shade700, + behavior: SnackBarBehavior.floating, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + margin: const EdgeInsets.all(10), + ), + ); + } + } else if (showUpdateNotification) { + + if (mounted) { + _showUpdateDialog(context, latestVersion); + } + } + } + } catch (e) { + print("Фоновая проверка версии не удалась: $e"); + } + } + + Future _initDeepLinking() async { + _appLinks = AppLinks(); + + Uri? initialUriFromLaunch; + + try { + initialUriFromLaunch = await _appLinks.getInitialLink(); + if (initialUriFromLaunch != null) { + print('Получена ссылка (initial): $initialUriFromLaunch'); + if (mounted) { + _handleJoinLink(initialUriFromLaunch); + } + } + } catch (e) { + print('Ошибка получения initial link: $e'); + } + + _linkSubscription = _appLinks.uriLinkStream.listen((uri) { + print('Получена ссылка (stream): $uri'); + + if (uri == initialUriFromLaunch) { + print('Ссылка из stream совпадает с initial, игнорируем.'); + + initialUriFromLaunch = null; + return; + } + + if (mounted) { + _handleJoinLink(uri); + } + }); + } + + void _handleJoinLink(Uri uri) { + if (uri.host == 'max.ru' && uri.path.startsWith('/join/')) { + final String fullLink = uri.toString(); + final String processedLink = _extractJoinLink(fullLink); + + if (!processedLink.contains('join/')) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Неверный формат ссылки. Ссылка должна содержать "join/"', + ), + backgroundColor: Colors.orange, + behavior: SnackBarBehavior.floating, + margin: EdgeInsets.all(10), + ), + ); + return; + } + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Загрузка информации о группе...'), + behavior: SnackBarBehavior.floating, + margin: EdgeInsets.all(10), + duration: Duration(seconds: 10), + ), + ); + + ApiService.instance.waitUntilOnline().then((_) { + ApiService.instance + .getChatInfoByLink(processedLink) + .then((chatInfo) { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + if (mounted) { + _showJoinConfirmationDialog(chatInfo, processedLink); + } + }) + .catchError((error) { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка: ${error.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + }); + } + } + + void _showJoinConfirmationDialog( + Map chatInfo, + String linkToJoin, + ) { + final String title = chatInfo['title'] ?? 'Без названия'; + final String? iconUrl = chatInfo['baseIconUrl']; + + int joinState = 0; + String? errorMessage; + + showDialog( + context: context, + barrierDismissible: false, + builder: (dialogContext) { + return StatefulBuilder( + builder: (context, setState) { + Widget content; + List actions = []; + + if (joinState == 1) { + content = Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 32), + const CircularProgressIndicator(), + const SizedBox(height: 24), + Text( + 'Присоединение...', + style: Theme.of(context).textTheme.titleLarge, + textAlign: TextAlign.center, + ), + const SizedBox(height: 32), + ], + ); + actions = []; + } else if (joinState == 2) { + content = Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 32), + const Icon( + Icons.check_circle_outline, + color: Colors.green, + size: 60, + ), + const SizedBox(height: 24), + Text( + 'Вы вступили в группу!', + style: Theme.of(context).textTheme.titleLarge, + textAlign: TextAlign.center, + ), + const SizedBox(height: 32), + ], + ); + actions = [ + FilledButton( + child: const Text('Отлично'), + onPressed: () { + Navigator.of(dialogContext).pop(); + }, + ), + ]; + } else if (joinState == 3) { + content = Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 32), + Icon( + Icons.error_outline, + color: Theme.of(context).colorScheme.error, + size: 60, + ), + const SizedBox(height: 24), + Text( + 'Ошибка', + style: Theme.of(context).textTheme.titleLarge, + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + errorMessage ?? 'Не удалось вступить в группу.', + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodySmall, + ), + const SizedBox(height: 32), + ], + ); + actions = [ + TextButton( + child: const Text('Закрыть'), + onPressed: () { + Navigator.of(dialogContext).pop(); + }, + ), + ]; + } else { + content = Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (iconUrl != null && iconUrl.isNotEmpty) + CircleAvatar( + radius: 60, + backgroundImage: NetworkImage(iconUrl), + onBackgroundImageError: (e, s) { + print("Ошибка загрузки аватара: $e"); + }, + backgroundColor: Colors.grey.shade300, + ) + else + CircleAvatar( + radius: 60, + backgroundColor: Colors.grey.shade300, + child: const Icon( + Icons.group, + size: 60, + color: Colors.white, + ), + ), + const SizedBox(height: 24), + Text( + title, + style: Theme.of(context).textTheme.titleLarge, + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + const Text( + 'Вы действительно хотите вступить в эту группу?', + textAlign: TextAlign.center, + ), + ], + ); + actions = [ + TextButton( + child: const Text('Отмена'), + onPressed: () { + Navigator.of(dialogContext).pop(); + }, + ), + FilledButton( + child: const Text('Вступить'), + onPressed: () async { + setState(() { + joinState = 1; + }); + + try { + await ApiService.instance.joinGroupByLink(linkToJoin); + + setState(() { + joinState = 2; + }); + + ApiService.instance.clearChatsCache(); + + await Future.delayed(const Duration(seconds: 2)); + if (mounted) { + Navigator.of(dialogContext).pop(); + } + } catch (e) { + setState(() { + joinState = 3; + errorMessage = e.toString().replaceFirst( + "Exception: ", + "", + ); + }); + } + }, + ), + ]; + } + + return AlertDialog( + title: joinState == 0 ? const Text('Вступить в группу?') : null, + content: AnimatedSize( + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + child: AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + transitionBuilder: + (Widget child, Animation animation) { + final slideAnimation = + Tween( + begin: const Offset(0, 0.2), + end: Offset.zero, + ).animate( + CurvedAnimation( + parent: animation, + curve: Curves.easeOutQuart, + ), + ); + + return FadeTransition( + opacity: animation, + child: SlideTransition( + position: slideAnimation, + child: child, + ), + ); + }, + child: Container( + key: ValueKey(joinState), + child: content, + ), + ), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + actionsAlignment: MainAxisAlignment.center, + actions: actions, + ); + }, + ); + }, + ); + } + + String _extractJoinLink(String inputLink) { + final link = inputLink.trim(); + + if (link.startsWith('join/')) { + print('Ссылка уже в правильном формате: $link'); + return link; + } + + final joinIndex = link.indexOf('join/'); + if (joinIndex != -1) { + final extractedLink = link.substring(joinIndex); + print('Извлечена ссылка из полной ссылки: $link -> $extractedLink'); + return extractedLink; + } + + print('Не найдено "join/" в ссылке: $link'); + return link; + } + + void _handleGroupJoinSuccess(Map message) { + final payload = message['payload']; + final chat = payload['chat']; + final chatTitle = chat?['title'] ?? 'Группа'; + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Успешно присоединились к группе "$chatTitle"!'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + void _handleGroupJoinError(Map message) { + final errorPayload = message['payload']; + String errorMessage = 'Неизвестная ошибка'; + if (errorPayload != null) { + if (errorPayload['localizedMessage'] != null) { + errorMessage = errorPayload['localizedMessage']; + } else if (errorPayload['message'] != null) { + errorMessage = errorPayload['message']; + } + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + Future _checkAndConnect() async { + final hasToken = await ApiService.instance.hasToken(); + if (hasToken) { + print("В HomeScreen: токен найден, проверяем подключение..."); + try { + await ApiService.instance.connect(); + print("В HomeScreen: подключение к WebSocket успешно"); + } catch (e) { + print("В HomeScreen: ошибка подключения к WebSocket: $e"); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка подключения к серверу: $e'), + backgroundColor: Colors.red, + duration: const Duration(seconds: 5), + ), + ); + } + } + } else { + print("В HomeScreen: токен не найден, пользователь не авторизован"); + } + } + + void _handleSessionTerminated(String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + backgroundColor: Theme.of(context).colorScheme.error, + duration: const Duration(seconds: 3), + ), + ); + Future.delayed(const Duration(seconds: 2), () { + if (mounted) { + Navigator.of(context).pushAndRemoveUntil( + PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) => + const PhoneEntryScreen(), + transitionsBuilder: + (context, animation, secondaryAnimation, child) { + return FadeTransition(opacity: animation, child: child); + }, + transitionDuration: const Duration(milliseconds: 500), + ), + (route) => false, + ); + } + }); + } + + void _showReconnectionScreen() { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ReconnectionScreen(), + fullscreenDialog: true, + ), + ); + } + + void _handleInvalidToken(String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + backgroundColor: Colors.red, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const PhoneEntryScreen()), + (route) => false, + ); + } + + @override + void dispose() { + _connectionSubscription?.cancel(); + _messageSubscription?.cancel(); + _linkSubscription?.cancel(); + super.dispose(); + } + + static const double kDesktopLayoutBreakpoint = 700.0; + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, themeProvider, child) { + return LayoutBuilder( + builder: (context, constraints) { + final shouldUseDesktopLayout = + themeProvider.useDesktopLayout && + constraints.maxWidth >= kDesktopLayoutBreakpoint; + + if (shouldUseDesktopLayout) { + return const _DesktopLayout(); + } else { + return const ChatsScreen(); + } + }, + ); + }, + ); + } +} + +class _DesktopLayout extends StatefulWidget { + const _DesktopLayout({super.key}); + + @override + State<_DesktopLayout> createState() => _DesktopLayoutState(); +} + +class _DesktopLayoutState extends State<_DesktopLayout> { + Chat? _selectedChat; + Contact? _selectedContact; + bool _isGroupChat = false; + bool _isChannel = false; + int? _participantCount; + Profile? _myProfile; + bool _isProfileLoading = true; + + final ValueNotifier _leftPanelWidth = ValueNotifier(320.0); + static const double _minPanelWidth = 280.0; + static const double _maxPanelWidth = 500.0; + + @override + void initState() { + super.initState(); + _loadMyProfile(); + } + + + Future _loadMyProfile() async { + if (!mounted) return; + setState(() => _isProfileLoading = true); + try { + final result = await ApiService.instance.getChatsAndContacts( + force: false, + ); + if (mounted) { + final profileJson = result['profile']; + if (profileJson != null) { + setState(() { + _myProfile = Profile.fromJson(profileJson); + _isProfileLoading = false; + }); + } + } + } catch (e) { + if (mounted) setState(() => _isProfileLoading = false); + print("Ошибка загрузки профиля в _DesktopLayout: $e"); + } + } + + + void _onChatSelected( + Chat chat, + Contact contact, + bool isGroup, + bool isChannel, + int? participantCount, + ) { + setState(() { + _selectedChat = chat; + _selectedContact = contact; + _isGroupChat = isGroup; + _isChannel = isChannel; + _participantCount = participantCount; + }); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + body: Row( + children: [ + ValueListenableBuilder( + valueListenable: _leftPanelWidth, + builder: (context, width, child) { + return SizedBox( + width: width, + child: ChatsScreen(onChatSelected: _onChatSelected), + ); + }, + ), + + GestureDetector( + onPanUpdate: (details) { + final newWidth = _leftPanelWidth.value + details.delta.dx; + if (newWidth >= _minPanelWidth && newWidth <= _maxPanelWidth) { + _leftPanelWidth.value = newWidth; + } + }, + child: MouseRegion( + cursor: SystemMouseCursors.resizeLeftRight, + child: Container( + width: 4.0, + color: colors.outline.withOpacity(0.3), + ), + ), + ), + + Expanded( + child: + (_selectedChat == null || + _selectedContact == null || + _isProfileLoading) + ? Center( + child: _isProfileLoading + ? const CircularProgressIndicator() + : Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.message, + size: 80, + color: colors.primary.withOpacity(0.5), + ), + const SizedBox(height: 16), + Text( + 'Выберите чат, чтобы начать общение', + style: TextStyle( + fontSize: 16, + color: colors.onSurfaceVariant, + ), + ), + ], + ), + ) + : ChatScreen( + key: ValueKey(_selectedChat!.id), + chatId: _selectedChat!.id, + contact: _selectedContact!, + myId: _myProfile?.id ?? 0, + isGroupChat: _isGroupChat, + isChannel: _isChannel, + participantCount: _participantCount, + isDesktopMode: true, + onChatUpdated: () {}, + ), + ), + ], + ), + ); + } +} diff --git a/lib/image_cache_service.dart b/lib/image_cache_service.dart new file mode 100644 index 0000000..6a92730 --- /dev/null +++ b/lib/image_cache_service.dart @@ -0,0 +1,266 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:path/path.dart' as path; +import 'package:http/http.dart' as http; +import 'package:cached_network_image/cached_network_image.dart'; + + +class ImageCacheService { + ImageCacheService._privateConstructor(); + static final ImageCacheService instance = + ImageCacheService._privateConstructor(); + + static const String _cacheDirectoryName = 'image_cache'; + static const Duration _cacheExpiration = Duration( + days: 7, + ); // Кеш изображений на 7 дней + late Directory _cacheDirectory; + + + Future initialize() async { + final appDir = await getApplicationDocumentsDirectory(); + _cacheDirectory = Directory(path.join(appDir.path, _cacheDirectoryName)); + + if (!_cacheDirectory.existsSync()) { + await _cacheDirectory.create(recursive: true); + } + + + await _cleanupExpiredCache(); + } + + + String getCachedImagePath(String url) { + final fileName = _generateFileName(url); + return path.join(_cacheDirectory.path, fileName); + } + + + bool isImageCached(String url) { + final file = File(getCachedImagePath(url)); + return file.existsSync(); + } + + + Future loadImage(String url, {bool forceRefresh = false}) async { + if (!forceRefresh && isImageCached(url)) { + final cachedFile = File(getCachedImagePath(url)); + if (await _isFileValid(cachedFile)) { + return cachedFile; + } else { + + await cachedFile.delete(); + } + } + + try { + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + final file = File(getCachedImagePath(url)); + await file.writeAsBytes(response.bodyBytes); + + + await _updateFileAccessTime(file); + + return file; + } + } catch (e) { + print('Ошибка загрузки изображения $url: $e'); + } + + return null; + } + + + Future loadImageAsBytes( + String url, { + bool forceRefresh = false, + }) async { + final file = await loadImage(url, forceRefresh: forceRefresh); + if (file != null) { + return await file.readAsBytes(); + } + return null; + } + + + Future preloadImage(String url) async { + await loadImage(url); + } + + + Future preloadContactAvatar(String? photoUrl) async { + if (photoUrl != null && photoUrl.isNotEmpty) { + await preloadImage(photoUrl); + } + } + + + Future preloadProfileAvatar(String? photoUrl) async { + if (photoUrl != null && photoUrl.isNotEmpty) { + await preloadImage(photoUrl); + } + } + + + Future preloadContactAvatars(List photoUrls) async { + final futures = photoUrls + .where((url) => url != null && url.isNotEmpty) + .map((url) => preloadImage(url!)) + .toList(); + + if (futures.isNotEmpty) { + await Future.wait(futures); + } + } + + + Future clearCache() async { + if (_cacheDirectory.existsSync()) { + await _cacheDirectory.delete(recursive: true); + await _cacheDirectory.create(recursive: true); + } + } + + + Future getCacheSize() async { + int totalSize = 0; + if (_cacheDirectory.existsSync()) { + await for (final entity in _cacheDirectory.list(recursive: true)) { + if (entity is File) { + totalSize += await entity.length(); + } + } + } + return totalSize; + } + + + Future getCacheFileCount() async { + int count = 0; + if (_cacheDirectory.existsSync()) { + await for (final entity in _cacheDirectory.list(recursive: true)) { + if (entity is File) { + count++; + } + } + } + return count; + } + + + Future _cleanupExpiredCache() async { + if (!_cacheDirectory.existsSync()) return; + + await for (final entity in _cacheDirectory.list(recursive: true)) { + if (entity is File && await _isFileExpired(entity)) { + await entity.delete(); + } + } + } + + + Future _isFileValid(File file) async { + if (!file.existsSync()) return false; + + + final stat = await file.stat(); + final age = DateTime.now().difference(stat.modified); + + return age < _cacheExpiration; + } + + + Future _isFileExpired(File file) async { + if (!file.existsSync()) return false; + + final stat = await file.stat(); + final age = DateTime.now().difference(stat.modified); + + return age >= _cacheExpiration; + } + + + Future _updateFileAccessTime(File file) async { + + try { + await file.setLastModified(DateTime.now()); + } catch (e) { + + } + } + + + String _generateFileName(String url) { + + final hash = url.hashCode.abs().toString(); + final extension = path.extension(url).isNotEmpty + ? path.extension(url) + : '.jpg'; // По умолчанию jpg + + return '$hash$extension'; + } + + + Future> getCacheStats() async { + final size = await getCacheSize(); + final fileCount = await getCacheFileCount(); + + return { + 'cache_size_bytes': size, + 'cache_size_mb': (size / (1024 * 1024)).toStringAsFixed(2), + 'file_count': fileCount, + 'cache_directory': _cacheDirectory.path, + }; + } +} + + +extension CachedImageExtension on String { + + Widget getCachedNetworkImage({ + Key? key, + double? width, + double? height, + BoxFit? fit, + Widget? placeholder, + Widget? errorWidget, + Duration? fadeInDuration, + bool useMemoryCache = true, + }) { + return CachedNetworkImage( + key: key, + imageUrl: this, + width: width, + height: height, + fit: fit, + placeholder: (context, url) => + placeholder ?? + Container( + width: width, + height: height, + color: Colors.grey[300], + child: const Icon(Icons.image, color: Colors.grey), + ), + errorWidget: (context, url, error) => + errorWidget ?? + Container( + width: width, + height: height, + color: Colors.grey[300], + child: const Icon(Icons.broken_image, color: Colors.grey), + ), + fadeInDuration: fadeInDuration ?? const Duration(milliseconds: 300), + useOldImageOnUrlChange: true, + memCacheWidth: useMemoryCache ? (width ?? 200).toInt() : null, + memCacheHeight: useMemoryCache ? (height ?? 200).toInt() : null, + ); + } + + + Future preloadImage() async { + await ImageCacheService.instance.loadImage(this); + } +} diff --git a/lib/join_group_screen.dart b/lib/join_group_screen.dart new file mode 100644 index 0000000..a58ff15 --- /dev/null +++ b/lib/join_group_screen.dart @@ -0,0 +1,341 @@ + + +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; + +class JoinGroupScreen extends StatefulWidget { + const JoinGroupScreen({super.key}); + + @override + State createState() => _JoinGroupScreenState(); +} + +class _JoinGroupScreenState extends State { + final TextEditingController _linkController = TextEditingController(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + } + + @override + void dispose() { + _linkController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'group_join_success') { + setState(() { + _isLoading = false; + }); + + final payload = message['payload']; + final chat = payload['chat']; + final chatTitle = chat?['title'] ?? 'Группа'; + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Успешно присоединились к группе "$chatTitle"!'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + + + Navigator.of(context).pop(); + } + + + if (message['cmd'] == 3 && message['opcode'] == 57) { + setState(() { + _isLoading = false; + }); + + final errorPayload = message['payload']; + String errorMessage = 'Неизвестная ошибка'; + if (errorPayload != null) { + if (errorPayload['localizedMessage'] != null) { + errorMessage = errorPayload['localizedMessage']; + } else if (errorPayload['message'] != null) { + errorMessage = errorPayload['message']; + } + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + } + + + String _extractJoinLink(String inputLink) { + final link = inputLink.trim(); + + + if (link.startsWith('join/')) { + print('Ссылка уже в правильном формате: $link'); + return link; + } + + + final joinIndex = link.indexOf('join/'); + if (joinIndex != -1) { + final extractedLink = link.substring(joinIndex); + print('Извлечена ссылка из полной ссылки: $link -> $extractedLink'); + return extractedLink; + } + + + print('Не найдено "join/" в ссылке: $link'); + return link; + } + + void _joinGroup() async { + final inputLink = _linkController.text.trim(); + + if (inputLink.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите ссылку на группу'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + + final processedLink = _extractJoinLink(inputLink); + + + if (!processedLink.contains('join/')) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text( + 'Неверный формат ссылки. Ссылка должна содержать "join/"', + ), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + await ApiService.instance.joinGroupByLink(processedLink); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка присоединения к группе: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Присоединиться к группе'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + ), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.group_add, color: colors.primary), + const SizedBox(width: 8), + Text( + 'Присоединение к группе', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + 'Введите ссылку на группу, чтобы присоединиться к ней. ' + 'Можно вводить как полную ссылку (https://max.ru/join/...), ' + 'так и короткую (join/...).', + style: TextStyle(color: colors.onSurfaceVariant), + ), + ], + ), + ), + + const SizedBox(height: 24), + + + Text( + 'Ссылка на группу', + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + + TextField( + controller: _linkController, + decoration: InputDecoration( + labelText: 'Ссылка на группу', + hintText: 'https://max.ru/join/ABC123DEF456GHI789JKL', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.link), + ), + maxLines: 3, + ), + const SizedBox(height: 8), + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + size: 16, + color: colors.primary, + ), + const SizedBox(width: 8), + Text( + 'Формат ссылки:', + style: TextStyle( + fontWeight: FontWeight.w600, + color: colors.primary, + fontSize: 14, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + '• Ссылка должна содержать "join/"\n' + '• После "join/" должен идти уникальный идентификатор группы\n' + '• Примеры:\n' + ' - https://max.ru/join/ABC123DEF456GHI789JKL\n' + ' - join/ABC123DEF456GHI789JKL', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 13, + height: 1.4, + ), + ), + ], + ), + ), + const SizedBox(height: 24), + + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _joinGroup, + icon: _isLoading + ? SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + ) + : const Icon(Icons.group_add), + label: Text( + _isLoading + ? 'Присоединение...' + : 'Присоединиться к группе', + ), + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + ], + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } +} diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..3b17d98 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,243 @@ + + +import 'package:flutter/material.dart'; +import 'package:dynamic_color/dynamic_color.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/date_symbol_data_local.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'home_screen.dart'; +import 'phone_entry_screen.dart'; +import 'theme_provider.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; +import 'api_service.dart'; +import 'connection_lifecycle_manager.dart'; +import 'services/cache_service.dart'; +import 'services/avatar_cache_service.dart'; +import 'services/chat_cache_service.dart'; +import 'services/version_checker.dart'; + +final GlobalKey navigatorKey = GlobalKey(); + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await initializeDateFormatting(); + + + print("Инициализируем сервисы кеширования..."); + await CacheService().initialize(); + await AvatarCacheService().initialize(); + await ChatCacheService().initialize(); + print("Сервисы кеширования инициализированы"); + + + final hasToken = await ApiService.instance.hasToken(); + print("При запуске приложения токен ${hasToken ? 'найден' : 'не найден'}"); + + + if (hasToken) { + print("Инициируем подключение к WebSocket при запуске..."); + ApiService.instance.connect(); + } + + runApp( + ChangeNotifierProvider( + create: (context) => ThemeProvider(), + child: ConnectionLifecycleManager(child: MyApp(hasToken: hasToken)), + ), + ); +} + +class MyApp extends StatelessWidget { + final bool hasToken; + + const MyApp({super.key, required this.hasToken}); + + @override + Widget build(BuildContext context) { + final themeProvider = context.watch(); + + return DynamicColorBuilder( + builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) { + + final Color accentColor = + (themeProvider.appTheme == AppTheme.system && lightDynamic != null) + ? lightDynamic.primary + : themeProvider.accentColor; + final ThemeData baseLightTheme = ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.light, + dynamicSchemeVariant: DynamicSchemeVariant.tonalSpot, + ), + useMaterial3: true, + appBarTheme: AppBarTheme( + titleTextStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.light, + ).onSurface, // ← Используем цвет onSurface из цветовой схемы + ), + ), + ); + + final ThemeData baseDarkTheme = ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.dark, + dynamicSchemeVariant: DynamicSchemeVariant.tonalSpot, + ), + useMaterial3: true, + appBarTheme: AppBarTheme( + titleTextStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: ColorScheme.fromSeed( + seedColor: accentColor, + brightness: Brightness.dark, + ).onSurface, // ← Используем цвет onSurface из цветовой схемы + ), + ), + ); + final ThemeData oledTheme = baseDarkTheme.copyWith( + scaffoldBackgroundColor: Colors.black, + colorScheme: baseDarkTheme.colorScheme.copyWith( + surface: Colors.black, + surfaceContainerLowest: Colors.black, + surfaceContainerLow: Colors.black, + ), + navigationBarTheme: NavigationBarThemeData( + backgroundColor: Colors.black, + indicatorColor: accentColor.withOpacity(0.4), + labelTextStyle: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.selected)) { + return TextStyle( + color: accentColor, + fontSize: 12, + fontWeight: FontWeight.bold, + ); + } + return const TextStyle(color: Colors.grey, fontSize: 12); + }), + iconTheme: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.selected)) { + return IconThemeData(color: accentColor); + } + return const IconThemeData(color: Colors.grey); + }), + ), + ); + + final ThemeData activeDarkTheme = + themeProvider.appTheme == AppTheme.black + ? oledTheme + : baseDarkTheme; + + return MaterialApp( + title: 'Komet', + navigatorKey: navigatorKey, + builder: (context, child) { + final showHud = themeProvider.debugShowPerformanceOverlay; + if (!showHud) return child ?? const SizedBox.shrink(); + return Stack( + children: [ + if (child != null) child, + const Positioned(top: 8, right: 56, child: _MiniFpsHud()), + ], + ); + }, + theme: baseLightTheme, + darkTheme: activeDarkTheme, + themeMode: themeProvider.themeMode, + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [Locale('ru'), Locale('en')], + locale: const Locale('ru'), + + home: hasToken ? const HomeScreen() : const PhoneEntryScreen(), + ); + }, + ); + } +} + + +class _MiniFpsHud extends StatefulWidget { + const _MiniFpsHud(); + + @override + State<_MiniFpsHud> createState() => _MiniFpsHudState(); +} + +class _MiniFpsHudState extends State<_MiniFpsHud> { + final List _timings = []; + static const int _sampleSize = 60; + double _fps = 0.0; + double _avgMs = 0.0; + + @override + void initState() { + super.initState(); + SchedulerBinding.instance.addTimingsCallback(_onTimings); + } + + @override + void dispose() { + SchedulerBinding.instance.removeTimingsCallback(_onTimings); + super.dispose(); + } + + void _onTimings(List timings) { + _timings.addAll(timings); + if (_timings.length > _sampleSize) { + _timings.removeRange(0, _timings.length - _sampleSize); + } + if (_timings.isEmpty) return; + final double avg = + _timings + .map((t) => (t.totalSpan.inMicroseconds) / 1000.0) + .fold(0.0, (a, b) => a + b) / + _timings.length; + setState(() { + _avgMs = avg; + _fps = avg > 0 ? (1000.0 / avg) : 0.0; + }); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), + decoration: BoxDecoration( + color: theme.surface.withOpacity(0.85), + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow(color: Colors.black.withOpacity(0.2), blurRadius: 8), + ], + ), + child: DefaultTextStyle( + style: TextStyle( + fontSize: 12, + color: theme.onSurface, + fontFeatures: const [FontFeature.tabularFigures()], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text('FPS: ${_fps.toStringAsFixed(0)}'), + const SizedBox(height: 2), + Text('${_avgMs.toStringAsFixed(1)} ms/frame'), + ], + ), + ), + ); + } +} diff --git a/lib/manage_account_screen.dart b/lib/manage_account_screen.dart new file mode 100644 index 0000000..1dd9c2f --- /dev/null +++ b/lib/manage_account_screen.dart @@ -0,0 +1,398 @@ + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/profile.dart'; +import 'package:gwid/phone_entry_screen.dart'; +import 'package:image_picker/image_picker.dart'; +import 'dart:io'; + +class ManageAccountScreen extends StatefulWidget { + final Profile? myProfile; + const ManageAccountScreen({super.key, this.myProfile}); + + @override + State createState() => _ManageAccountScreenState(); +} + +class _ManageAccountScreenState extends State { + late final TextEditingController _firstNameController; + late final TextEditingController _lastNameController; + late final TextEditingController _descriptionController; + final GlobalKey _formKey = GlobalKey(); + + @override + void initState() { + super.initState(); + _firstNameController = TextEditingController( + text: widget.myProfile?.firstName ?? '', + ); + _lastNameController = TextEditingController( + text: widget.myProfile?.lastName ?? '', + ); + _descriptionController = TextEditingController( + text: widget.myProfile?.description ?? '', + ); + } + + void _saveProfile() { + if (!_formKey.currentState!.validate()) { + return; + } + + ApiService.instance.updateProfileText( + _firstNameController.text.trim(), + _lastNameController.text.trim(), + _descriptionController.text.trim(), + ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Профиль успешно сохранен"), + behavior: SnackBarBehavior.floating, + duration: Duration(seconds: 2), + ), + ); + } + + void _logout() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Выйти из аккаунта?'), + content: const Text('Вы уверены, что хотите выйти из аккаунта?'), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + style: FilledButton.styleFrom( + backgroundColor: Colors.red.shade400, + foregroundColor: Colors.white, + ), + child: const Text('Выйти'), + ), + ], + ), + ); + + if (confirmed == true && mounted) { + try { + await ApiService.instance.logout(); + if (mounted) { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const PhoneEntryScreen()), + (route) => false, + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка выхода: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + behavior: SnackBarBehavior.floating, + ), + ); + } + } + } + } + + void _pickAndUpdateProfilePhoto() async { + final ImagePicker picker = ImagePicker(); + + final XFile? image = await picker.pickImage(source: ImageSource.gallery); + + + if (image != null) { + + File imageFile = File(image.path); + + + + + + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Фотография профиля обновляется..."), + behavior: SnackBarBehavior.floating, + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Scaffold( + appBar: AppBar( + title: const Text("Изменить профиль"), + centerTitle: true, + scrolledUnderElevation: 0, + actions: [ + TextButton( + onPressed: _saveProfile, + child: const Text( + "Сохранить", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + ), + ], + ), + body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 20.0), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildAvatarSection(theme), + const SizedBox(height: 32), + + + Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Основная информация", + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 20), + TextFormField( + controller: _firstNameController, + maxLength: 60, // Ограничение по символам + decoration: _buildInputDecoration( + "Имя", + Icons.person_outline, + ).copyWith(counterText: ""), // Скрываем счетчик + validator: (value) => + value!.isEmpty ? 'Введите ваше имя' : null, + ), + const SizedBox(height: 16), + TextFormField( + controller: _lastNameController, + maxLength: 60, // Ограничение по символам + decoration: _buildInputDecoration( + "Фамилия", + Icons.person_outline, + ).copyWith(counterText: ""), // Скрываем счетчик + ), + ], + ), + ), + ), + const SizedBox(height: 24), + + + Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Дополнительно", + style: theme.textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 20), + TextFormField( + controller: _descriptionController, + maxLines: 4, + maxLength: 400, + decoration: _buildInputDecoration( + "О себе", + Icons.edit_note_outlined, + alignLabel: true, + ), + ), + ], + ), + ), + ), + const SizedBox(height: 24), + + + if (widget.myProfile != null) + Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + clipBehavior: Clip.antiAlias, + child: Column( + children: [ + _buildInfoTile( + icon: Icons.phone_outlined, + title: "Телефон", + subtitle: widget.myProfile!.formattedPhone, + ), + const Divider(height: 1), + _buildTappableInfoTile( + icon: Icons.tag, + title: "Ваш ID", + subtitle: widget.myProfile!.id.toString(), + onTap: () { + Clipboard.setData( + ClipboardData( + text: widget.myProfile!.id.toString(), + ), + ); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('ID скопирован в буфер обмена'), + behavior: SnackBarBehavior.floating, + ), + ); + }, + ), + ], + ), + ), + + const SizedBox(height: 32), + _buildLogoutButton(), + ], + ), + ), + ), + ); + } + + + + Widget _buildAvatarSection(ThemeData theme) { + return Center( + child: GestureDetector( + + onTap: _pickAndUpdateProfilePhoto, // 2. Вызываем метод при нажатии + child: Stack( + children: [ + CircleAvatar( + radius: 60, + backgroundColor: theme.colorScheme.secondaryContainer, + backgroundImage: widget.myProfile?.photoBaseUrl != null + ? NetworkImage(widget.myProfile!.photoBaseUrl!) + : null, + child: widget.myProfile?.photoBaseUrl == null + ? Icon( + Icons.person, + size: 60, + color: theme.colorScheme.onSecondaryContainer, + ) + : null, + ), + Positioned( + bottom: 4, + right: 4, + child: Container( + decoration: BoxDecoration( + color: theme.colorScheme.primary, + shape: BoxShape.circle, + ), + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon(Icons.camera_alt, color: Colors.white, size: 20), + ), + ), + ), + ], + ), + ), + ); + } + + InputDecoration _buildInputDecoration( + String label, + IconData icon, { + bool alignLabel = false, + }) { + + final prefixIcon = (label == "О себе") + ? Padding( + padding: const EdgeInsets.only(bottom: 60), // Смещаем иконку вверх + child: Icon(icon), + ) + : Icon(icon); + + return InputDecoration( + labelText: label, + prefixIcon: prefixIcon, + border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + alignLabelWithHint: alignLabel, + ); + } + + Widget _buildInfoTile({ + required IconData icon, + required String title, + required String subtitle, + }) { + return ListTile( + leading: Icon(icon, color: Theme.of(context).colorScheme.primary), + title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + subtitle: Text(subtitle), + ); + } + + Widget _buildTappableInfoTile({ + required IconData icon, + required String title, + required String subtitle, + required VoidCallback onTap, + }) { + return InkWell( + onTap: onTap, + child: ListTile( + leading: Icon(icon, color: Theme.of(context).colorScheme.primary), + title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)), + subtitle: Text(subtitle), + trailing: const Icon(Icons.copy_outlined, size: 20), + ), + ); + } + + Widget _buildLogoutButton() { + return OutlinedButton.icon( + icon: const Icon(Icons.logout), + label: const Text('Выйти из аккаунта'), + onPressed: _logout, + style: OutlinedButton.styleFrom( + foregroundColor: Colors.red.shade400, + side: BorderSide(color: Colors.red.shade200), + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + ), + ); + } + + @override + void dispose() { + _firstNameController.dispose(); + _lastNameController.dispose(); + _descriptionController.dispose(); + super.dispose(); + } +} diff --git a/lib/models/attach.dart b/lib/models/attach.dart new file mode 100644 index 0000000..c9e2a64 --- /dev/null +++ b/lib/models/attach.dart @@ -0,0 +1,116 @@ + +enum AttachTypes { call, control, inlineKeyboard, share } + +abstract class Attachment { + final AttachTypes type; + + Attachment(this.type); + + factory Attachment.fromJson(Map json) { + final typeString = json['_type'] as String; + switch (typeString) { + case 'CALL': + return CallAttachment.fromJson(json); + case 'CONTROL': + return ControlAttachment.fromJson(json); + case 'INLINE_KEYBOARD': + return InlineKeyboardAttachment.fromJson(json); + case 'SHARE': + return ShareAttachment.fromJson(json); + default: + throw ArgumentError('Unknown attachment type: $typeString'); + } + } +} + +class CallAttachment extends Attachment { + final int duration; + final String conversationId; + final String hangupType; + final String joinLink; + final String callType; + + CallAttachment({ + required this.duration, + required this.conversationId, + required this.hangupType, + required this.joinLink, + required this.callType, + }) : super(AttachTypes.call); + + factory CallAttachment.fromJson(Map json) { + return CallAttachment( + duration: json['duration'] as int, + conversationId: json['conversationId'] as String, + hangupType: json['hangupType'] as String, + joinLink: json['joinLink'] as String, + callType: json['callType'] as String, + ); + } +} + +class ControlAttachment extends Attachment { + final String event; + + ControlAttachment({required this.event}) : super(AttachTypes.control); + + factory ControlAttachment.fromJson(Map json) { + return ControlAttachment(event: json['event'] as String); + } +} + +class InlineKeyboardAttachment extends Attachment { + final Map keyboard; + final String callbackId; + + InlineKeyboardAttachment({required this.keyboard, required this.callbackId}) + : super(AttachTypes.inlineKeyboard); + + factory InlineKeyboardAttachment.fromJson(Map json) { + return InlineKeyboardAttachment( + keyboard: json['keyboard'] as Map, + callbackId: json['callbackId'] as String, + ); + } +} + +class ShareAttachment extends Attachment { + final Map image; + final String description; + final bool contentLevel; + final int shareId; + final String title; + final String url; + + ShareAttachment({ + required this.image, + required this.description, + required this.contentLevel, + required this.shareId, + required this.title, + required this.url, + }) : super(AttachTypes.share); + + factory ShareAttachment.fromJson(Map json) { + return ShareAttachment( + image: json['image'] as Map, + description: json['description'] as String, + contentLevel: json['contentLevel'] as bool, + shareId: json['shareId'] as int, + title: json['title'] as String, + url: json['url'] as String, + ); + } +} + +class AttachmentsParser { + static List parse(List jsonList) { + return jsonList.map((jsonItem) { + if (jsonItem is Map) { + return Attachment.fromJson(jsonItem); + } else { + throw ArgumentError('Invalid JSON item in the list: $jsonItem'); + } + }).toList(); + } +} diff --git a/lib/models/channel.dart b/lib/models/channel.dart new file mode 100644 index 0000000..c8e9fb8 --- /dev/null +++ b/lib/models/channel.dart @@ -0,0 +1,37 @@ +class Channel { + final int id; + final String name; + final String? description; + final String? photoBaseUrl; + final String? link; + final String? webApp; + final List options; + final int updateTime; + + Channel({ + required this.id, + required this.name, + this.description, + this.photoBaseUrl, + this.link, + this.webApp, + required this.options, + required this.updateTime, + }); + + factory Channel.fromJson(Map json) { + final names = json['names'] as List?; + final nameData = names?.isNotEmpty == true ? names![0] : null; + + return Channel( + id: json['id'] as int, + name: nameData?['name'] as String? ?? 'Неизвестный канал', + description: nameData?['description'] as String?, + photoBaseUrl: json['baseUrl'] as String?, + link: json['link'] as String?, + webApp: json['webApp'] as String?, + options: List.from(json['options'] ?? []), + updateTime: json['updateTime'] as int? ?? 0, + ); + } +} diff --git a/lib/models/chat.dart b/lib/models/chat.dart new file mode 100644 index 0000000..600129a --- /dev/null +++ b/lib/models/chat.dart @@ -0,0 +1,99 @@ +import 'package:gwid/models/message.dart'; + +class Chat { + final int id; + final int ownerId; + final Message lastMessage; + final List participantIds; + final int newMessages; + final String? title; // Название группы + final String? type; // Тип чата (DIALOG, CHAT) + final String? baseIconUrl; // URL иконки группы + final String? description; + final int? participantsCount; + + Chat({ + required this.id, + required this.ownerId, + required this.lastMessage, + required this.participantIds, + required this.newMessages, + this.title, + this.type, + this.baseIconUrl, + this.description, + this.participantsCount, + }); + + factory Chat.fromJson(Map json) { + var participantsMap = json['participants'] as Map? ?? {}; + List participantIds = participantsMap.keys + .map((id) => int.parse(id)) + .toList(); + + + Message lastMessage; + if (json['lastMessage'] != null) { + lastMessage = Message.fromJson(json['lastMessage']); + } else { + lastMessage = Message( + id: 'empty', + senderId: 0, + time: DateTime.now().millisecondsSinceEpoch, + text: '', + cid: null, + attaches: [], + ); + } + + return Chat( + id: json['id'] ?? 0, + ownerId: json['owner'] ?? 0, + lastMessage: lastMessage, + participantIds: participantIds, + newMessages: json['newMessages'] ?? 0, + title: json['title'], + type: json['type'], + baseIconUrl: json['baseIconUrl'], + description: json['description'], + participantsCount: json['participantsCount'], + ); + } + + + bool get isGroup => type == 'CHAT' || participantIds.length > 2; + + List get groupParticipantIds => participantIds; + + int get onlineParticipantsCount => participantIds.length; // Упрощенная версия + + String get displayTitle { + if (title != null && title!.isNotEmpty) { + return title!; + } + if (isGroup) { + return 'Группа ${participantIds.length}'; + } + return 'Чат'; + } + + Chat copyWith({ + Message? lastMessage, + int? newMessages, + String? title, + String? type, + String? baseIconUrl, + }) { + return Chat( + id: id, + ownerId: ownerId, + lastMessage: lastMessage ?? this.lastMessage, + participantIds: participantIds, + newMessages: newMessages ?? this.newMessages, + title: title ?? this.title, + type: type ?? this.type, + baseIconUrl: baseIconUrl ?? this.baseIconUrl, + description: description ?? this.description, + ); + } +} diff --git a/lib/models/chat_folder.dart b/lib/models/chat_folder.dart new file mode 100644 index 0000000..ea32f4d --- /dev/null +++ b/lib/models/chat_folder.dart @@ -0,0 +1,83 @@ +class ChatFolder { + final String id; + final String title; + final String? emoji; + final List? include; + final List filters; + final bool hideEmpty; + final List widgets; + final List? favorites; + final Map? filterSubjects; + final List? options; + + ChatFolder({ + required this.id, + required this.title, + this.emoji, + this.include, + required this.filters, + required this.hideEmpty, + required this.widgets, + this.favorites, + this.filterSubjects, + this.options, + }); + + factory ChatFolder.fromJson(Map json) { + return ChatFolder( + id: json['id'], + title: json['title'], + emoji: json['emoji'], + include: json['include'] != null ? List.from(json['include']) : null, + filters: json['filters'] != null + ? List.from(json['filters']) + : [], + hideEmpty: json['hideEmpty'] ?? false, + widgets: + (json['widgets'] as List?) + ?.map((widget) => ChatFolderWidget.fromJson(widget)) + .toList() ?? + [], + favorites: json['favorites'] != null + ? List.from(json['favorites']) + : null, + filterSubjects: json['filterSubjects'], + options: json['options'] != null ? List.from(json['options']) : null, + ); + } +} + +class ChatFolderWidget { + final int id; + final String name; + final String description; + final String? iconUrl; + final String? url; + final String? startParam; + final String? background; + final int? appId; + + ChatFolderWidget({ + required this.id, + required this.name, + required this.description, + this.iconUrl, + this.url, + this.startParam, + this.background, + this.appId, + }); + + factory ChatFolderWidget.fromJson(Map json) { + return ChatFolderWidget( + id: json['id'], + name: json['name'], + description: json['description'], + iconUrl: json['iconUrl'], + url: json['url'], + startParam: json['startParam'], + background: json['background'], + appId: json['appId'], + ); + } +} diff --git a/lib/models/contact.dart b/lib/models/contact.dart new file mode 100644 index 0000000..fd21c14 --- /dev/null +++ b/lib/models/contact.dart @@ -0,0 +1,68 @@ +class Contact { + final int id; + final String name; + final String firstName; + final String lastName; + final String? description; + final String? photoBaseUrl; + final bool isBlocked; + final bool isBlockedByMe; + final int accountStatus; + final String? status; + final List options; + + Contact({ + required this.id, + required this.name, + required this.firstName, + required this.lastName, + this.description, + this.photoBaseUrl, + this.isBlocked = false, + this.isBlockedByMe = false, + this.accountStatus = 0, + this.status, + this.options = const [], + }); + + bool get isBot => options.contains('BOT'); + + bool get isUserBlocked => isBlockedByMe || isBlocked; + + factory Contact.fromJson(Map json) { + final nameData = json['names']?[0]; + + String finalFirstName = ''; + String finalLastName = ''; + String finalName = 'Unknown'; + + if (nameData != null) { + finalFirstName = nameData['firstName'] ?? ''; + finalLastName = nameData['lastName'] ?? ''; + final fullName = '$finalFirstName $finalLastName'.trim(); + finalName = fullName.isNotEmpty + ? fullName + : (nameData['name'] ?? 'Unknown'); + } + + + final status = json['status']; + final isBlocked = status == 'BLOCKED'; + + final isBlockedByMe = status == 'BLOCKED'; + + return Contact( + id: json['id'], + name: finalName, + firstName: finalFirstName, + lastName: finalLastName, + description: json['description'], + photoBaseUrl: json['baseUrl'], + isBlocked: isBlocked, + isBlockedByMe: isBlockedByMe, + accountStatus: json['accountStatus'] ?? 0, + status: json['status'], + options: List.from(json['options'] ?? []), + ); + } +} diff --git a/lib/models/message.dart b/lib/models/message.dart new file mode 100644 index 0000000..53e2f0e --- /dev/null +++ b/lib/models/message.dart @@ -0,0 +1,133 @@ +class Message { + final String id; + final String text; + final int time; + final int senderId; + final String? status; // EDITED, DELETED, etc. + final int? updateTime; // Время последнего редактирования + final List> attaches; + final int? cid; // клиентский id (timestamp) + final Map? reactionInfo; // Информация о реакциях + final Map? link; // Информация об ответе на сообщение + + Message({ + required this.id, + required this.text, + required this.time, + required this.senderId, + this.status, + this.updateTime, + this.attaches = const [], + this.cid, + this.reactionInfo, + this.link, + }); + + factory Message.fromJson(Map json) { + + + + + int senderId; + if (json['sender'] is int) { + senderId = json['sender']; + } else { + + senderId = 0; + } + + + int time; + if (json['time'] is int) { + time = json['time']; + } else { + time = 0; + } + + return Message( + + id: + json['id']?.toString() ?? + 'local_${DateTime.now().millisecondsSinceEpoch}', + text: json['text'] ?? '', + time: time, + senderId: senderId, // Use the new safe logic + status: json['status'], + updateTime: json['updateTime'], + attaches: + (json['attaches'] as List?) + ?.map((e) => (e as Map).cast()) + .toList() ?? + const [], + cid: json['cid'], + reactionInfo: json['reactionInfo'], + link: json['link'], + ); + } + + Message copyWith({ + String? id, + String? text, + int? time, + int? senderId, + String? status, + int? updateTime, + List>? attaches, + int? cid, + Map? reactionInfo, + Map? link, + }) { + return Message( + id: id ?? this.id, + text: text ?? this.text, + time: time ?? this.time, + senderId: senderId ?? this.senderId, + status: status ?? this.status, + updateTime: updateTime ?? this.updateTime, + attaches: attaches ?? this.attaches, + cid: cid ?? this.cid, + reactionInfo: reactionInfo ?? this.reactionInfo, + link: link ?? this.link, + ); + } + + bool get isEdited => status == 'EDITED'; + bool get isDeleted => status == 'DELETED'; + bool get isReply => link != null && link!['type'] == 'REPLY'; + bool get isForwarded => link != null && link!['type'] == 'FORWARD'; + + + + + + + bool canEdit(int currentUserId) { + if (isDeleted) return false; + if (senderId != currentUserId) return false; + if (attaches.isNotEmpty) { + return false; // Нельзя редактировать сообщения с вложениями + } + + + final now = DateTime.now().millisecondsSinceEpoch; + final messageTime = time; + final hoursSinceCreation = (now - messageTime) / (1000 * 60 * 60); + + return hoursSinceCreation <= 24; + } + + Map toJson() { + return { + 'id': id, + 'text': text, + 'time': time, + 'sender': senderId, + 'status': status, + 'updateTime': updateTime, + 'cid': cid, + 'attaches': attaches, + 'link': link, + 'reactionInfo': reactionInfo, + }; + } +} diff --git a/lib/models/profile.dart b/lib/models/profile.dart new file mode 100644 index 0000000..360d03f --- /dev/null +++ b/lib/models/profile.dart @@ -0,0 +1,82 @@ +class Profile { + final int id; + final String phone; + final String firstName; + final String lastName; + final String? description; + final String? photoBaseUrl; + final int photoId; + final int updateTime; + final List options; + final int accountStatus; + final List profileOptions; + + Profile({ + required this.id, + required this.phone, + required this.firstName, + required this.lastName, + this.description, + this.photoBaseUrl, + required this.photoId, + required this.updateTime, + required this.options, + required this.accountStatus, + required this.profileOptions, + }); + + factory Profile.fromJson(Map json) { + + Map profileData; + if (json.containsKey('contact')) { + profileData = json['contact'] as Map; + } else { + + profileData = json; + } + + final names = profileData['names'] as List? ?? []; + final nameData = names.isNotEmpty ? names[0] as Map : {}; + + return Profile( + id: profileData['id'], + phone: profileData['phone'].toString(), + firstName: nameData['firstName'] ?? '', + lastName: nameData['lastName'] ?? '', + description: profileData['description'], + photoBaseUrl: profileData['baseUrl'], + photoId: profileData['photoId'] ?? 0, + updateTime: profileData['updateTime'] ?? 0, + options: List.from(profileData['options'] ?? []), + accountStatus: profileData['accountStatus'] ?? 0, + profileOptions: + (json['profileOptions'] as List?) + ?.map((option) => ProfileOption.fromJson(option)) + .toList() ?? + [], + ); + } + + String get displayName { + final fullName = '$firstName $lastName'.trim(); + return fullName.isNotEmpty ? fullName : 'Пользователь'; + } + + String get formattedPhone { + if (phone.length == 11 && phone.startsWith('7')) { + return '+7 (${phone.substring(1, 4)}) ${phone.substring(4, 7)}-${phone.substring(7, 9)}-${phone.substring(9)}'; + } + return phone; + } +} + +class ProfileOption { + final String key; + final dynamic value; + + ProfileOption({required this.key, required this.value}); + + factory ProfileOption.fromJson(Map json) { + return ProfileOption(key: json['key'], value: json['value']); + } +} diff --git a/lib/otp_screen.dart b/lib/otp_screen.dart new file mode 100644 index 0000000..6bce98b --- /dev/null +++ b/lib/otp_screen.dart @@ -0,0 +1,198 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:pinput/pinput.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/chats_screen.dart'; +import 'package:gwid/password_auth_screen.dart'; + +class OTPScreen extends StatefulWidget { + final String phoneNumber; + final String otpToken; + + const OTPScreen({ + super.key, + required this.phoneNumber, + required this.otpToken, + }); + + @override + State createState() => _OTPScreenState(); +} + +class _OTPScreenState extends State { + final TextEditingController _pinController = TextEditingController(); + final FocusNode _pinFocusNode = FocusNode(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _apiSubscription = ApiService.instance.messages.listen((message) { + + if (message['type'] == 'password_required' && mounted) { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const PasswordAuthScreen(), + ), + ); + } + }); + return; + } + + if (message['opcode'] == 18 && mounted) { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() => _isLoading = false); + } + }); + + final payload = message['payload']; + print('Полный payload при авторизации: $payload'); + if (payload != null && + payload['tokenAttrs']?['LOGIN']?['token'] != null) { + final String finalToken = payload['tokenAttrs']['LOGIN']['token']; + final userId = payload['tokenAttrs']?['LOGIN']?['userId']; + print('Успешная авторизация! Токен: $finalToken, UserID: $userId'); + + ApiService.instance + .saveToken(finalToken, userId: userId?.toString()) + .then((_) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Код верный! Вход выполнен.'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const ChatsScreen()), + (route) => false, + ); + }); + } else { + _handleIncorrectCode(); + } + } + }); + } + + void _verifyCode(String code) async { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + setState(() => _isLoading = true); + } + }); + + try { + await ApiService.instance.verifyCode(widget.otpToken, code); + } catch (e) { + if (mounted) { + setState(() => _isLoading = false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка подключения: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + } + + void _handleIncorrectCode() { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Неверный код. Попробуйте снова.'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + _pinController.clear(); + _pinFocusNode.requestFocus(); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final defaultPinTheme = PinTheme( + width: 56, + height: 60, + textStyle: TextStyle(fontSize: 22, color: colors.onSurface), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(16), + ), + ); + + return Scaffold( + appBar: AppBar(title: const Text('Подтверждение')), + body: Stack( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Код отправлен на номер', + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 8), + Text( + widget.phoneNumber, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 30), + Pinput( + length: 6, + controller: _pinController, + focusNode: _pinFocusNode, + autofocus: true, + defaultPinTheme: defaultPinTheme, + focusedPinTheme: defaultPinTheme.copyWith( + decoration: defaultPinTheme.decoration!.copyWith( + border: Border.all(color: colors.primary, width: 2), + ), + ), + onCompleted: (pin) => _verifyCode(pin), + ), + ], + ), + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } + + @override + void dispose() { + _pinController.dispose(); + _pinFocusNode.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } +} diff --git a/lib/packet_framer.dart b/lib/packet_framer.dart new file mode 100644 index 0000000..14fc798 --- /dev/null +++ b/lib/packet_framer.dart @@ -0,0 +1,104 @@ + + +import 'dart:typed_data'; +import 'package:msgpack_dart/msgpack_dart.dart'; +import 'package:es_compression/lz4.dart'; + +final lz4Codec = Lz4Codec(); + + +Uint8List packPacket({ + required int ver, + required int cmd, + required int seq, + required int opcode, + required Map payload, +}) { + Uint8List payloadBytes = serialize(payload); + bool isCompressed = false; + + if (payloadBytes.length >= 32) { + final uncompressedSize = ByteData(4) + ..setUint32(0, payloadBytes.length, Endian.big); + + final compressedData = lz4Codec.encode(payloadBytes); + + final builder = BytesBuilder(); + builder.add(uncompressedSize.buffer.asUint8List()); + builder.add(compressedData); + payloadBytes = builder.toBytes(); + isCompressed = true; + } + + final header = ByteData(10); + header.setUint8(0, ver); + header.setUint16(1, cmd, Endian.big); + header.setUint8(3, seq); + header.setUint16(4, opcode, Endian.big); + + int packedLen = payloadBytes.length; + if (isCompressed) { + packedLen |= (1 << 24); + } + header.setUint32(6, packedLen, Endian.big); + + final builder = BytesBuilder(); + builder.add(header.buffer.asUint8List()); + builder.add(payloadBytes); + + return builder.toBytes(); +} + + +Map? unpackPacket(Uint8List data) { + if (data.length < 10) { + print("Ошибка распаковки: Пакет слишком короткий для заголовка."); + return null; + } + + final byteData = data.buffer.asByteData( + data.offsetInBytes, + data.lengthInBytes, + ); + + final ver = byteData.getUint8(0); + final cmd = byteData.getUint16(1, Endian.big); + final seq = byteData.getUint8(3); + final opcode = byteData.getUint16(4, Endian.big); + final packedLen = byteData.getUint32(6, Endian.big); + + final compFlag = packedLen >> 24; + final payloadLength = packedLen & 0x00FFFFFF; + + if (data.length < 10 + payloadLength) { + print( + "Ошибка распаковки: Фактическая длина пакета (${data.length}) меньше заявленной (${10 + payloadLength}).", + ); + return null; + } + + Uint8List payloadBytes = data.sublist(10, 10 + payloadLength); + + if (compFlag != 0) { + try { + final compressedData = payloadBytes.sublist(4); + + + + payloadBytes = Uint8List.fromList(lz4Codec.decode(compressedData)); + } catch (e) { + print("Ошибка распаковки LZ4: $e"); + return null; + } + } + + final dynamic payload = deserialize(payloadBytes); + + return { + "ver": ver, + "cmd": cmd, + "seq": seq, + "opcode": opcode, + "payload": payload, + }; +} diff --git a/lib/password_auth_screen.dart b/lib/password_auth_screen.dart new file mode 100644 index 0000000..fec2d5d --- /dev/null +++ b/lib/password_auth_screen.dart @@ -0,0 +1,298 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/chats_screen.dart'; + +class PasswordAuthScreen extends StatefulWidget { + const PasswordAuthScreen({super.key}); + + @override + State createState() => _PasswordAuthScreenState(); +} + +class _PasswordAuthScreenState extends State { + final TextEditingController _passwordController = TextEditingController(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + String? _hint; + String? _email; + + @override + void initState() { + super.initState(); + + + _apiSubscription = ApiService.instance.messages.listen((message) { + if (message['type'] == 'password_required' && mounted) { + setState(() { + _hint = message['hint']; + _email = message['email']; + }); + } + + + if (message['opcode'] == 115 && message['cmd'] == 1 && mounted) { + final payload = message['payload']; + if (payload != null && + payload['tokenAttrs']?['LOGIN']?['token'] != null) { + final String finalToken = payload['tokenAttrs']['LOGIN']['token']; + final userId = payload['tokenAttrs']?['LOGIN']?['userId']; + + print( + 'Успешная аутентификация паролем! Токен: $finalToken, UserID: $userId', + ); + + + ApiService.instance + .saveToken(finalToken, userId: userId?.toString()) + .then((_) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароль верный! Вход выполнен.'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + + + ApiService.instance.clearPasswordAuthData(); + + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const ChatsScreen()), + (route) => false, + ); + }); + } + } + + + if (message['opcode'] == 115 && message['cmd'] == 3 && mounted) { + setState(() { + _isLoading = false; + }); + + final error = message['payload']; + String errorMessage = 'Ошибка аутентификации'; + + if (error != null) { + if (error['localizedMessage'] != null) { + errorMessage = error['localizedMessage']; + } else if (error['message'] != null) { + errorMessage = error['message']; + } + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + + + final authData = ApiService.instance.getPasswordAuthData(); + _hint = authData['hint']; + _email = authData['email']; + } + + void _submitPassword() async { + final password = _passwordController.text.trim(); + if (password.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите пароль'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + final authData = ApiService.instance.getPasswordAuthData(); + final trackId = authData['trackId']; + + if (trackId == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Ошибка: отсутствует идентификатор сессии'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + await ApiService.instance.sendPassword(trackId, password); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка отправки пароля: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Ввод пароля'), + backgroundColor: colors.surface, + elevation: 0, + ), + body: Stack( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + if (_email != null) + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: colors.outline.withOpacity(0.2), + ), + ), + child: Column( + children: [ + Text( + 'Аккаунт защищен паролем', + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w600, + fontSize: 16, + ), + ), + const SizedBox(height: 8), + Text( + _email!, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + if (_hint != null) ...[ + const SizedBox(height: 8), + Text( + 'Подсказка: $_hint', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + fontStyle: FontStyle.italic, + ), + ), + ], + ], + ), + ), + + const SizedBox(height: 30), + + + TextField( + controller: _passwordController, + obscureText: true, + decoration: InputDecoration( + labelText: 'Пароль', + hintText: 'Введите пароль от аккаунта', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.lock), + filled: true, + fillColor: colors.surfaceContainerHighest, + ), + onSubmitted: (_) => _submitPassword(), + ), + + const SizedBox(height: 24), + + + SizedBox( + width: double.infinity, + height: 50, + child: FilledButton( + onPressed: _isLoading ? null : _submitPassword, + style: FilledButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + child: _isLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), + ), + ) + : const Text('Войти'), + ), + ), + ], + ), + ), + ), + + + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } + + @override + void dispose() { + _passwordController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } +} diff --git a/lib/password_management_screen.dart b/lib/password_management_screen.dart new file mode 100644 index 0000000..632d4b2 --- /dev/null +++ b/lib/password_management_screen.dart @@ -0,0 +1,426 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/api_service.dart'; + +class PasswordManagementScreen extends StatefulWidget { + const PasswordManagementScreen({super.key}); + + @override + State createState() => + _PasswordManagementScreenState(); +} + +class _PasswordManagementScreenState extends State { + final TextEditingController _passwordController = TextEditingController(); + final TextEditingController _confirmPasswordController = + TextEditingController(); + final TextEditingController _hintController = TextEditingController(); + + StreamSubscription? _apiSubscription; + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + } + + @override + void dispose() { + _passwordController.dispose(); + _confirmPasswordController.dispose(); + _hintController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'password_set_success') { + setState(() { + _isLoading = false; + }); + + _clearFields(); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароль успешно установлен!'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + + if (message['cmd'] == 3 && message['opcode'] == 116) { + setState(() { + _isLoading = false; + }); + + final errorPayload = message['payload']; + String errorMessage = 'Неизвестная ошибка'; + if (errorPayload != null) { + if (errorPayload['localizedMessage'] != null) { + errorMessage = errorPayload['localizedMessage']; + } else if (errorPayload['message'] != null) { + errorMessage = errorPayload['message']; + } + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + } + + void _clearFields() { + _passwordController.clear(); + _confirmPasswordController.clear(); + _hintController.clear(); + } + + void _setPassword() async { + final password = _passwordController.text.trim(); + final confirmPassword = _confirmPasswordController.text.trim(); + final hint = _hintController.text.trim(); + + if (password.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите пароль'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + if (password.length < 6) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароль должен содержать минимум 6 символов'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + if (password.length > 30) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароль не должен превышать 30 символов'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + + if (!password.contains(RegExp(r'[A-Z]')) || + !password.contains(RegExp(r'[a-z]'))) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text( + 'Пароль должен содержать заглавные и строчные буквы', + ), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + + if (!password.contains(RegExp(r'[0-9]'))) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароль должен содержать цифры'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + + if (!password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'))) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text( + 'Пароль должен содержать специальные символы (!@#\$%^&*)', + ), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + if (password != confirmPassword) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Пароли не совпадают'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + await ApiService.instance.setAccountPassword(password, hint); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка установки пароля: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar(title: const Text('Пароль аккаунта')), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.info_outline, color: colors.primary), + const SizedBox(width: 8), + Text( + 'Пароль аккаунта', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + 'Пароль добавляет дополнительную защиту к вашему аккаунту. ' + 'После установки пароля для входа потребуется не только SMS-код, ' + 'но и пароль.', + style: TextStyle(color: colors.onSurfaceVariant), + ), + ], + ), + ), + + const SizedBox(height: 24), + + + Text( + 'Установить пароль', + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + + TextField( + controller: _passwordController, + obscureText: true, + decoration: InputDecoration( + labelText: 'Новый пароль', + hintText: 'Введите пароль', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.lock), + ), + ), + const SizedBox(height: 16), + + TextField( + controller: _confirmPasswordController, + obscureText: true, + decoration: InputDecoration( + labelText: 'Подтвердите пароль', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.lock_outline), + ), + ), + const SizedBox(height: 16), + + TextField( + controller: _hintController, + decoration: InputDecoration( + labelText: 'Подсказка для пароля (необязательно)', + hintText: 'Например: "Мой любимый цвет"', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.lightbulb_outline), + ), + maxLength: 30, + ), + const SizedBox(height: 16), + + + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + size: 16, + color: colors.primary, + ), + const SizedBox(width: 8), + Text( + 'Требования к паролю:', + style: TextStyle( + fontWeight: FontWeight.w600, + color: colors.primary, + fontSize: 14, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + '• Не менее 6 символов\n' + '• Содержать заглавные и строчные буквы\n' + '• Включать цифры и специальные символы (!@#\$%^&*)\n' + '• Максимум 30 символов', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 13, + height: 1.4, + ), + ), + ], + ), + ), + const SizedBox(height: 24), + + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _setPassword, + icon: _isLoading + ? SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + ) + : const Icon(Icons.lock), + label: Text( + _isLoading ? 'Установка...' : 'Установить пароль', + ), + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + ], + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } +} diff --git a/lib/phone_entry_screen.dart b/lib/phone_entry_screen.dart new file mode 100644 index 0000000..b9a737c --- /dev/null +++ b/lib/phone_entry_screen.dart @@ -0,0 +1,666 @@ +import 'dart:async'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/otp_screen.dart'; +import 'package:gwid/screens/settings/session_spoofing_screen.dart'; +import 'package:gwid/token_auth_screen.dart'; +import 'package:gwid/tos_screen.dart'; // Импорт экрана ToS +import 'package:mask_text_input_formatter/mask_text_input_formatter.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class Country { + final String name; + final String code; + final String flag; + final String mask; + final int digits; + + const Country({ + required this.name, + required this.code, + required this.flag, + required this.mask, + required this.digits, + }); +} + +class PhoneEntryScreen extends StatefulWidget { + const PhoneEntryScreen({super.key}); + + @override + State createState() => _PhoneEntryScreenState(); +} + +class _PhoneEntryScreenState extends State + with TickerProviderStateMixin { + final TextEditingController _phoneController = TextEditingController(); + + static const List _countries = [ + Country( + name: 'Россия', + code: '+7', + flag: '🇷🇺', + mask: '+7 (###) ###-##-##', + digits: 10, + ), + Country( + name: 'Беларусь', + code: '+375', + flag: '🇧🇾', + mask: '+375 (##) ###-##-##', + digits: 9, + ), + ]; + + Country _selectedCountry = _countries[0]; + late MaskTextInputFormatter _maskFormatter; + bool _isButtonEnabled = false; + bool _isLoading = false; + bool _hasCustomAnonymity = false; + StreamSubscription? _apiSubscription; + bool _showContent = false; + bool _isTosAccepted = false; // Состояние для отслеживания принятия соглашения + + late final AnimationController _animationController; + late final Animation _topAlignmentAnimation; + late final Animation _bottomAlignmentAnimation; + + @override + void initState() { + super.initState(); + + _animationController = AnimationController( + vsync: this, + duration: const Duration(seconds: 15), + ); + + _topAlignmentAnimation = + AlignmentTween( + begin: Alignment.topLeft, + end: Alignment.topRight, + ).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOut, + ), + ); + _bottomAlignmentAnimation = + AlignmentTween( + begin: Alignment.bottomRight, + end: Alignment.bottomLeft, + ).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOut, + ), + ); + + _animationController.repeat(reverse: true); + + _initializeMaskFormatter(); + _checkAnonymitySettings(); + _phoneController.addListener(_onPhoneChanged); + + Future.delayed(const Duration(milliseconds: 300), () { + if (mounted) setState(() => _showContent = true); + }); + + _apiSubscription = ApiService.instance.messages.listen((message) { + if (message['opcode'] == 17 && mounted) { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) setState(() => _isLoading = false); + }); + final payload = message['payload']; + if (payload != null && payload['token'] != null) { + final String token = payload['token']; + final String fullPhoneNumber = + _selectedCountry.code + _maskFormatter.getUnmaskedText(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + OTPScreen(phoneNumber: fullPhoneNumber, otpToken: token), + ), + ); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Не удалось запросить код. Попробуйте позже.'), + backgroundColor: Colors.red, + ), + ); + } + } + }); + } + + void _initializeMaskFormatter() { + final mask = _selectedCountry.mask + .replaceFirst(RegExp(r'^\+\d+\s?'), '') + .trim(); + _maskFormatter = MaskTextInputFormatter( + mask: mask, + filter: {"#": RegExp(r'[0-9]')}, + type: MaskAutoCompletionType.lazy, + ); + } + + void _onPhoneChanged() { + final text = _phoneController.text; + if (text.isNotEmpty) { + Country? detectedCountry = _detectCountryFromInput(text); + if (detectedCountry != null && detectedCountry != _selectedCountry) { + if (_shouldClearFieldForCountry(text, detectedCountry)) { + _phoneController.clear(); + } + setState(() { + _selectedCountry = detectedCountry; + _initializeMaskFormatter(); + }); + } + } + final isFull = + _maskFormatter.getUnmaskedText().length == _selectedCountry.digits; + if (isFull != _isButtonEnabled) { + setState(() => _isButtonEnabled = isFull); + } + } + + bool _shouldClearFieldForCountry(String input, Country country) { + final cleanInput = input.replaceAll(RegExp(r'[^\d+]'), ''); + if (country.code == '+7') { + return !(cleanInput.startsWith('+7') || cleanInput.startsWith('7')); + } else if (country.code == '+375') { + return !(cleanInput.startsWith('+375') || cleanInput.startsWith('375')); + } + return true; + } + + Country? _detectCountryFromInput(String input) { + final cleanInput = input.replaceAll(RegExp(r'[^\d+]'), ''); + if (cleanInput.startsWith('+7') || cleanInput.startsWith('7')) { + return _countries.firstWhere((c) => c.code == '+7'); + } else if (cleanInput.startsWith('+375') || cleanInput.startsWith('375')) { + return _countries.firstWhere((c) => c.code == '+375'); + } + return null; + } + + void _onCountryChanged(Country? country) { + if (country != null && country != _selectedCountry) { + setState(() { + _selectedCountry = country; + _phoneController.clear(); + _initializeMaskFormatter(); + _isButtonEnabled = false; + }); + } + } + + void _checkAnonymitySettings() async { + final prefs = await SharedPreferences.getInstance(); + final anonymityEnabled = prefs.getBool('anonymity_enabled') ?? false; + if (mounted) setState(() => _hasCustomAnonymity = anonymityEnabled); + } + + void _requestOtp() async { + if (!_isButtonEnabled || _isLoading || !_isTosAccepted) return; + setState(() => _isLoading = true); + final String fullPhoneNumber = + _selectedCountry.code + _maskFormatter.getUnmaskedText(); + try { + ApiService.instance.errorStream.listen((error) { + if (mounted) { + setState(() => _isLoading = false); + _showErrorDialog(error); + } + }); + await ApiService.instance.requestOtp(fullPhoneNumber); + } catch (e) { + if (mounted) { + setState(() => _isLoading = false); + _showErrorDialog('Ошибка подключения: ${e.toString()}'); + } + } + } + + void _showErrorDialog(String error) { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + title: const Text('Ошибка валидации'), + content: Text(error), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('OK'), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final textTheme = Theme.of(context).textTheme; + + return Scaffold( + body: Stack( + children: [ + AnimatedBuilder( + animation: _animationController, + builder: (context, child) { + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: _topAlignmentAnimation.value, + end: _bottomAlignmentAnimation.value, + colors: [ + Color.lerp(colors.surface, colors.primary, 0.2)!, + Color.lerp(colors.surface, colors.tertiary, 0.15)!, + colors.surface, + Color.lerp(colors.surface, colors.secondary, 0.15)!, + Color.lerp(colors.surface, colors.primary, 0.25)!, + ], + stops: const [0.0, 0.25, 0.5, 0.75, 1.0], + ), + ), + ); + }, + ), + SafeArea( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 340), + child: AnimatedOpacity( + duration: const Duration(milliseconds: 700), + curve: Curves.easeOut, + opacity: _showContent ? 1.0 : 0.0, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox(height: 48), + Center( + child: Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: colors.primary.withOpacity(0.1), + ), + child: const Image( + image: AssetImage( + 'assets/images/komet_512.png', + ), + width: 75, + height: 75, + ), + ), + ), + const SizedBox(height: 24), + Text( + 'Komet', + textAlign: TextAlign.center, + style: GoogleFonts.manrope( + textStyle: textTheme.headlineLarge, + fontWeight: FontWeight.w800, + ), + ), + const SizedBox(height: 8), + Text( + 'Введите номер телефона для входа', + textAlign: TextAlign.center, + style: GoogleFonts.manrope( + textStyle: textTheme.titleMedium, + color: colors.onSurfaceVariant, + ), + ), + const SizedBox(height: 48), + _PhoneInput( + phoneController: _phoneController, + maskFormatter: _maskFormatter, + selectedCountry: _selectedCountry, + countries: _countries, + onCountryChanged: _onCountryChanged, + ), + const SizedBox(height: 16), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Checkbox( + value: _isTosAccepted, + onChanged: (bool? value) { + setState(() { + _isTosAccepted = value ?? false; + }); + }, + visualDensity: VisualDensity.compact, + ), + Expanded( + child: Text.rich( + TextSpan( + style: GoogleFonts.manrope( + textStyle: textTheme.bodySmall, + color: colors.onSurfaceVariant, + ), + children: [ + const TextSpan(text: 'Я принимаю '), + TextSpan( + text: 'Пользовательское соглашение', + style: TextStyle( + color: colors.primary, + decoration: TextDecoration.underline, + decorationColor: colors.primary, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const TosScreen(), + ), + ); + }, + ), + ], + ), + ), + ), + ], + ), + const SizedBox(height: 16), + FilledButton( + onPressed: _isButtonEnabled && _isTosAccepted + ? _requestOtp + : null, + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + child: Text( + 'Далее', + style: GoogleFonts.manrope( + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 16), + OutlinedButton.icon( + onPressed: _isTosAccepted + ? () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const TokenAuthScreen(), + ), + ) + : null, + icon: const Icon(Icons.vpn_key_outlined), + label: Text( + 'Альтернативные способы входа', + style: GoogleFonts.manrope( + fontWeight: FontWeight.bold, + ), + ), + style: OutlinedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + ), + ), + const SizedBox(height: 32), + _AnonymityCard(isConfigured: _hasCustomAnonymity), + const SizedBox(height: 24), + Text.rich( + textAlign: TextAlign.center, + TextSpan( + style: GoogleFonts.manrope( + textStyle: textTheme.bodySmall, + color: colors.onSurfaceVariant.withOpacity(0.8), + ), + children: [ + const TextSpan( + text: + 'Используя Komet, вы принимаете на себя всю ответственность за использование стороннего клиента.\n', + ), + TextSpan( + text: '@TeamKomet', + style: TextStyle( + color: colors.primary, + decoration: TextDecoration.underline, + decorationColor: colors.primary, + ), + recognizer: TapGestureRecognizer() + ..onTap = () async { + final Uri url = Uri.parse( + 'https://t.me/TeamKomet', + ); + if (!await launchUrl(url)) { + debugPrint('Could not launch $url'); + } + }, + ), + ], + ), + ), + const SizedBox(height: 16), + ], + ), + ), + ), + ), + ), + ), + ), + if (_isLoading) + Container( + color: colors.scrim.withOpacity(0.7), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + const SizedBox(height: 16), + Text( + 'Отправляем код...', + style: textTheme.titleMedium?.copyWith( + color: colors.onPrimary, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + @override + void dispose() { + _animationController.dispose(); + _phoneController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } +} + +class _PhoneInput extends StatelessWidget { + final TextEditingController phoneController; + final MaskTextInputFormatter maskFormatter; + final Country selectedCountry; + final List countries; + final ValueChanged onCountryChanged; + + const _PhoneInput({ + required this.phoneController, + required this.maskFormatter, + required this.selectedCountry, + required this.countries, + required this.onCountryChanged, + }); + + @override + Widget build(BuildContext context) { + return TextFormField( + controller: phoneController, + inputFormatters: [maskFormatter], + keyboardType: TextInputType.number, + style: GoogleFonts.manrope( + textStyle: Theme.of(context).textTheme.titleMedium, + fontWeight: FontWeight.w600, + ), + decoration: InputDecoration( + hintText: maskFormatter.getMask()?.replaceAll('#', '0'), + prefixIcon: _CountryPicker( + selectedCountry: selectedCountry, + countries: countries, + onCountryChanged: onCountryChanged, + ), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + ), + autofocus: true, + ); + } +} + +class _CountryPicker extends StatelessWidget { + final Country selectedCountry; + final List countries; + final ValueChanged onCountryChanged; + + const _CountryPicker({ + required this.selectedCountry, + required this.countries, + required this.onCountryChanged, + }); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final textTheme = Theme.of(context).textTheme; + + return Container( + margin: const EdgeInsets.only(left: 8), + child: DropdownButtonHideUnderline( + child: DropdownButton( + value: selectedCountry, + onChanged: onCountryChanged, + icon: Icon(Icons.keyboard_arrow_down, color: colors.onSurfaceVariant), + items: countries.map((Country country) { + return DropdownMenuItem( + value: country, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(country.flag, style: textTheme.titleMedium), + const SizedBox(width: 8), + Text( + country.code, + style: GoogleFonts.manrope( + textStyle: textTheme.titleMedium, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + }).toList(), + ), + ), + ); + } +} + +class _AnonymityCard extends StatelessWidget { + final bool isConfigured; + const _AnonymityCard({required this.isConfigured}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final textTheme = Theme.of(context).textTheme; + + final Color cardColor = isConfigured + ? colors.secondaryContainer + : colors.surfaceContainerHighest.withOpacity(0.5); + final Color onCardColor = isConfigured + ? colors.onSecondaryContainer + : colors.onSurfaceVariant; + final IconData icon = isConfigured + ? Icons.verified_user_outlined + : Icons.visibility_outlined; + + return Card( + elevation: 0, + color: cardColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: colors.outline.withOpacity(0.5)), + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Row( + children: [ + Icon(icon, color: onCardColor, size: 20), + const SizedBox(width: 12), + Expanded( + child: Text( + isConfigured + ? 'Активны кастомные настройки анонимности' + : 'Настройте анонимность для скрытия данных', + style: GoogleFonts.manrope( + textStyle: textTheme.bodyMedium, + color: onCardColor, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: isConfigured + ? FilledButton.tonalIcon( + onPressed: _navigateToSpoofingScreen(context), + icon: const Icon(Icons.settings, size: 18), + label: Text( + 'Изменить настройки', + style: GoogleFonts.manrope(fontWeight: FontWeight.bold), + ), + ) + : FilledButton.icon( + onPressed: _navigateToSpoofingScreen(context), + icon: const Icon(Icons.visibility_off, size: 18), + label: Text( + 'Настроить анонимность', + style: GoogleFonts.manrope(fontWeight: FontWeight.bold), + ), + ), + ), + ], + ), + ), + ); + } + + VoidCallback _navigateToSpoofingScreen(BuildContext context) { + return () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const SessionSpoofingScreen()), + ); + }; + } +} diff --git a/lib/profile_menu_dialog.dart b/lib/profile_menu_dialog.dart new file mode 100644 index 0000000..f9828e1 --- /dev/null +++ b/lib/profile_menu_dialog.dart @@ -0,0 +1,304 @@ + +import 'package:flutter/material.dart'; +import 'package:gwid/manage_account_screen.dart'; +import 'package:gwid/models/profile.dart'; +import 'package:gwid/screens/settings/settings_screen.dart'; +import 'package:gwid/phone_entry_screen.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; + +class ProfileMenuDialog extends StatefulWidget { + final Profile? myProfile; + + const ProfileMenuDialog({super.key, this.myProfile}); + + @override + State createState() => _ProfileMenuDialogState(); +} + +class _ProfileMenuDialogState extends State { + bool _isAvatarExpanded = false; + + void _toggleAvatar() { + setState(() { + _isAvatarExpanded = !_isAvatarExpanded; + }); + } + + void _collapseAvatar() { + if (_isAvatarExpanded) { + setState(() { + _isAvatarExpanded = false; + }); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + final String subtitle = "Профиль"; + + final Profile? myProfile = widget.myProfile; + + return Dialog( + alignment: Alignment.topCenter, + insetPadding: const EdgeInsets.only(top: 60.0, left: 16.0, right: 16.0), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28.0)), + child: SafeArea( + bottom: false, + child: Stack( + children: [ + + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 12.0, + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + IconButton( + icon: const Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + const SizedBox(width: 8), + const Expanded( + child: Text( + "Komet", + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w600, + ), + ), + ), + ], + ), + const SizedBox(height: 8), + Container( + decoration: BoxDecoration( + color: Color(0x0ff33333), + borderRadius: BorderRadius.circular(24), + ), + padding: const EdgeInsets.fromLTRB(12, 8, 12, 12), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + contentPadding: EdgeInsets.zero, + leading: GestureDetector( + onTap: _toggleAvatar, + child: Opacity( + opacity: _isAvatarExpanded ? 0 : 1, + child: CircleAvatar( + radius: 22, + backgroundImage: + myProfile?.photoBaseUrl != null + ? NetworkImage(myProfile!.photoBaseUrl!) + : null, + child: myProfile?.photoBaseUrl == null + ? Text( + myProfile?.displayName.isNotEmpty == + true + ? myProfile!.displayName[0] + .toUpperCase() + : '?', + ) + : null, + ), + ), + ), + title: Text( + myProfile?.displayName ?? "Загрузка...", + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(subtitle), + trailing: const Icon( + Icons.keyboard_arrow_down_rounded, + ), + ), + Builder( + builder: (context) { + final extra = context + .read() + .extraTransition; + final strength = context + .read() + .extraAnimationStrength; + final panel = SizedBox( + width: double.infinity, + child: OutlinedButton( + style: OutlinedButton.styleFrom( + shape: const StadiumBorder(), + side: BorderSide(color: colors.outline), + ), + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + ManageAccountScreen( + myProfile: myProfile, + ), + ), + ); + }, + child: const Text("Управление аккаунтом"), + ), + ); + if (extra == TransitionOption.slide && + _isAvatarExpanded) { + return AnimatedSlide( + offset: _isAvatarExpanded + ? Offset.zero + : Offset(0, strength / 400.0), + duration: const Duration(milliseconds: 220), + curve: Curves.easeInOut, + child: AnimatedOpacity( + opacity: _isAvatarExpanded ? 1.0 : 0.0, + duration: const Duration(milliseconds: 220), + curve: Curves.easeInOut, + child: panel, + ), + ); + } + return panel; + }, + ), + ], + ), + ), + const SizedBox(height: 8), + const Divider(), + _SettingsTile( + icon: Icons.settings_outlined, + title: "Настройки", + onTap: () { + Navigator.of(context).pop(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SettingsScreen(), + ), + ); + }, + ), + const SizedBox(height: 4), + _SettingsTile( + icon: Icons.logout, + title: "Выйти", + onTap: () async { + if (context.mounted) { + Navigator.of(context).pop(); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (_) => const PhoneEntryScreen(), + ), + (route) => false, + ); + } + }, + ), + const SizedBox(height: 4), + ], + ), + ), + ), + + + if (_isAvatarExpanded) + Positioned.fill( + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: _collapseAvatar, + child: const SizedBox.expand(), + ), + ), + + + AnimatedAlign( + alignment: _isAvatarExpanded + ? Alignment.center + : Alignment.topLeft, + duration: const Duration(milliseconds: 220), + curve: Curves.easeInOut, + child: IgnorePointer( + ignoring: !_isAvatarExpanded, + child: GestureDetector( + onTap: () {}, + child: Builder( + builder: (context) { + final extra = context + .read() + .extraTransition; + final avatar = CircleAvatar( + radius: 80, + backgroundImage: widget.myProfile?.photoBaseUrl != null + ? NetworkImage(widget.myProfile!.photoBaseUrl!) + : null, + child: widget.myProfile?.photoBaseUrl == null + ? Text( + widget.myProfile?.displayName.isNotEmpty == true + ? widget.myProfile!.displayName[0] + .toUpperCase() + : '?', + style: const TextStyle(fontSize: 36), + ) + : null, + ); + if (extra == TransitionOption.slide) { + return AnimatedSlide( + offset: _isAvatarExpanded + ? Offset.zero + : const Offset(0, -1), + duration: const Duration(milliseconds: 220), + curve: Curves.easeInOut, + child: avatar, + ); + } + return AnimatedScale( + scale: _isAvatarExpanded ? 1.0 : 0.0, + duration: const Duration(milliseconds: 220), + curve: Curves.easeInOut, + child: avatar, + ); + }, + ), + ), + ), + ), + ], + ), + ), + ); + } +} + +class _SettingsTile extends StatelessWidget { + final IconData icon; + final String title; + final VoidCallback onTap; + + const _SettingsTile({ + required this.icon, + required this.title, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + contentPadding: EdgeInsets.zero, + leading: Icon(icon), + title: Text(title), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: onTap, + ); + } +} diff --git a/lib/proxy_service.dart b/lib/proxy_service.dart new file mode 100644 index 0000000..f92e114 --- /dev/null +++ b/lib/proxy_service.dart @@ -0,0 +1,117 @@ + + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'proxy_settings.dart'; + +class ProxyService { + ProxyService._privateConstructor(); + static final ProxyService instance = ProxyService._privateConstructor(); + + static const _proxySettingsKey = 'proxy_settings'; + + Future saveProxySettings(ProxySettings settings) async { + final prefs = await SharedPreferences.getInstance(); + final jsonString = jsonEncode(settings.toJson()); + await prefs.setString(_proxySettingsKey, jsonString); + } + + Future loadProxySettings() async { + final prefs = await SharedPreferences.getInstance(); + final jsonString = prefs.getString(_proxySettingsKey); + if (jsonString != null) { + try { + return ProxySettings.fromJson(jsonDecode(jsonString)); + } catch (e) { + return ProxySettings(); + } + } + return ProxySettings(); + } + + + Future checkProxy(ProxySettings settings) async { + print("Проверка прокси: ${settings.host}:${settings.port}"); + HttpClient client = _createClientWithOptions(settings); + + client.connectionTimeout = const Duration(seconds: 10); + + try { + final request = await client.headUrl( + Uri.parse('https://www.google.com/generate_204'), + ); + final response = await request.close(); + + print("Ответ от прокси получен, статус: ${response.statusCode}"); + + if (response.statusCode >= 400) { + + throw Exception('Прокси вернул ошибку: ${response.statusCode}'); + } + } on HandshakeException catch (e) { + print("Поймана ошибка сертификата при проверке прокси: $e"); + print( + "Предполагаем, что badCertificateCallback обработает это в реальном соединении. Считаем проверку успешной.", + ); + + return; + } on SocketException catch (e) { + print("Ошибка сокета при проверке прокси: $e"); + throw Exception('Неверный хост или порт'); + } on TimeoutException catch (_) { + print("Таймаут при проверке прокси"); + throw Exception('Сервер не отвечает (таймаут)'); + } catch (e) { + print("Неизвестная ошибка при проверке прокси: $e"); + throw Exception('Неизвестная ошибка: ${e.toString()}'); + } finally { + client.close(); + } + } + + + Future getHttpClientWithProxy() async { + final settings = await loadProxySettings(); + return _createClientWithOptions(settings); + } + + + HttpClient _createClientWithOptions(ProxySettings settings) { + final client = HttpClient(); + + if (settings.isEnabled && settings.host.isNotEmpty) { + print("Используется прокси: ${settings.toFindProxyString()}"); + + client.findProxy = (uri) { + return settings.toFindProxyString(); + }; + + if (settings.username != null && settings.username!.isNotEmpty) { + print( + "Настраивается аутентификация на прокси для пользователя: ${settings.username}", + ); + client.authenticateProxy = (host, port, scheme, realm) async { + client.addProxyCredentials( + host, + port, + realm ?? '', + HttpClientBasicCredentials( + settings.username!, + settings.password ?? '', + ), + ); + return true; + }; + } + + client.badCertificateCallback = + (X509Certificate cert, String host, int port) => true; + } else { + client.findProxy = HttpClient.findProxyFromEnvironment; + } + + return client; + } +} diff --git a/lib/proxy_settings.dart b/lib/proxy_settings.dart new file mode 100644 index 0000000..816a8ef --- /dev/null +++ b/lib/proxy_settings.dart @@ -0,0 +1,91 @@ + + +enum ProxyProtocol { http, https, socks4, socks5 } + +class ProxySettings { + final bool isEnabled; + final String host; + final int port; + final ProxyProtocol protocol; + final String? username; + final String? password; + + ProxySettings({ + this.isEnabled = false, + this.host = '', + this.port = 8080, + this.protocol = ProxyProtocol.http, + this.username, + this.password, + }); + + + String toFindProxyString() { + if (!isEnabled || host.isEmpty) { + return 'DIRECT'; + } + + + String protocolString; + switch (protocol) { + case ProxyProtocol.http: + case ProxyProtocol.https: + protocolString = 'PROXY'; // HttpClient ожидает 'PROXY' для HTTP и HTTPS + break; + case ProxyProtocol.socks4: + + + protocolString = 'SOCKS4'; + break; + case ProxyProtocol.socks5: + protocolString = 'SOCKS5'; + break; + } + + + return '$protocolString $host:$port'; + } + + ProxySettings copyWith({ + bool? isEnabled, + String? host, + int? port, + ProxyProtocol? protocol, + String? username, + String? password, + }) { + return ProxySettings( + isEnabled: isEnabled ?? this.isEnabled, + host: host ?? this.host, + port: port ?? this.port, + protocol: protocol ?? this.protocol, + username: username ?? this.username, + password: password ?? this.password, + ); + } + + Map toJson() { + return { + 'isEnabled': isEnabled, + 'host': host, + 'port': port, + 'protocol': protocol.name, + 'username': username, + 'password': password, + }; + } + + factory ProxySettings.fromJson(Map json) { + return ProxySettings( + isEnabled: json['isEnabled'] ?? false, + host: json['host'] ?? '', + port: json['port'] ?? 8080, + protocol: ProxyProtocol.values.firstWhere( + (e) => e.name == json['protocol'], + orElse: () => ProxyProtocol.http, + ), + username: json['username'], + password: json['password'], + ); + } +} diff --git a/lib/screens/group_settings_screen.dart b/lib/screens/group_settings_screen.dart new file mode 100644 index 0000000..e6729c1 --- /dev/null +++ b/lib/screens/group_settings_screen.dart @@ -0,0 +1,1206 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/services/avatar_cache_service.dart'; +import 'package:gwid/widgets/user_profile_panel.dart'; + +class GroupSettingsScreen extends StatefulWidget { + final int chatId; + final Contact initialContact; + final int myId; + final VoidCallback? onChatUpdated; + + const GroupSettingsScreen({ + super.key, + required this.chatId, + required this.initialContact, + required this.myId, + this.onChatUpdated, + }); + + @override + State createState() => _GroupSettingsScreenState(); +} + +class _GroupSettingsScreenState extends State { + late Contact _currentContact; + StreamSubscription? _contactSubscription; + StreamSubscription? _membersSubscription; + + final List> _loadedMembers = []; + final Set _loadedMemberIds = {}; + final ScrollController _scrollController = ScrollController(); + int? _lastMarker; + bool _isLoadingMembers = false; + bool _hasMoreMembers = true; + + @override + void initState() { + super.initState(); + _currentContact = widget.initialContact; + + + _contactSubscription = ApiService.instance.contactUpdates.listen((contact) { + if (contact.id == _currentContact.id && mounted) { + ApiService.instance.updateCachedContact(contact); + setState(() { + _currentContact = contact; + }); + } + }); + + + _membersSubscription = ApiService.instance.messages.listen((message) { + if (message['type'] == 'group_members' && mounted) { + _handleGroupMembersResponse(message['payload']); + } + }); + + + _loadMembersFromCache(); + + + if (_loadedMembers.length < 50) { + _loadedMembers.clear(); + _loadedMemberIds.clear(); + _lastMarker = null; + _hasMoreMembers = true; + ApiService.instance.getGroupMembers(widget.chatId, marker: 0, count: 50); + _isLoadingMembers = true; + } else { + + _lastMarker = _loadedMembers.isNotEmpty + ? _loadedMembers.last['id'] as int? + : null; + _hasMoreMembers = + _loadedMembers.length >= 50; // Если 50+ из кэша - есть пагинация + _isLoadingMembers = false; + print( + 'DEBUG: Участники загружены из кэша, marker: $_lastMarker, hasMore: $_hasMoreMembers', + ); + } + + + _scrollController.addListener(_onScroll); + } + + void _onScroll() { + if (!_scrollController.hasClients) return; + + final maxScroll = _scrollController.position.maxScrollExtent; + final currentScroll = _scrollController.position.pixels; + final viewportHeight = _scrollController.position.viewportDimension; + + print( + 'DEBUG: Scroll - current: $currentScroll, max: $maxScroll, viewport: $viewportHeight, threshold: ${maxScroll - 100}', + ); + + if (currentScroll >= maxScroll - 100 && maxScroll > 0) { + print('DEBUG: Достигнут порог скролла, вызываем _loadMoreMembers()'); + _loadMoreMembers(); + } + } + + void _loadMembersFromCache() { + final currentChat = _getCurrentGroupChat(); + if (currentChat == null) { + print('DEBUG: Чат не найден в кэше'); + return; + } + + + List membersRaw = []; + if (currentChat['members'] is List) { + membersRaw = currentChat['members'] as List; + } else if (currentChat['participants'] is List) { + membersRaw = currentChat['participants'] as List; + } + + print('DEBUG: Найдено ${membersRaw.length} участников в кэше чата'); + + final members = >[]; + for (final memberRaw in membersRaw) { + final memberData = memberRaw as Map; + final contact = memberData['contact'] as Map?; + if (contact != null) { + final memberId = contact['id'] as int; + if (!_loadedMemberIds.contains(memberId)) { + members.add({ + 'id': memberId, + 'contact': contact, + 'presence': memberData['presence'] as Map?, + 'dialogChatId': null, + }); + _loadedMemberIds.add(memberId); + } + } + } + + _loadedMembers.addAll(members); + print( + 'DEBUG: Загружено ${members.length} участников из кэша (всего: ${_loadedMembers.length})', + ); + } + + void _loadMoreMembers() { + print('DEBUG: _loadMoreMembers() вызван'); + if (_isLoadingMembers || !_hasMoreMembers || _lastMarker == null) { + print( + 'DEBUG: Пропуск загрузки - isLoading: $_isLoadingMembers, hasMore: $_hasMoreMembers, marker: $_lastMarker', + ); + return; + } + + print('DEBUG: Загружаем больше участников с маркером: $_lastMarker'); + _isLoadingMembers = true; + setState(() {}); + + ApiService.instance.getGroupMembers( + widget.chatId, + marker: _lastMarker!, + count: 50, + ); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + void _handleGroupMembersResponse(Map payload) { + print( + 'DEBUG: _handleGroupMembersResponse вызван с payload: ${payload.keys}', + ); + if (!mounted) return; + + List membersRaw = []; + if (payload['members'] is List) { + membersRaw = payload['members'] as List; + } else if (payload['participants'] is List) { + membersRaw = payload['participants'] as List; + } + + final members = >[]; + int skippedCount = 0; + int addedCount = 0; + + for (final memberRaw in membersRaw) { + final memberData = memberRaw as Map; + final contact = memberData['contact'] as Map?; + if (contact != null) { + final memberId = contact['id'] as int; + if (!_loadedMemberIds.contains(memberId)) { + members.add({ + 'id': memberId, + 'contact': contact, + 'presence': memberData['presence'] as Map?, + 'dialogChatId': null, + }); + _loadedMemberIds.add(memberId); + addedCount++; + } else { + skippedCount++; + } + } else { + print('WARNING: Участник без contact поля: $memberData'); + } + } + + print( + 'DEBUG: Обработано ${membersRaw.length} участников из ответа: добавлено $addedCount, пропущено $skippedCount (дубликаты)', + ); + + final markerFromPayload = payload['marker'] as int?; + int? nextMarker; + + if (markerFromPayload != null && markerFromPayload > 0) { + nextMarker = markerFromPayload; + } else if (members.isNotEmpty) { + final lastMember = members.last; + nextMarker = lastMember['id'] as int?; + } + + setState(() { + _loadedMembers.addAll(members); + _lastMarker = nextMarker; + _hasMoreMembers = nextMarker != null && nextMarker > 0; + _isLoadingMembers = false; + }); + + print( + 'DEBUG: Загружено ${members.length} новых участников (всего: ${_loadedMembers.length}), маркер: $nextMarker, есть еще: $_hasMoreMembers', + ); + print('DEBUG: _handleGroupMembersResponse завершен'); + } + + @override + void dispose() { + _contactSubscription?.cancel(); + _membersSubscription?.cancel(); + _scrollController.dispose(); + super.dispose(); + } + + Map? _getCurrentGroupChat() { + final chatData = ApiService.instance.lastChatsPayload; + if (chatData == null || chatData['chats'] == null) return null; + + final chats = chatData['chats'] as List; + try { + return chats.firstWhere( + (chat) => chat['id'] == widget.chatId, + orElse: () => null, + ); + } catch (e) { + return null; + } + } + + void _showEditGroupNameDialog() { + final nameController = TextEditingController(text: _currentContact.name); + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Изменить название группы'), + content: TextField( + controller: nameController, + decoration: const InputDecoration( + hintText: 'Введите новое название группы', + border: OutlineInputBorder(), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () { + final newName = nameController.text.trim(); + if (newName.isNotEmpty && newName != _currentContact.name) { + ApiService.instance.renameGroup(widget.chatId, newName); + + setState(() { + _currentContact = Contact( + id: _currentContact.id, + name: newName, + firstName: _currentContact.firstName, + lastName: _currentContact.lastName, + description: _currentContact.description, + photoBaseUrl: _currentContact.photoBaseUrl, + isBlocked: _currentContact.isBlocked, + isBlockedByMe: _currentContact.isBlockedByMe, + accountStatus: _currentContact.accountStatus, + status: _currentContact.status, + ); + }); + + widget.onChatUpdated?.call(); // Уведомляем список чатов + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Название группы изменено')), + ); + } + }, + child: const Text('Изменить'), + ), + ], + ), + ); + } + + void _showAddMemberDialog() { + final chatData = ApiService.instance.lastChatsPayload; + if (chatData == null || chatData['contacts'] == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось загрузить контакты')), + ); + return; + } + + final contacts = chatData['contacts'] as List; + final availableContacts = >[]; + + final currentChat = _getCurrentGroupChat(); + if (currentChat != null) { + final participants = + currentChat['participants'] as Map? ?? {}; + final participantIds = participants.keys + .map((id) => int.parse(id)) + .toSet(); + + for (final contact in contacts) { + final contactId = contact['id'] as int; + if (!participantIds.contains(contactId)) { + availableContacts.add(contact); + } + } + } else { + availableContacts.addAll(contacts.cast>()); + } + + if (availableContacts.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Нет доступных контактов для добавления')), + ); + return; + } + + showDialog( + context: context, + builder: (context) => _AddMemberDialog( + contacts: availableContacts, + onAddMembers: (selectedContacts) { + if (selectedContacts.isNotEmpty) { + ApiService.instance.addGroupMember(widget.chatId, selectedContacts); + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + 'Добавлено ${selectedContacts.length} участников', + ), + ), + ); + + } + }, + ), + ); + } + + void _showRemoveMemberDialog() { + final currentChat = _getCurrentGroupChat(); + if (currentChat == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось загрузить данные группы')), + ); + return; + } + + final participants = + currentChat['participants'] as Map? ?? {}; + final admins = currentChat['admins'] as List? ?? []; + + final chatData = ApiService.instance.lastChatsPayload; + if (chatData == null || chatData['contacts'] == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось загрузить контакты')), + ); + return; + } + + final contacts = chatData['contacts'] as List; + final contactMap = >{}; + for (final contact in contacts) { + contactMap[contact['id']] = contact; + } + + final removableMembers = >[]; + + for (final participantId in participants.keys) { + final id = int.parse(participantId); + if (id != widget.myId && !admins.contains(id)) { + final contact = contactMap[id]; + if (contact != null) { + removableMembers.add({ + 'id': id, + 'name': contact['names']?[0]?['name'] ?? 'Неизвестный', + 'contact': contact, + }); + } + } + } + + if (removableMembers.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Нет участников для удаления')), + ); + return; + } + + showDialog( + context: context, + builder: (context) => _RemoveMemberDialog( + members: removableMembers, + onRemoveMembers: (selectedMembers) { + if (selectedMembers.isNotEmpty) { + ApiService.instance.removeGroupMember( + widget.chatId, + selectedMembers, + ); + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Удалено ${selectedMembers.length} участников'), + ), + ); + + } + }, + ), + ); + } + + void _showPromoteToAdminDialog() { + final currentChat = _getCurrentGroupChat(); + if (currentChat == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось загрузить данные группы')), + ); + return; + } + + final participants = + currentChat['participants'] as Map? ?? {}; + final admins = currentChat['admins'] as List? ?? []; + + final chatData = ApiService.instance.lastChatsPayload; + if (chatData == null || chatData['contacts'] == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Не удалось загрузить контакты')), + ); + return; + } + + final contacts = chatData['contacts'] as List; + final contactMap = >{}; + for (final contact in contacts) { + contactMap[contact['id']] = contact; + } + + final promotableMembers = >[]; + + for (final participantId in participants.keys) { + final id = int.parse(participantId); + if (id != widget.myId && !admins.contains(id)) { + final contact = contactMap[id]; + if (contact != null) { + promotableMembers.add({ + 'id': id, + 'name': contact['names']?[0]?['name'] ?? 'Неизвестный', + 'contact': contact, + }); + } + } + } + + if (promotableMembers.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Нет участников для назначения администратором'), + ), + ); + return; + } + + showDialog( + context: context, + builder: (context) => _PromoteAdminDialog( + members: promotableMembers, + onPromoteToAdmin: (memberId) { + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Функция назначения администратора будет добавлена', + ), + ), + ); + }, + ), + ); + } + + void _showLeaveGroupDialog() { + showDialog( + context: context, + builder: (dialogContext) => AlertDialog( + title: const Text('Выйти из группы'), + content: Text( + 'Вы уверены, что хотите выйти из группы "${_currentContact.name}"?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () { + Navigator.of(dialogContext).pop(); // Закрываем диалог + try { + ApiService.instance.leaveGroup(widget.chatId); + + if (mounted) { + + Navigator.of(context) + ..pop() + ..pop(); + widget.onChatUpdated?.call(); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Вы вышли из группы'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при выходе из группы: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + }, + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + ), + child: const Text('Выйти'), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: CustomScrollView( + controller: _scrollController, + slivers: [ + _buildSliverAppBar(), + _buildGroupManagementButtons(), + SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Text( + 'Участники', + style: Theme.of(context).textTheme.titleSmall?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + _buildGroupMembersList(), + ], + ), + ); + } + + Widget _buildSliverAppBar() { + const double appBarHeight = 250.0; + + return SliverAppBar( + expandedHeight: appBarHeight, + pinned: true, + floating: false, + stretch: true, + backgroundColor: Theme.of(context).colorScheme.surface, + flexibleSpace: FlexibleSpaceBar( + title: Text( + _currentContact.name, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + centerTitle: false, + titlePadding: const EdgeInsetsDirectional.only( + start: 56.0, + bottom: 16.0, + end: 16.0, + ), + background: Stack( + fit: StackFit.expand, + children: [ + Hero( + tag: 'contact_avatar_${widget.initialContact.id}', + child: Material( + type: MaterialType.transparency, + child: (_currentContact.photoBaseUrl != null) + ? Image.network( + _currentContact.photoBaseUrl!, + fit: BoxFit.cover, + height: appBarHeight, + width: double.infinity, + errorBuilder: (context, error, stackTrace) => Container( + height: appBarHeight, + width: double.infinity, + color: Theme.of( + context, + ).colorScheme.secondaryContainer, + child: Center( + child: Icon( + Icons.error_outline, + color: Theme.of( + context, + ).colorScheme.onSecondaryContainer, + size: 48, + ), + ), + ), + ) + : Container( + height: appBarHeight, + width: double.infinity, + color: Theme.of(context).colorScheme.secondaryContainer, + child: Center( + child: Text( + _currentContact.name.isNotEmpty + ? _currentContact.name[0].toUpperCase() + : '?', + style: TextStyle( + fontSize: 96, + color: Theme.of( + context, + ).colorScheme.onSecondaryContainer, + ), + ), + ), + ), + ), + ), + + Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, + Colors.black.withOpacity(0.1), + Colors.black.withOpacity(0.5), + ], + stops: const [0.5, 0.7, 1.0], + ), + ), + ), + ], + ), + ), + ); + } + + Widget _buildGroupManagementButtons() { + final colorScheme = Theme.of(context).colorScheme; + + + bool amIAdmin = false; + final currentChat = _getCurrentGroupChat(); + if (currentChat != null) { + final admins = currentChat['admins'] as List? ?? []; + amIAdmin = admins.contains(widget.myId); + } + + return SliverPadding( + padding: const EdgeInsets.all(16.0), + sliver: SliverList( + delegate: SliverChildListDelegate.fixed([ + if (amIAdmin) ...[ + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _showEditGroupNameDialog, + icon: const Icon(Icons.edit), + label: const Text('Изменить название группы'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + const SizedBox(height: 12), + Row( + children: [ + Expanded( + child: FilledButton.icon( + onPressed: _showAddMemberDialog, + icon: const Icon(Icons.person_add), + label: const Text('Добавить'), + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + const SizedBox(width: 8), + Expanded( + child: ElevatedButton.icon( + onPressed: _showRemoveMemberDialog, + icon: const Icon(Icons.person_remove), + label: const Text('Удалить'), + style: ElevatedButton.styleFrom( + backgroundColor: colorScheme.errorContainer, + foregroundColor: colorScheme.onErrorContainer, + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + ], + ), + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _showPromoteToAdminDialog, + icon: const Icon(Icons.admin_panel_settings), + label: const Text('Назначить администратором'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + const SizedBox(height: 16), + const Divider(), + const SizedBox(height: 8), + ], + + + SizedBox( + width: double.infinity, + child: FilledButton.icon( + onPressed: _showLeaveGroupDialog, + icon: const Icon(Icons.exit_to_app), + label: const Text('Выйти из группы'), + style: FilledButton.styleFrom( + backgroundColor: colorScheme.error, + foregroundColor: colorScheme.onError, + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + ]), + ), + ); + } + + Widget _buildGroupMembersList() { + final chatData = ApiService.instance.lastChatsPayload; + final contacts = chatData?['contacts'] as List? ?? []; + final contactMap = >{}; + for (final contact in contacts) { + contactMap[contact['id']] = contact; + } + + final currentChat = _getCurrentGroupChat(); + final admins = currentChat?['admins'] as List? ?? []; + final owner = currentChat?['owner'] as int?; + + print('DEBUG: owner=$owner, admins=$admins, myId=${widget.myId}'); + + final members = >[]; + + print( + 'DEBUG: Строим список из ${_loadedMembers.length} загруженных участников', + ); + + for (final memberData in _loadedMembers) { + final id = memberData['id'] as int?; + if (id == null) continue; + + final contactData = memberData['contact'] as Map?; + final contact = contactData ?? contactMap[id]; + final isAdmin = admins.contains(id); + final isOwner = owner != null && id == owner; + + String? name; + String? avatarUrl; + if (contact?['names'] is List) { + final namesList = contact?['names'] as List; + if (namesList.isNotEmpty) { + final nameData = namesList[0] as Map?; + if (nameData != null) { + final firstName = nameData['firstName'] as String? ?? ''; + final lastName = nameData['lastName'] as String? ?? ''; + final fullName = '$firstName $lastName'.trim(); + name = fullName.isNotEmpty + ? fullName + : (nameData['name'] as String? ?? 'Неизвестный'); + } + } + } + if (name == null || name.isEmpty) { + name = 'Неизвестный'; + } + avatarUrl = + contact?['baseUrl'] as String? ?? contact?['baseRawUrl'] as String?; + + String role; + if (isOwner) { + role = 'Владелец'; + } else if (isAdmin) { + role = 'Администратор'; + } else { + role = 'Участник'; + } + + final dialogChatId = memberData['dialogChatId'] as int?; + + members.add({ + 'id': id, + 'name': name, + 'role': role, + 'isAdmin': isAdmin, + 'isOwner': isOwner, + 'contact': contact, + 'avatarUrl': avatarUrl, + 'dialogChatId': dialogChatId, + }); + } + + members.sort((a, b) { + final aId = a['id'] as int; + final bId = b['id'] as int; + final aIsMe = aId == widget.myId; + final bIsMe = bId == widget.myId; + final aIsOwner = a['isOwner'] as bool; + final bIsOwner = b['isOwner'] as bool; + final aIsAdmin = a['isAdmin'] as bool; + final bIsAdmin = b['isAdmin'] as bool; + + if (aIsMe && !bIsMe) return -1; + if (!aIsMe && bIsMe) return 1; + if (aIsOwner && !bIsOwner) return -1; + if (!aIsOwner && bIsOwner) return 1; + if (aIsAdmin && !bIsAdmin) return -1; + if (!aIsAdmin && bIsAdmin) return 1; + return 0; + }); + + print('DEBUG: Итого участников для отображения: ${members.length}'); + + if (_loadedMembers.isEmpty && _isLoadingMembers) { + return const SliverToBoxAdapter( + child: Center( + child: Padding( + padding: EdgeInsets.all(16.0), + child: CircularProgressIndicator(), + ), + ), + ); + } + + if (_loadedMembers.isEmpty) { + return const SliverToBoxAdapter( + child: Center( + child: Padding( + padding: EdgeInsets.all(16.0), + child: Text('Участники не загружены'), + ), + ), + ); + } + + return SliverList( + delegate: SliverChildBuilderDelegate((context, index) { + if (index == members.length) { + if (_isLoadingMembers) { + return const Center( + child: Padding( + padding: EdgeInsets.all(16.0), + child: CircularProgressIndicator(), + ), + ); + } + if (!_hasMoreMembers) { + return const SizedBox.shrink(); + } + return const SizedBox.shrink(); + } + + final member = members[index]; + final isMe = member['id'] == widget.myId; + final isAdmin = member['isAdmin'] as bool; + final isOwner = member['isOwner'] as bool; + final avatarUrl = member['avatarUrl'] as String?; + final memberName = member['name'] as String; + + final contact = member['contact'] as Map?; + final contactNames = contact?['names'] as List?; + String? firstName; + String? lastName; + if (contactNames != null && contactNames.isNotEmpty) { + final nameData = contactNames[0] as Map?; + firstName = nameData?['firstName'] as String?; + lastName = nameData?['lastName'] as String?; + } + final dialogChatId = member['dialogChatId'] as int?; + + return ListTile( + onTap: isMe + ? null + : () { + final userId = member['id'] as int; + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => UserProfilePanel( + userId: userId, + name: memberName, + firstName: firstName, + lastName: lastName, + avatarUrl: avatarUrl, + description: contact?['description'] as String?, + myId: widget.myId, + currentChatId: widget.chatId, + contactData: contact, + dialogChatId: dialogChatId, + ), + ); + }, + leading: AvatarCacheService().getAvatarWidget( + avatarUrl, + userId: member['id'] as int, + size: 40, + fallbackText: memberName, + backgroundColor: isMe + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.secondaryContainer, + textColor: isMe + ? Theme.of(context).colorScheme.onPrimary + : Theme.of(context).colorScheme.onSecondaryContainer, + ), + title: Row( + children: [ + Expanded( + child: Text( + '$memberName ${isMe ? '(Вы)' : ''}', + style: TextStyle( + fontWeight: isMe || isOwner + ? FontWeight.bold + : FontWeight.normal, + color: isMe || isOwner + ? Theme.of(context).colorScheme.primary + : null, + ), + ), + ), + ], + ), + subtitle: Text( + member['role'].toString(), + style: TextStyle( + color: isOwner + ? Colors.amber[700] + : isAdmin + ? Theme.of(context).colorScheme.primary + : null, + ), + ), + trailing: isOwner + ? Icon(Icons.star, color: Colors.amber, size: 20) + : isAdmin + ? Icon( + Icons.admin_panel_settings, + color: Theme.of(context).colorScheme.primary, + size: 20, + ) + : null, + ); + }, childCount: members.length + (_isLoadingMembers ? 1 : 0)), + ); + } +} + +class _AddMemberDialog extends StatefulWidget { + final List> contacts; + final Function(List) onAddMembers; + + const _AddMemberDialog({required this.contacts, required this.onAddMembers}); + + @override + State<_AddMemberDialog> createState() => _AddMemberDialogState(); +} + +class _AddMemberDialogState extends State<_AddMemberDialog> { + final Set _selectedContacts = {}; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Добавить участников'), + content: SizedBox( + width: double.maxFinite, + height: 400, + child: ListView.builder( + itemCount: widget.contacts.length, + itemBuilder: (context, index) { + final contact = widget.contacts[index]; + final contactId = contact['id'] as int; + final contactName = contact['names']?[0]?['name'] ?? 'Неизвестный'; + final isSelected = _selectedContacts.contains(contactId); + + return CheckboxListTile( + value: isSelected, + onChanged: (value) { + setState(() { + if (value == true) { + _selectedContacts.add(contactId); + } else { + _selectedContacts.remove(contactId); + } + }); + }, + title: Text(contactName), + subtitle: Text('ID: $contactId'), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: _selectedContacts.isEmpty + ? null + : () => widget.onAddMembers(_selectedContacts.toList()), + child: Text('Добавить (${_selectedContacts.length})'), + ), + ], + ); + } +} + +class _RemoveMemberDialog extends StatefulWidget { + final List> members; + final Function(List) onRemoveMembers; + + const _RemoveMemberDialog({ + required this.members, + required this.onRemoveMembers, + }); + + @override + State<_RemoveMemberDialog> createState() => _RemoveMemberDialogState(); +} + +class _RemoveMemberDialogState extends State<_RemoveMemberDialog> { + final Set _selectedMembers = {}; + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Удалить участников'), + content: SizedBox( + width: double.maxFinite, + height: 400, + child: ListView.builder( + itemCount: widget.members.length, + itemBuilder: (context, index) { + final member = widget.members[index]; + final memberId = member['id'] as int; + final memberName = member['name'] as String; + final isSelected = _selectedMembers.contains(memberId); + + return CheckboxListTile( + value: isSelected, + onChanged: (value) { + setState(() { + if (value == true) { + _selectedMembers.add(memberId); + } else { + _selectedMembers.remove(memberId); + } + }); + }, + title: Text(memberName), + subtitle: Text('ID: $memberId'), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: _selectedMembers.isEmpty + ? null + : () => widget.onRemoveMembers(_selectedMembers.toList()), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + ), + child: Text('Удалить (${_selectedMembers.length})'), + ), + ], + ); + } +} + +class _PromoteAdminDialog extends StatelessWidget { + final List> members; + final Function(int) onPromoteToAdmin; + + const _PromoteAdminDialog({ + required this.members, + required this.onPromoteToAdmin, + }); + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: const Text('Назначить администратором'), + content: SizedBox( + width: double.maxFinite, + height: 300, + child: ListView.builder( + itemCount: members.length, + itemBuilder: (context, index) { + final member = members[index]; + final memberId = member['id'] as int; + final memberName = member['name'] as String; + + return ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of(context).colorScheme.primary, + child: Text( + memberName[0].toUpperCase(), + style: TextStyle( + color: Theme.of(context).colorScheme.onPrimary, + ), + ), + ), + title: Text(memberName), + subtitle: Text('ID: $memberId'), + trailing: const Icon(Icons.admin_panel_settings), + onTap: () => onPromoteToAdmin(memberId), + ); + }, + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + ], + ); + } +} diff --git a/lib/screens/settings/about_screen.dart b/lib/screens/settings/about_screen.dart new file mode 100644 index 0000000..0a43105 --- /dev/null +++ b/lib/screens/settings/about_screen.dart @@ -0,0 +1,440 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/tos_screen.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AboutScreen extends StatelessWidget { + final bool isModal; + + const AboutScreen({super.key, this.isModal = false}); + + + Future _launchUrl(String url) async { + if (!await launchUrl(Uri.parse(url))) { + + print('Could not launch $url'); + } + } + + + Widget _buildTeamMember( + BuildContext context, { + required String name, + required String role, + required String description, + }) { + final textTheme = Theme.of(context).textTheme; + final colorScheme = Theme.of(context).colorScheme; + return Padding( + padding: const EdgeInsets.only(bottom: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RichText( + text: TextSpan( + style: textTheme.bodyMedium?.copyWith(height: 1.5), + children: [ + TextSpan( + text: '• $name', + style: const TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: ' — $role'), + ], + ), + ), + Padding( + padding: const EdgeInsets.only(left: 16.0, top: 2.0), + child: Text( + description, + style: textTheme.bodySmall?.copyWith( + fontStyle: FontStyle.italic, + color: colorScheme.onSurfaceVariant, + ), + ), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + if (isModal) { + return buildModalContent(context); + } + + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text("О нас"), + ), + body: ListView( + padding: const EdgeInsets.all(24.0), + children: [ + Text( + "Команда «Komet»", + style: Theme.of( + context, + ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 12), + const Text( + "Мы — команда энтузиастов, создавшая Komet. Нас объединила страсть к технологиям и желание дать пользователям свободу выбора.", + style: TextStyle(fontSize: 16, height: 1.5), + ), + const SizedBox(height: 24), + + + Card( + clipBehavior: Clip.antiAlias, // для скругления углов InkWell + child: ListTile( + leading: const Icon(Icons.description_outlined), + title: const Text("Пользовательское соглашение"), + subtitle: const Text("Правовая информация и условия"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const TosScreen()), + ); + }, + ), + ), + + + const SizedBox(height: 24), + Text( + "Наша команда:", + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + _buildTeamMember( + context, + name: "Floppy", + role: "руководитель проекта", + description: "Стратегическое видение и общее руководство", + ), + _buildTeamMember( + context, + name: "Klocky", + role: "главный программист", + description: "Архитектура и ключевые технические решения", + ), + _buildTeamMember( + context, + name: "Noxzion", + role: "программист", + description: "Участие в разработке приложения и сайта", + ), + _buildTeamMember( + context, + name: "Jganenok", + role: "программист", + description: "Участие в разработке и пользовательские интерфейсы", + ), + _buildTeamMember( + context, + name: "Zennix", + role: "программист", + description: "Участие в разработке и технические решения", + ), + _buildTeamMember( + context, + name: "Qmark", + role: "программист", + description: "Участие в разработке и технические решения", + ), + _buildTeamMember( + context, + name: "ivan2282", + role: "программист", + description: "Основной программист клиента на GNU/Linux", + ), + _buildTeamMember( + context, + name: "Ink", + role: "документация сервера", + description: "Техническая документация и API", + ), + _buildTeamMember( + context, + name: "Килобайт", + role: "веб-разработчик и дизайнер", + description: "Веб-платформа и дизайн-система", + ), + _buildTeamMember( + context, + name: "WhiteMax", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + _buildTeamMember( + context, + name: "Mixott Orego", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + _buildTeamMember( + context, + name: "Raspberry", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + const SizedBox(height: 24), + const Text( + "Мы верим в открытость, прозрачность и право пользователей на выбор. Komet — это наш ответ излишним ограничениям.", + style: TextStyle(fontSize: 16, height: 1.5), + ), + const SizedBox(height: 24), + const Divider(), + const SizedBox(height: 16), + InkWell( + onTap: () => _launchUrl('https://t.me/TeamKomet'), + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: RichText( + text: TextSpan( + style: Theme.of( + context, + ).textTheme.bodyMedium?.copyWith(height: 1.5), + children: [ + const TextSpan(text: "Связаться с нами: \n"), + TextSpan( + text: "Телеграм-канал: https://t.me/TeamKomet", + style: TextStyle( + color: colors.primary, + decoration: TextDecoration.underline, + decorationColor: colors.primary, + ), + ), + ], + ), + ), + ), + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + + Column( + children: [ + Image.asset( + 'assets/icon/komet.png', + width: 128, + height: 128, + ), + const SizedBox(height: 16), + Text( + 'Komet', + style: TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + const SizedBox(height: 8), + Text( + 'Версия 0.3.0', + style: TextStyle( + fontSize: 16, + color: colors.onSurface.withOpacity(0.7), + ), + ), + ], + ), + const SizedBox(height: 20), + + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Команда разработки', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + const SizedBox(height: 12), + Text( + 'Мы — команда энтузиастов, создавшая Komet. Нас объединила страсть к технологиям и желание дать пользователям свободу выбора.', + style: TextStyle( + color: colors.onSurface.withOpacity(0.8), + height: 1.5, + ), + ), + const SizedBox(height: 16), + Text( + 'Наша команда:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + const SizedBox(height: 12), + _buildTeamMember( + context, + name: "Floppy", + role: "руководитель проекта", + description: "Стратегическое видение и общее руководство", + ), + _buildTeamMember( + context, + name: "Klocky", + role: "главный программист", + description: "Архитектура и ключевые технические решения", + ), + _buildTeamMember( + context, + name: "Noxzion", + role: "программист", + description: "Участие в разработке приложения и сайта", + ), + _buildTeamMember( + context, + name: "Jganenok", + role: "программист", + description: "Участие в разработке и пользовательские интерфейсы", + ), + _buildTeamMember( + context, + name: "Zennix", + role: "программист", + description: "Участие в разработке и технические решения", + ), + _buildTeamMember( + context, + name: "Qmark", + role: "программист", + description: "Участие в разработке и технические решения", + ), + _buildTeamMember( + context, + name: "Ink", + role: "документация сервера", + description: "Техническая документация и API", + ), + _buildTeamMember( + context, + name: "Килобайт", + role: "веб-разработчик и дизайнер", + description: "Веб-платформа и дизайн-система", + ), + _buildTeamMember( + context, + name: "WhiteMax", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + _buildTeamMember( + context, + name: "Mixott Orego", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + _buildTeamMember( + context, + name: "Raspberry", + role: "PR-менеджер", + description: "Коммуникация с сообществом и продвижение проекта", + ), + const SizedBox(height: 16), + Text( + 'Мы верим в открытость, прозрачность и право пользователей на выбор. Komet — это наш ответ излишним ограничениям.', + style: TextStyle( + color: colors.onSurface.withOpacity(0.8), + height: 1.5, + ), + ), + const SizedBox(height: 16), + InkWell( + onTap: () => _launchUrl('https://t.me/TeamKomet'), + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: RichText( + text: TextSpan( + style: TextStyle( + color: colors.onSurface.withOpacity(0.8), + height: 1.5, + ), + children: [ + const TextSpan(text: "Связаться с нами: \n"), + TextSpan( + text: "Телеграм-канал: https://t.me/TeamKomet", + style: TextStyle( + color: colors.primary, + decoration: TextDecoration.underline, + decorationColor: colors.primary, + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + const SizedBox(height: 20), + + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Полезные ссылки', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + const SizedBox(height: 12), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.description_outlined), + title: const Text('Пользовательское соглашение'), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const TosScreen(), + ), + ); + }, + ), + ], + ), + ), + ], + ), + ); + } +} + diff --git a/lib/screens/settings/animations_screen.dart b/lib/screens/settings/animations_screen.dart new file mode 100644 index 0000000..fedf5ff --- /dev/null +++ b/lib/screens/settings/animations_screen.dart @@ -0,0 +1,370 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; + + +class AnimationsScreen extends StatelessWidget { + const AnimationsScreen({super.key}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final theme = context.watch(); + + return Scaffold( + appBar: AppBar( + title: const Text("Настройки анимаций"), + backgroundColor: colors.surface, + surfaceTintColor: Colors.transparent, + ), + body: ListView( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + children: [ + + _ModernSection( + title: "Анимации сообщений", + children: [ + _DropdownSettingTile( + icon: Icons.chat_bubble_outline, + title: "Стиль появления", + items: TransitionOption.values, + value: theme.messageTransition, + onChanged: (value) { + if (value != null) theme.setMessageTransition(value); + }, + itemToString: (item) => item.displayName, + ), + const Divider(height: 24), + _CustomSettingTile( + icon: Icons.photo_library_outlined, + title: "Анимация фото", + subtitle: "Плавное появление фото в чате", + child: Switch( + value: theme.animatePhotoMessages, + onChanged: (value) => theme.setAnimatePhotoMessages(value), + ), + ), + if (theme.messageTransition == TransitionOption.slide) ...[ + const SizedBox(height: 8), + _SliderTile( + icon: Icons.open_in_full_rounded, + label: "Расстояние слайда", + value: theme.messageSlideDistance, + min: 1.0, + max: 200.0, + divisions: 20, + onChanged: (value) => theme.setMessageSlideDistance(value), + displayValue: "${theme.messageSlideDistance.round()}px", + ), + ], + ], + ), + const SizedBox(height: 24), + + + _ModernSection( + title: "Переходы и эффекты", + children: [ + _DropdownSettingTile( + icon: Icons.swap_horiz_rounded, + title: "Переход между чатами", + items: TransitionOption.values, + value: theme.chatTransition, + onChanged: (value) { + if (value != null) theme.setChatTransition(value); + }, + itemToString: (item) => item.displayName, + ), + const Divider(height: 24), + _DropdownSettingTile( + icon: Icons.auto_awesome_motion_outlined, + title: "Дополнительные эффекты", + subtitle: "Для диалогов и других элементов", + items: TransitionOption.values, + value: theme.extraTransition, + onChanged: (value) { + if (value != null) theme.setExtraTransition(value); + }, + itemToString: (item) => item.displayName, + ), + if (theme.extraTransition == TransitionOption.slide) ...[ + const SizedBox(height: 8), + _SliderTile( + icon: Icons.bolt_rounded, + label: "Сила эффекта", + value: theme.extraAnimationStrength, + min: 1.0, + max: 400.0, + divisions: 20, + onChanged: (value) => theme.setExtraAnimationStrength(value), + displayValue: "${theme.extraAnimationStrength.round()}", + ), + ], + ], + ), + const SizedBox(height: 24), + + + _ModernSection( + title: "Управление", + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric( + vertical: 4, + horizontal: 4, + ), + leading: Icon(Icons.restore_rounded, color: colors.error), + title: Text( + "Сбросить настройки анимаций", + style: TextStyle(color: colors.error), + ), + subtitle: const Text("Вернуть все значения по умолчанию"), + onTap: () => _showResetDialog(context, theme), + ), + ], + ), + ], + ), + ); + } + + void _showResetDialog(BuildContext context, ThemeProvider theme) { + showDialog( + context: context, + builder: (context) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + title: const Text('Сбросить настройки?'), + content: const Text( + 'Все параметры анимаций на этом экране будут возвращены к значениям по умолчанию.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton.icon( + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + foregroundColor: Theme.of(context).colorScheme.onError, + ), + onPressed: () { + theme.resetAnimationsToDefault(); + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Настройки анимаций сброшены'), + behavior: SnackBarBehavior.floating, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + ), + ); + }, + icon: const Icon(Icons.restore), + label: const Text('Сбросить'), + ), + ], + ), + ); + } +} + + + + +class _ModernSection extends StatelessWidget { + final String title; + final List children; + + const _ModernSection({required this.title, required this.children}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16.0, bottom: 12.0), + child: Text( + title.toUpperCase(), + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 14, + letterSpacing: 0.8, + ), + ), + ), + Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: colors.outlineVariant.withOpacity(0.3)), + ), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Column(children: children), + ), + ), + ], + ); + } +} + +class _CustomSettingTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final Widget child; + + const _CustomSettingTile({ + required this.icon, + required this.title, + this.subtitle, + required this.child, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + children: [ + Icon(icon, color: Theme.of(context).colorScheme.primary), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + ), + ), + if (subtitle != null) + Text( + subtitle!, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), + ), + child, + ], + ), + ); + } +} + +class _DropdownSettingTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final T value; + final List items; + final ValueChanged onChanged; + final String Function(T) itemToString; + + const _DropdownSettingTile({ + required this.icon, + required this.title, + this.subtitle, + required this.value, + required this.items, + required this.onChanged, + required this.itemToString, + }); + + @override + Widget build(BuildContext context) { + return _CustomSettingTile( + icon: icon, + title: title, + subtitle: subtitle, + child: DropdownButton( + value: value, + underline: const SizedBox.shrink(), + onChanged: onChanged, + items: items.map((item) { + return DropdownMenuItem(value: item, child: Text(itemToString(item))); + }).toList(), + ), + ); + } +} + +class _SliderTile extends StatelessWidget { + final IconData? icon; + final String label; + final double value; + final double min; + final double max; + final int divisions; + final ValueChanged onChanged; + final String displayValue; + + const _SliderTile({ + this.icon, + required this.label, + required this.value, + required this.min, + required this.max, + required this.divisions, + required this.onChanged, + required this.displayValue, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + if (icon != null) ...[ + Icon( + icon, + size: 20, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + const SizedBox(width: 12), + ], + Expanded( + child: Text(label, style: const TextStyle(fontSize: 14)), + ), + Text( + displayValue, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + SizedBox( + height: 30, + child: Slider( + value: value, + min: min, + max: max, + divisions: divisions, + onChanged: onChanged, + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/settings/appearance_settings_screen.dart b/lib/screens/settings/appearance_settings_screen.dart new file mode 100644 index 0000000..238d0c0 --- /dev/null +++ b/lib/screens/settings/appearance_settings_screen.dart @@ -0,0 +1,325 @@ + + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:gwid/screens/settings/customization_screen.dart'; +import 'package:gwid/screens/settings/animations_screen.dart'; + +class AppearanceSettingsScreen extends StatelessWidget { + final bool isModal; + + const AppearanceSettingsScreen({super.key, this.isModal = false}); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final colors = Theme.of(context).colorScheme; + + if (isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar(title: const Text("Внешний вид")), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Кастомизация", colors), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.palette_outlined), + title: const Text("Настройки тем"), + subtitle: const Text("Тема, обои и другие настройки"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => CustomizationScreen(), + ), + ); + }, + ), + + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.animation), + title: const Text("Настройки анимаций"), + subtitle: const Text("Анимации сообщений и переходов"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => AnimationsScreen(), + ), + ); + }, + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Производительность", colors), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.speed_outlined), + title: const Text("Оптимизация чатов"), + subtitle: const Text("Улучшить производительность в чатах"), + value: theme.optimizeChats, + onChanged: (value) => theme.setOptimizeChats(value), + ), + + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.flash_on_outlined), + title: const Text("Ультра оптимизация"), + subtitle: const Text("Максимальная производительность"), + value: theme.ultraOptimizeChats, + onChanged: (value) => theme.setUltraOptimizeChats(value), + ), + ], + ), + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + final theme = context.watch(); + final colors = Theme.of(context).colorScheme; + return ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Кастомизация", colors), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.palette_outlined), + title: const Text("Настройки тем"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const CustomizationScreen(), + ), + ); + }, + ), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.animation_outlined), + title: const Text("Анимации"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const AnimationsScreen(), + ), + ); + }, + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Производительность", colors), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.speed_outlined), + title: const Text("Ультра-оптимизация чатов"), + subtitle: const Text("Максимальная производительность"), + value: theme.ultraOptimizeChats, + onChanged: (value) => theme.setUltraOptimizeChats(value), + ), + ], + ), + ), + ], + ); + } + + Widget _buildModalSettings(BuildContext context, ThemeProvider theme, ColorScheme colors) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Внешний вид", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Кастомизация", colors), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.palette_outlined), + title: const Text("Настройки тем"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const CustomizationScreen(), + ), + ); + }, + ), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.animation_outlined), + title: const Text("Анимации"), + trailing: const Icon(Icons.chevron_right), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const AnimationsScreen(), + ), + ); + }, + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Производительность", colors), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.speed_outlined), + title: const Text("Ультра-оптимизация чатов"), + subtitle: const Text("Максимальная производительность"), + value: theme.ultraOptimizeChats, + onChanged: (value) => theme.setUltraOptimizeChats(value), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildSectionTitle(String title, ColorScheme colors) { + return Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + title, + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + ); + } +} + +class _OutlinedSection extends StatelessWidget { + final Widget child; + const _OutlinedSection({required this.child}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border.all(color: colors.outline.withOpacity(0.3)), + borderRadius: BorderRadius.circular(12), + ), + child: child, + ); + } +} diff --git a/lib/screens/settings/bypass_screen.dart b/lib/screens/settings/bypass_screen.dart new file mode 100644 index 0000000..94e7530 --- /dev/null +++ b/lib/screens/settings/bypass_screen.dart @@ -0,0 +1,331 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; + +class BypassScreen extends StatelessWidget { + final bool isModal; + + const BypassScreen({super.key, this.isModal = false}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + if (isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar(title: const Text("Bypass")), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.info_outline, color: colors.primary), + const SizedBox(width: 8), + Text( + "Обход блокировки", + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + "Эта функция позволяет отправлять сообщения заблокированным пользователям, " + "даже если они заблокировали вас. Включите эту опцию, если хотите обойти " + "стандартные ограничения мессенджера.", + style: TextStyle(color: colors.onSurfaceVariant), + ), + ], + ), + ), + + const SizedBox(height: 24), + + Consumer( + builder: (context, themeProvider, child) { + return Card( + child: SwitchListTile( + title: const Text( + "Обход блокировки", + style: TextStyle(fontWeight: FontWeight.w600), + ), + subtitle: const Text( + "Разрешить отправку сообщений заблокированным пользователям", + ), + value: themeProvider.blockBypass, + onChanged: (value) { + themeProvider.setBlockBypass(value); + }, + secondary: Icon( + themeProvider.blockBypass + ? Icons.psychology + : Icons.psychology_outlined, + color: themeProvider.blockBypass + ? colors.primary + : colors.onSurfaceVariant, + ), + ), + ); + }, + ), + + const SizedBox(height: 16), + + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.warning_outlined, + color: colors.primary, + size: 16, + ), + const SizedBox(width: 8), + Text( + "Важно знать", + style: TextStyle( + fontWeight: FontWeight.w600, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + "Используя любую из bypass функций мы не несем ответственности за ваш аккаунт", + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildModalSettings(BuildContext context, ColorScheme colors) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Bypass", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: colors.outline.withOpacity(0.3), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + color: colors.primary, + size: 20, + ), + const SizedBox(width: 8), + Text( + "Информация", + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + "Эта функция предназначена для обхода ограничений и блокировок. Используйте с осторожностью и только в законных целях.", + style: TextStyle( + color: colors.onSurface.withOpacity(0.8), + fontSize: 14, + ), + ), + ], + ), + ), + const SizedBox(height: 20), + Consumer( + builder: (context, themeProvider, child) { + return SwitchListTile( + title: const Text("Включить обход"), + subtitle: const Text("Активировать функции обхода ограничений"), + value: false, // Временно отключено + onChanged: (value) { + + }, + ); + }, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: colors.outline.withOpacity(0.3), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + color: colors.primary, + size: 20, + ), + const SizedBox(width: 8), + Text( + "Информация", + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + "Эта функция предназначена для обхода ограничений и блокировок. Используйте с осторожностью. Всю ответственность за ваш аккаунт несете только вы.", + style: TextStyle( + color: colors.onSurface.withOpacity(0.8), + fontSize: 14, + ), + ), + ], + ), + ), + const SizedBox(height: 20), + Consumer( + builder: (context, themeProvider, child) { + return SwitchListTile( + title: const Text("Обход блокировки"), + subtitle: const Text("Активировать функции обхода ограничений"), + value: themeProvider.blockBypass, + onChanged: (value) { + themeProvider.setBlockBypass(value); + }, + ); + }, + ), + ], + ); + } +} diff --git a/lib/screens/settings/customization_screen.dart b/lib/screens/settings/customization_screen.dart new file mode 100644 index 0000000..38c09eb --- /dev/null +++ b/lib/screens/settings/customization_screen.dart @@ -0,0 +1,1503 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:provider/provider.dart'; +import 'package:gwid/theme_provider.dart'; +import 'dart:io'; +import 'dart:ui'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/widgets/chat_message_bubble.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:file_picker/file_picker.dart'; +import 'dart:convert'; +import 'package:video_player/video_player.dart'; + +void _showColorPicker( + BuildContext context, { + required Color initialColor, + required ValueChanged onColorChanged, +}) { + Color pickedColor = initialColor; + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text("Выберите цвет"), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + content: SingleChildScrollView( + child: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return ColorPicker( + pickerColor: pickedColor, + onColorChanged: (color) { + setState(() => pickedColor = color); + }, + enableAlpha: false, + pickerAreaHeightPercent: 0.8, + ); + }, + ), + ), + actions: [ + TextButton( + child: const Text('Отмена'), + onPressed: () => Navigator.of(context).pop(), + ), + TextButton( + child: const Text('Готово'), + onPressed: () { + onColorChanged(pickedColor); + Navigator.of(context).pop(); + }, + ), + ], + ), + ); +} + +class CustomizationScreen extends StatefulWidget { + const CustomizationScreen({super.key}); + + @override + State createState() => _CustomizationScreenState(); +} + +class _CustomizationScreenState extends State { + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final colors = Theme.of(context).colorScheme; + final bool isSystemTheme = theme.appTheme == AppTheme.system; + final bool isCurrentlyDark = + Theme.of(context).brightness == Brightness.dark; + + if (isSystemTheme) { + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + final systemAccentColor = Theme.of(context).colorScheme.primary; + theme.updateBubbleColorsForSystemTheme(systemAccentColor); + } + }); + } + + final Color? myBubbleColorToShow = isCurrentlyDark + ? theme.myBubbleColorDark + : theme.myBubbleColorLight; + final Color? theirBubbleColorToShow = isCurrentlyDark + ? theme.theirBubbleColorDark + : theme.theirBubbleColorLight; + + final Function(Color?) myBubbleSetter = isCurrentlyDark + ? theme.setMyBubbleColorDark + : theme.setMyBubbleColorLight; + final Function(Color?) theirBubbleSetter = isCurrentlyDark + ? theme.setTheirBubbleColorDark + : theme.setTheirBubbleColorLight; + + final Color myBubbleFallback = isCurrentlyDark + ? const Color(0xFF2b5278) + : Colors.blue.shade100; + final Color theirBubbleFallback = isCurrentlyDark + ? const Color(0xFF182533) + : Colors.grey.shade200; + + return Scaffold( + appBar: AppBar( + title: const Text("Кастомизация"), + surfaceTintColor: Colors.transparent, + backgroundColor: colors.surface, + ), + body: ListView( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 24), + children: [ + const _MessagePreviewSection(), + const SizedBox(height: 24), + const _ThemeManagementSection(), + const SizedBox(height: 24), + _ModernSection( + title: "Тема приложения", + children: [ + AppThemeSelector( + selectedTheme: theme.appTheme, + onChanged: (appTheme) => theme.setTheme(appTheme), + ), + const SizedBox(height: 16), + IgnorePointer( + ignoring: isSystemTheme, + child: Opacity( + opacity: isSystemTheme ? 0.5 : 1.0, + child: _ColorPickerTile( + title: "Акцентный цвет", + subtitle: isSystemTheme + ? "Используются цвета системы (Material You)" + : "Основной цвет интерфейса", + color: isSystemTheme ? colors.primary : theme.accentColor, + onColorChanged: (color) => theme.setAccentColor(color), + ), + ), + ), + ], + ), + const SizedBox(height: 24), + _ModernSection( + title: "Обои чата", + children: [ + _CustomSettingTile( + icon: Icons.wallpaper, + title: "Использовать свои обои", + child: Switch( + value: theme.useCustomChatWallpaper, + onChanged: (value) => theme.setUseCustomChatWallpaper(value), + ), + ), + if (theme.useCustomChatWallpaper) ...[ + const Divider(height: 24), + _CustomSettingTile( + icon: Icons.image, + title: "Тип обоев", + child: DropdownButton( + value: theme.chatWallpaperType, + underline: const SizedBox.shrink(), + onChanged: (value) { + if (value != null) theme.setChatWallpaperType(value); + }, + items: ChatWallpaperType.values.map((type) { + return DropdownMenuItem( + value: type, + child: Text(type.displayName), + ); + }).toList(), + ), + ), + if (theme.chatWallpaperType == ChatWallpaperType.solid || + theme.chatWallpaperType == ChatWallpaperType.gradient) ...[ + const SizedBox(height: 16), + _ColorPickerTile( + title: "Цвет 1", + subtitle: "Основной цвет фона", + color: theme.chatWallpaperColor1, + onColorChanged: (color) => + theme.setChatWallpaperColor1(color), + ), + ], + if (theme.chatWallpaperType == ChatWallpaperType.gradient) ...[ + const SizedBox(height: 16), + _ColorPickerTile( + title: "Цвет 2", + subtitle: "Дополнительный цвет для градиента", + color: theme.chatWallpaperColor2, + onColorChanged: (color) => + theme.setChatWallpaperColor2(color), + ), + ], + if (theme.chatWallpaperType == ChatWallpaperType.image) ...[ + const Divider(height: 24), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.photo_library_outlined), + title: const Text("Выбрать изображение"), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + final picker = ImagePicker(); + final image = await picker.pickImage( + source: ImageSource.gallery, + ); + if (image != null) { + theme.setChatWallpaperImagePath(image.path); + } + }, + ), + if (theme.chatWallpaperImagePath?.isNotEmpty == true) ...[ + _SliderTile( + icon: Icons.blur_on, + label: "Размытие", + value: theme.chatWallpaperImageBlur, + min: 0.0, + max: 10.0, + divisions: 20, + onChanged: (value) => + theme.setChatWallpaperImageBlur(value), + displayValue: theme.chatWallpaperImageBlur + .toStringAsFixed(1), + ), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon( + Icons.delete_outline, + color: Colors.redAccent, + ), + title: const Text( + "Удалить изображение", + style: TextStyle(color: Colors.redAccent), + ), + onTap: () => theme.setChatWallpaperImagePath(null), + ), + ], + ], + if (theme.chatWallpaperType == ChatWallpaperType.video) ...[ + const Divider(height: 24), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.video_library_outlined), + title: const Text("Выбрать видео"), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + + final result = await FilePicker.platform.pickFiles( + type: FileType.video, + ); + if (result != null && result.files.single.path != null) { + theme.setChatWallpaperVideoPath( + result.files.single.path!, + ); + } + }, + ), + if (theme.chatWallpaperVideoPath?.isNotEmpty == true) ...[ + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon( + Icons.delete_outline, + color: Colors.redAccent, + ), + title: const Text( + "Удалить видео", + style: TextStyle(color: Colors.redAccent), + ), + onTap: () => theme.setChatWallpaperVideoPath(null), + ), + ], + ], + ], + ], + ), + const SizedBox(height: 24), + _ModernSection( + title: "Сообщения", + children: [ + _SliderTile( + icon: Icons.text_fields, + label: "Непрозрачность текста", + value: theme.messageTextOpacity, + min: 0.1, + max: 1.0, + divisions: 18, + onChanged: (value) => theme.setMessageTextOpacity(value), + displayValue: "${(theme.messageTextOpacity * 100).round()}%", + ), + _SliderTile( + icon: Icons.blur_circular, + label: "Интенсивность тени", + value: theme.messageShadowIntensity, + min: 0.0, + max: 0.5, + divisions: 10, + onChanged: (value) => theme.setMessageShadowIntensity(value), + displayValue: + "${(theme.messageShadowIntensity * 100).round()}%", + ), + _SliderTile( + icon: Icons.rounded_corner, + label: "Скругление углов", + value: theme.messageBorderRadius, + min: 4.0, + max: 50.0, + divisions: 23, + onChanged: (value) => theme.setMessageBorderRadius(value), + displayValue: "${theme.messageBorderRadius.round()}px", + ), + const Divider(height: 24), + _SliderTile( + icon: Icons.menu, + label: "Непрозрачность меню", + value: theme.messageMenuOpacity, + min: 0.1, + max: 1.0, + divisions: 18, + onChanged: (value) => theme.setMessageMenuOpacity(value), + displayValue: "${(theme.messageMenuOpacity * 100).round()}%", + ), + _SliderTile( + icon: Icons.blur_on, + label: "Размытие меню", + value: theme.messageMenuBlur, + min: 0.0, + max: 20.0, + divisions: 20, + onChanged: (value) => theme.setMessageMenuBlur(value), + displayValue: theme.messageMenuBlur.toStringAsFixed(1), + ), + const Divider(height: 24), + if (MediaQuery.of(context).size.height < 600) + const SizedBox(height: 5), + _SliderTile( + icon: Icons.opacity, + label: "Непрозрачность сообщений", + value: 1.0 - theme.messageBubbleOpacity, + min: 0.0, + max: 1.0, + divisions: 20, + onChanged: (value) => + theme.setMessageBubbleOpacity(1.0 - value), + displayValue: + "${((1.0 - theme.messageBubbleOpacity) * 100).round()}%", + ), + const SizedBox(height: 16), + _CustomSettingTile( + icon: Icons.format_color_fill, + title: "Тип отображения", + child: IgnorePointer( + ignoring: isSystemTheme, + child: Opacity( + opacity: isSystemTheme ? 0.5 : 1.0, + child: DropdownButton( + value: theme.messageBubbleType, + underline: const SizedBox.shrink(), + onChanged: (value) { + if (value != null) theme.setMessageBubbleType(value); + }, + items: MessageBubbleType.values.map((type) { + return DropdownMenuItem( + value: type, + child: Text(type.displayName), + ); + }).toList(), + ), + ), + ), + ), + const SizedBox(height: 16), + _CustomSettingTile( + icon: Icons.palette, + title: "Цвет моих сообщений", + child: IgnorePointer( + ignoring: isSystemTheme, + child: Opacity( + opacity: isSystemTheme ? 0.5 : 1.0, + child: GestureDetector( + onTap: () async { + final initial = myBubbleColorToShow ?? myBubbleFallback; + _showColorPicker( + context, + initialColor: initial, + onColorChanged: (color) => myBubbleSetter(color), + ); + }, + child: Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: myBubbleColorToShow ?? myBubbleFallback, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey), + ), + ), + ), + ), + ), + ), + const SizedBox(height: 16), + _CustomSettingTile( + icon: Icons.palette_outlined, + title: "Цвет сообщений собеседника", + child: IgnorePointer( + ignoring: isSystemTheme, + child: Opacity( + opacity: isSystemTheme ? 0.5 : 1.0, + child: GestureDetector( + onTap: () async { + final initial = + theirBubbleColorToShow ?? theirBubbleFallback; + _showColorPicker( + context, + initialColor: initial, + onColorChanged: (color) => theirBubbleSetter(color), + ); + }, + child: Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: theirBubbleColorToShow ?? theirBubbleFallback, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey), + ), + ), + ), + ), + ), + ), + const Divider(height: 24), + _CustomSettingTile( + icon: Icons.reply, + title: "Автоцвет панели ответа", + subtitle: "", + child: Switch( + value: theme.useAutoReplyColor, + onChanged: (value) => theme.setUseAutoReplyColor(value), + ), + ), + if (!theme.useAutoReplyColor) ...[ + const SizedBox(height: 16), + _ColorPickerTile( + title: "Цвет панели ответа", + subtitle: "Фиксированный цвет", + color: theme.customReplyColor ?? Colors.blue, + onColorChanged: (color) => theme.setCustomReplyColor(color), + ), + ], + ], + ), + const SizedBox(height: 24), + _ModernSection( + title: "Всплывающие окна", + children: [ + _SliderTile( + icon: Icons.opacity, + label: "Прозрачность фона (профиль)", + value: theme.profileDialogOpacity, + min: 0.0, + max: 1.0, + divisions: 20, + onChanged: (value) => theme.setProfileDialogOpacity(value), + displayValue: "${(theme.profileDialogOpacity * 100).round()}%", + ), + _SliderTile( + icon: Icons.blur_on, + label: "Размытие фона (профиль)", + value: theme.profileDialogBlur, + min: 0.0, + max: 30.0, + divisions: 30, + onChanged: (value) => theme.setProfileDialogBlur(value), + displayValue: theme.profileDialogBlur.toStringAsFixed(1), + ), + ], + ), + const SizedBox(height: 24), + _ModernSection( + title: "Режим рабочего стола", + children: [ + _CustomSettingTile( + icon: Icons.desktop_windows, + title: "Режим с контактами слева", + subtitle: "Контакты слева, чат справа", + child: Switch( + value: theme.useDesktopLayout, + onChanged: (value) => theme.setUseDesktopLayout(value), + ), + ), + ], + ), + const SizedBox(height: 24), + _ModernSection( + title: "Панели чата", + children: [ + _CustomSettingTile( + icon: Icons.tune, + title: "Эффект стекла для панелей", + subtitle: "Размытие и прозрачность", + child: Switch( + value: theme.useGlassPanels, + onChanged: (value) => theme.setUseGlassPanels(value), + ), + ), + if (theme.useGlassPanels) ...[ + const Divider(height: 24, indent: 16, endIndent: 16), + _SliderTile( + label: "Непрозрачность верхней панели", + value: theme.topBarOpacity, + min: 0.1, + max: 1.0, + divisions: 18, + onChanged: (value) => theme.setTopBarOpacity(value), + displayValue: "${(theme.topBarOpacity * 100).round()}%", + ), + _SliderTile( + label: "Размытие верхней панели", + value: theme.topBarBlur, + min: 0.0, + max: 20.0, + divisions: 40, + onChanged: (value) => theme.setTopBarBlur(value), + displayValue: theme.topBarBlur.toStringAsFixed(1), + ), + const Divider(height: 24, indent: 16, endIndent: 16), + _SliderTile( + label: "Непрозрачность нижней панели", + value: theme.bottomBarOpacity, + min: 0.1, + max: 1.0, + divisions: 18, + onChanged: (value) => theme.setBottomBarOpacity(value), + displayValue: "${(theme.bottomBarOpacity * 100).round()}%", + ), + _SliderTile( + label: "Размытие нижней панели", + value: theme.bottomBarBlur, + min: 0.0, + max: 20.0, + divisions: 40, + onChanged: (value) => theme.setBottomBarBlur(value), + displayValue: theme.bottomBarBlur.toStringAsFixed(1), + ), + ], + ], + ), + ], + ), + ); + } +} + +class _ThemeManagementSection extends StatelessWidget { + const _ThemeManagementSection(); + + void _showSaveThemeDialog(BuildContext context, ThemeProvider theme) { + final controller = TextEditingController( + text: "Копия ${theme.activeTheme.name}", + ); + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text("Сохранить тему"), + content: TextField( + controller: controller, + autofocus: true, + decoration: const InputDecoration(labelText: "Название темы"), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text("Отмена"), + ), + TextButton( + onPressed: () { + theme.saveCurrentThemeAs(controller.text); + Navigator.of(context).pop(); + }, + child: const Text("Сохранить"), + ), + ], + ); + }, + ); + } + + void _showConfirmDeleteDialog( + BuildContext context, + ThemeProvider theme, + CustomThemePreset preset, + ) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text("Удалить тему?"), + content: Text("Вы уверены, что хотите удалить '${preset.name}'?"), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text("Отмена"), + ), + TextButton( + onPressed: () { + theme.deleteTheme(preset.id); + Navigator.of(context).pop(); + }, + child: const Text("Удалить", style: TextStyle(color: Colors.red)), + ), + ], + ); + }, + ); + } + + void _showRenameDialog( + BuildContext context, + ThemeProvider theme, + CustomThemePreset preset, + ) { + final controller = TextEditingController(text: preset.name); + controller.selection = TextSelection( + baseOffset: 0, + extentOffset: controller.text.length, + ); + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text("Переименовать тему"), + content: TextField( + controller: controller, + autofocus: true, + decoration: const InputDecoration(labelText: "Новое название"), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text("Отмена"), + ), + TextButton( + onPressed: () { + if (controller.text.trim().isNotEmpty) { + theme.renameTheme(preset.id, controller.text); + Navigator.of(context).pop(); + } + }, + child: const Text("Сохранить"), + ), + ], + ); + }, + ); + } + + Future _doExport( + BuildContext context, + ThemeProvider theme, + CustomThemePreset preset, + ) async { + try { + final String jsonString = jsonEncode(preset.toJson()); + final String fileName = + '${preset.name.replaceAll(RegExp(r'[\\/*?:"<>|]'), '_')}.ktheme'; + + String? outputFile = await FilePicker.platform.saveFile( + dialogTitle: 'Сохранить тему...', + fileName: fileName, + allowedExtensions: ['ktheme'], + type: FileType.custom, + ); + + if (outputFile != null) { + if (!outputFile.endsWith('.ktheme')) { + outputFile += '.ktheme'; + } + + final file = File(outputFile); + await file.writeAsString(jsonString); + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Тема "${preset.name}" экспортирована.')), + ); + } + } + } catch (e) { + if (context.mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Ошибка экспорта: $e'))); + } + } + } + + Future _doImport(BuildContext context, ThemeProvider theme) async { + try { + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['ktheme'], + ); + + if (result != null && result.files.single.path != null) { + final file = File(result.files.single.path!); + final jsonString = await file.readAsString(); + + final bool success = await theme.importThemeFromJson(jsonString); + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + success + ? 'Тема успешно импортирована!' + : 'Ошибка: Неверный формат файла темы.', + ), + ), + ); + } + } + } catch (e) { + if (context.mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Ошибка импорта: $e'))); + } + } + } + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final colors = Theme.of(context).colorScheme; + + return _ModernSection( + title: "Пресеты тем", + children: [ + ...theme.savedThemes.map((preset) { + final bool isActive = theme.activeTheme.id == preset.id; + return ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 4), + leading: Icon( + isActive ? Icons.check_circle : Icons.radio_button_unchecked, + color: isActive ? colors.primary : colors.onSurfaceVariant, + ), + title: Text( + preset.name, + style: TextStyle( + fontWeight: isActive ? FontWeight.bold : FontWeight.normal, + ), + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (preset.id != 'default') + IconButton( + icon: const Icon(Icons.edit_outlined), + tooltip: "Переименовать", + onPressed: () => _showRenameDialog(context, theme, preset), + ), + + IconButton( + icon: const Icon(Icons.file_upload_outlined), + tooltip: "Экспорт", + onPressed: () => _doExport(context, theme, preset), + ), + if (preset.id != 'default') + IconButton( + icon: const Icon( + Icons.delete_outline, + color: Colors.redAccent, + ), + tooltip: "Удалить", + onPressed: () => + _showConfirmDeleteDialog(context, theme, preset), + ), + ], + ), + onTap: () { + if (!isActive) { + theme.applyTheme(preset.id); + } + }, + ); + }), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + TextButton.icon( + icon: const Icon(Icons.add), + label: const Text("Сохранить"), + onPressed: () => _showSaveThemeDialog(context, theme), + ), + TextButton.icon( + icon: const Icon(Icons.file_download_outlined), + label: const Text("Импорт"), + onPressed: () => _doImport(context, theme), + ), + ], + ), + ], + ); + } +} + +class _ModernSection extends StatelessWidget { + final String title; + final List children; + + const _ModernSection({required this.title, required this.children}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16.0, bottom: 12.0), + child: Text( + title.toUpperCase(), + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 14, + letterSpacing: 0.8, + ), + ), + ), + Card( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide(color: colors.outlineVariant.withOpacity(0.3)), + ), + clipBehavior: Clip.antiAlias, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Column(children: children), + ), + ), + ], + ); + } +} + +class _CustomSettingTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final Widget child; + + const _CustomSettingTile({ + required this.icon, + required this.title, + this.subtitle, + required this.child, + }); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Icon(icon, color: Theme.of(context).colorScheme.primary), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + ), + ), + if (subtitle != null) + Text( + subtitle!, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), + ), + child, + ], + ); + } +} + +class _ColorPickerTile extends StatelessWidget { + final String title; + final String subtitle; + final Color color; + final ValueChanged onColorChanged; + + const _ColorPickerTile({ + required this.title, + required this.subtitle, + required this.color, + required this.onColorChanged, + }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () => _showColorPicker( + context, + initialColor: color, + onColorChanged: onColorChanged, + ), + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + children: [ + const Icon(Icons.color_lens_outlined), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + ), + ), + Text( + subtitle, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), + ), + Container( + width: 32, + height: 32, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + border: Border.all( + color: Theme.of(context).colorScheme.outline.withOpacity(0.5), + ), + ), + ), + ], + ), + ), + ); + } +} + +class _SliderTile extends StatelessWidget { + final IconData? icon; + final String label; + final double value; + final double min; + final double max; + final int divisions; + final ValueChanged onChanged; + final String displayValue; + + const _SliderTile({ + this.icon, + required this.label, + required this.value, + required this.min, + required this.max, + required this.divisions, + required this.onChanged, + required this.displayValue, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + if (icon != null) ...[ + Icon( + icon, + size: 20, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + const SizedBox(width: 12), + ], + Expanded( + child: Text(label, style: const TextStyle(fontSize: 14)), + ), + Text( + displayValue, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + SizedBox( + height: 30, + child: Slider( + value: value, + min: min, + max: max, + divisions: divisions, + onChanged: onChanged, + ), + ), + ], + ), + ); + } +} + +class AppThemeSelector extends StatelessWidget { + final AppTheme selectedTheme; + final ValueChanged onChanged; + + const AppThemeSelector({ + super.key, + required this.selectedTheme, + required this.onChanged, + }); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _ThemeButton( + theme: AppTheme.system, + selectedTheme: selectedTheme, + onChanged: onChanged, + icon: Icons.brightness_auto_outlined, + label: "Система", + ), + _ThemeButton( + theme: AppTheme.light, + selectedTheme: selectedTheme, + onChanged: onChanged, + icon: Icons.light_mode_outlined, + label: "Светлая", + ), + _ThemeButton( + theme: AppTheme.dark, + selectedTheme: selectedTheme, + onChanged: onChanged, + icon: Icons.dark_mode_outlined, + label: "Тёмная", + ), + _ThemeButton( + theme: AppTheme.black, + selectedTheme: selectedTheme, + onChanged: onChanged, + icon: Icons.dark_mode, + label: "OLED", + ), + ], + ); + } +} + +class _ThemeButton extends StatelessWidget { + final AppTheme theme; + final AppTheme selectedTheme; + final ValueChanged onChanged; + final IconData icon; + final String label; + + const _ThemeButton({ + required this.theme, + required this.selectedTheme, + required this.onChanged, + required this.icon, + required this.label, + }); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final isSelected = selectedTheme == theme; + + return GestureDetector( + onTap: () => onChanged(theme), + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 70, + height: 70, + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: isSelected + ? colors.primaryContainer + : colors.surfaceVariant.withOpacity(0.3), + border: Border.all( + color: isSelected ? colors.primary : Colors.transparent, + width: 2, + ), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + icon, + size: 24, + color: isSelected + ? colors.onPrimaryContainer + : colors.onSurfaceVariant, + ), + const SizedBox(height: 4), + Text( + label, + style: TextStyle( + fontSize: 12, + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + color: isSelected + ? colors.onPrimaryContainer + : colors.onSurfaceVariant, + ), + textAlign: TextAlign.center, + maxLines: 1, + ), + ], + ), + ), + ); + } +} + +class _MessagePreviewSection extends StatelessWidget { + const _MessagePreviewSection(); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final colors = Theme.of(context).colorScheme; + final mockMyMessage = Message( + id: '1', + senderId: 100, + text: "Выглядит отлично! 🔥", + time: DateTime.now().millisecondsSinceEpoch, + attaches: const [], + ); + final mockTheirMessage = Message( + id: '2', + senderId: 200, + text: "Привет! Как тебе новый вид?", + time: DateTime.now().millisecondsSinceEpoch, + attaches: const [], + ); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16.0, bottom: 12.0), + child: Text( + "ПРЕДПРОСМОТР", + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.bold, + fontSize: 14, + letterSpacing: 0.8, + ), + ), + ), + Container( + height: 250, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outlineVariant.withOpacity(0.3)), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(15), + child: Stack( + children: [ + const _ChatWallpaperPreview(), + Column( + children: [ + ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.useGlassPanels ? theme.topBarBlur : 0, + sigmaY: theme.useGlassPanels ? theme.topBarBlur : 0, + ), + child: Container( + height: 40, + color: colors.surface.withOpacity( + theme.useGlassPanels ? theme.topBarOpacity : 0.0, + ), + child: Row( + children: [ + const SizedBox(width: 16), + CircleAvatar( + backgroundColor: colors.primaryContainer, + radius: 12, + ), + const SizedBox(width: 8), + Expanded( + child: Container( + height: 10, + decoration: BoxDecoration( + color: colors.primaryContainer, + borderRadius: BorderRadius.circular(4), + ), + ), + ), + const SizedBox(width: 40), + ], + ), + ), + ), + ), + const Spacer(), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: ChatMessageBubble( + message: mockTheirMessage, + isMe: false, + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: ChatMessageBubble( + message: mockMyMessage, + isMe: true, + ), + ), + const SizedBox(height: 8), + ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.useGlassPanels + ? theme.bottomBarBlur + : 0, + sigmaY: theme.useGlassPanels + ? theme.bottomBarBlur + : 0, + ), + child: Container( + height: 40, + color: colors.surface.withOpacity( + theme.useGlassPanels ? theme.bottomBarOpacity : 0.0, + ), + child: Row( + children: [ + const SizedBox(width: 16), + Expanded( + child: Container( + height: 24, + decoration: BoxDecoration( + color: colors.surfaceVariant, + borderRadius: BorderRadius.circular(12), + ), + ), + ), + const SizedBox(width: 8), + Icon(Icons.send, color: colors.primary), + const SizedBox(width: 16), + ], + ), + ), + ), + ), + ], + ), + ], + ), + ), + ), + ], + ); + } +} + +class _ChatWallpaperPreview extends StatelessWidget { + const _ChatWallpaperPreview(); + + @override + Widget build(BuildContext context) { + final theme = context.watch(); + final isDarkTheme = Theme.of(context).brightness == Brightness.dark; + + if (!theme.useCustomChatWallpaper) { + return Container(color: Theme.of(context).scaffoldBackgroundColor); + } + + switch (theme.chatWallpaperType) { + case ChatWallpaperType.solid: + return Container(color: theme.chatWallpaperColor1); + case ChatWallpaperType.gradient: + return Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [theme.chatWallpaperColor1, theme.chatWallpaperColor2], + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ), + ), + ); + case ChatWallpaperType.image: + if (theme.chatWallpaperImagePath?.isNotEmpty == true) { + return Stack( + fit: StackFit.expand, + children: [ + Image.file( + File(theme.chatWallpaperImagePath!), + fit: BoxFit.cover, + errorBuilder: (context, error, stackTrace) => + const Center(child: Icon(Icons.error)), + ), + if (theme.chatWallpaperImageBlur > 0) + BackdropFilter( + filter: ImageFilter.blur( + sigmaX: theme.chatWallpaperImageBlur, + sigmaY: theme.chatWallpaperImageBlur, + ), + child: Container(color: Colors.black.withOpacity(0.05)), + ), + ], + ); + } else { + return Container( + color: isDarkTheme ? Colors.grey[850] : Colors.grey[200], + child: Center( + child: Icon( + Icons.image_not_supported_outlined, + color: isDarkTheme ? Colors.grey[600] : Colors.grey[400], + size: 40, + ), + ), + ); + } + case ChatWallpaperType.video: + + if (Platform.isWindows) { + return Container( + color: isDarkTheme ? Colors.grey[850] : Colors.grey[200], + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.video_library_outlined, + color: isDarkTheme ? Colors.grey[600] : Colors.grey[400], + size: 40, + ), + const SizedBox(height: 8), + Text( + 'Видео-обои\nне поддерживаются на Windows', + style: TextStyle( + color: isDarkTheme ? Colors.grey[600] : Colors.grey[400], + fontSize: 12, + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } + if (theme.chatWallpaperVideoPath?.isNotEmpty == true) { + return _VideoWallpaper(path: theme.chatWallpaperVideoPath!); + } else { + return Container( + color: isDarkTheme ? Colors.grey[850] : Colors.grey[200], + child: Center( + child: Icon( + Icons.video_library_outlined, + color: isDarkTheme ? Colors.grey[600] : Colors.grey[400], + size: 40, + ), + ), + ); + } + } + } +} + +class _VideoWallpaper extends StatefulWidget { + final String path; + + const _VideoWallpaper({required this.path}); + + @override + State<_VideoWallpaper> createState() => _VideoWallpaperState(); +} + +class _VideoWallpaperState extends State<_VideoWallpaper> { + VideoPlayerController? _controller; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _initializeVideo(); + } + + Future _initializeVideo() async { + try { + final file = File(widget.path); + if (!await file.exists()) { + setState(() { + _errorMessage = 'Video file not found'; + }); + print('ERROR: Video file does not exist: ${widget.path}'); + return; + } + + _controller = VideoPlayerController.file(file); + await _controller!.initialize(); + + if (mounted) { + _controller!.setVolume(0); + _controller!.setLooping(true); + _controller!.play(); + setState(() {}); + print('SUCCESS: Video initialized and playing'); + } + } catch (e) { + print('ERROR initializing video: $e'); + setState(() { + _errorMessage = e.toString(); + }); + } + } + + @override + void dispose() { + _controller?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_errorMessage != null) { + print('ERROR building video widget: $_errorMessage'); + return Container( + color: Colors.black, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.error_outline, color: Colors.white70, size: 40), + const SizedBox(height: 8), + Text( + _errorMessage!, + style: const TextStyle(color: Colors.white70, fontSize: 10), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } + + if (_controller == null) { + return const Center(child: CircularProgressIndicator()); + } + + if (!_controller!.value.isInitialized) { + return const Center(child: CircularProgressIndicator()); + } + + return Stack( + fit: StackFit.expand, + children: [ + Positioned.fill( + child: FittedBox( + fit: BoxFit.cover, + child: SizedBox( + width: _controller!.value.size.width, + height: _controller!.value.size.height, + child: VideoPlayer(_controller!), + ), + ), + ), + + Container( + decoration: BoxDecoration(color: Colors.black.withOpacity(0.3)), + ), + ], + ); + } +} diff --git a/lib/screens/settings/export_session_screen.dart b/lib/screens/settings/export_session_screen.dart new file mode 100644 index 0000000..ea242ed --- /dev/null +++ b/lib/screens/settings/export_session_screen.dart @@ -0,0 +1,278 @@ + + +import 'dart:convert'; +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:file_saver/file_saver.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/proxy_service.dart'; +import 'package:gwid/spoofing_service.dart'; +import 'package:encrypt/encrypt.dart' as encrypt; +import 'package:crypto/crypto.dart' as crypto; + +class ExportSessionScreen extends StatefulWidget { + const ExportSessionScreen({super.key}); + + @override + State createState() => _ExportSessionScreenState(); +} + +class _ExportSessionScreenState extends State { + final _passwordController = TextEditingController(); + bool _isPasswordVisible = false; + bool _isExporting = false; + bool _saveProxySettings = false; + + + Future _exportAndSaveSession() async { + if (!mounted) return; + setState(() => _isExporting = true); + final messenger = ScaffoldMessenger.of(context); + + try { + final spoofData = await SpoofingService.getSpoofedSessionData(); + final token = ApiService.instance.token; + + if (token == null || token.isEmpty) { + throw Exception('Токен пользователя не найден.'); + } + + final sessionData = { + 'token': token, + 'spoof_data': spoofData ?? 'Подмена устройства неактивна', + }; + + if (_saveProxySettings) { + final proxySettings = await ProxyService.instance.loadProxySettings(); + sessionData['proxy_settings'] = proxySettings.toJson(); + } + + const jsonEncoder = JsonEncoder.withIndent(' '); + final plainJsonContent = jsonEncoder.convert(sessionData); + String finalFileContent; + final password = _passwordController.text; + + if (password.isNotEmpty) { + final keyBytes = utf8.encode(password); + final keyHash = crypto.sha256.convert(keyBytes); + final key = encrypt.Key(Uint8List.fromList(keyHash.bytes)); + final iv = encrypt.IV.fromLength(16); + final encrypter = encrypt.Encrypter( + encrypt.AES(key, mode: encrypt.AESMode.cbc), + ); + final encrypted = encrypter.encrypt(plainJsonContent, iv: iv); + final encryptedOutput = { + 'encrypted': true, + 'iv_base64': iv.base64, + 'data_base64': encrypted.base64, + }; + finalFileContent = jsonEncoder.convert(encryptedOutput); + } else { + finalFileContent = plainJsonContent; + } + + Uint8List bytes = Uint8List.fromList(utf8.encode(finalFileContent)); + + String? filePath = await FileSaver.instance.saveAs( + name: 'komet_session_${DateTime.now().millisecondsSinceEpoch}', + bytes: bytes, + fileExtension: 'json', + mimeType: MimeType.json, + ); + + if (filePath != null && mounted) { + messenger.showSnackBar( + const SnackBar( + content: Text('Файл сессии успешно сохранен'), + backgroundColor: Colors.green, + ), + ); + } else if (mounted) { + messenger.showSnackBar( + const SnackBar(content: Text('Сохранение файла было отменено.')), + ); + } + } catch (e) { + messenger.showSnackBar( + SnackBar( + backgroundColor: Colors.red, + content: Text('Не удалось экспортировать сессию: $e'), + ), + ); + } finally { + if (mounted) { + setState(() => _isExporting = false); + } + } + } + + @override + void dispose() { + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final textTheme = Theme.of(context).textTheme; + + return Scaffold( + appBar: AppBar(title: const Text('Экспорт сессии')), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + + Center( + child: CircleAvatar( + radius: 40, + backgroundColor: colors.primaryContainer, + child: Icon( + Icons.upload_file_outlined, + size: 40, + color: colors.onPrimaryContainer, + ), + ), + ), + const SizedBox(height: 16), + Text( + 'Резервная копия сессии', + textAlign: TextAlign.center, + style: textTheme.headlineSmall?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + Text( + 'Создайте зашифрованный файл для переноса вашего аккаунта на другое устройство без повторной авторизации.', + textAlign: TextAlign.center, + style: textTheme.bodyLarge?.copyWith( + color: colors.onSurfaceVariant, + ), + ), + const SizedBox(height: 24), + const Divider(), + const SizedBox(height: 24), + + + Text( + '1. Защитите файл паролем', + style: textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 8), + Text( + 'Настоятельно рекомендуется установить пароль для шифрования (AES-256). Без него файл будет сохранен в открытом виде.', + style: textTheme.bodyMedium?.copyWith( + color: colors.onSurfaceVariant, + ), + ), + const SizedBox(height: 16), + TextField( + controller: _passwordController, + obscureText: !_isPasswordVisible, + decoration: InputDecoration( + labelText: 'Пароль (необязательно)', + border: const OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + prefixIcon: const Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + _isPasswordVisible + ? Icons.visibility_off + : Icons.visibility, + ), + onPressed: () => + setState(() => _isPasswordVisible = !_isPasswordVisible), + ), + ), + ), + const SizedBox(height: 24), + Text( + '2. Дополнительные данные', + style: textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + ), + ), + const SizedBox(height: 8), + + Card( + margin: EdgeInsets.zero, + child: CheckboxListTile( + title: const Text('Сохранить настройки прокси'), + subtitle: const Text( + 'Включить текущие параметры прокси в файл экспорта.', + ), + value: _saveProxySettings, + onChanged: (bool? value) => + setState(() => _saveProxySettings = value ?? false), + controlAffinity: + ListTileControlAffinity.leading, // Чекбокс слева + ), + ), + const SizedBox(height: 32), + + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.errorContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.warning_amber_rounded, + color: colors.error, + size: 28, + ), + const SizedBox(width: 12), + Expanded( + child: Text( + 'Никогда и никому не передавайте этот файл. Он дает полный доступ к вашему аккаунту.', + style: textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 32), + + + FilledButton.icon( + onPressed: _isExporting ? null : _exportAndSaveSession, + icon: _isExporting + ? Container( + width: 24, + height: 24, + padding: const EdgeInsets.all(2.0), + child: const CircularProgressIndicator( + color: Colors.white, + strokeWidth: 3, + ), + ) + : const Icon(Icons.download_for_offline_outlined), + label: Text( + _isExporting ? 'Сохранение...' : 'Экспортировать и сохранить', + ), + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + textStyle: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/settings/komet_misc_screen.dart b/lib/screens/settings/komet_misc_screen.dart new file mode 100644 index 0000000..dd3ea54 --- /dev/null +++ b/lib/screens/settings/komet_misc_screen.dart @@ -0,0 +1,521 @@ +import 'package:flutter/material.dart'; +import 'package:disable_battery_optimization/disable_battery_optimization.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'dart:io' show Platform; + +class KometMiscScreen extends StatefulWidget { + final bool isModal; + + const KometMiscScreen({super.key, this.isModal = false}); + + @override + State createState() => _KometMiscScreenState(); +} + +class _KometMiscScreenState extends State { + bool? _isBatteryOptimizationDisabled; + bool _isAutoUpdateEnabled = true; + bool _showUpdateNotification = true; + bool _enableWebVersionCheck = false; + + @override + void initState() { + super.initState(); + _checkBatteryOptimizationStatus(); + _loadUpdateSettings(); + } + + Future _loadUpdateSettings() async { + final prefs = await SharedPreferences.getInstance(); + setState(() { + + _isAutoUpdateEnabled = prefs.getBool('auto_update_enabled') ?? true; + _showUpdateNotification = + prefs.getBool('show_update_notification') ?? true; + _enableWebVersionCheck = + prefs.getBool('enable_web_version_check') ?? false; + }); + } + + Future _checkBatteryOptimizationStatus() async { + bool? isDisabled = + await DisableBatteryOptimization.isBatteryOptimizationDisabled; + if (mounted) { + setState(() { + _isBatteryOptimizationDisabled = isDisabled; + }); + } + } + + Future _requestDisableBatteryOptimization() async { + await DisableBatteryOptimization.showDisableBatteryOptimizationSettings(); + Future.delayed(const Duration(milliseconds: 500), () { + _checkBatteryOptimizationStatus(); + }); + } + + Future _updateSettings(String key, bool value) async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(key, value); + } + + @override + Widget build(BuildContext context) { + String subtitleText; + Color statusColor; + final defaultTextColor = Theme.of(context).textTheme.bodyMedium?.color; + + + final isDesktopOrIOS = + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux || + Platform.isIOS; + + if (isDesktopOrIOS) { + subtitleText = "Недоступно"; + statusColor = Colors.grey; + } else if (_isBatteryOptimizationDisabled == null) { + subtitleText = "Проверка статуса..."; + statusColor = Colors.grey; + } else if (_isBatteryOptimizationDisabled == true) { + subtitleText = "Разрешено"; + statusColor = Colors.green; + } else { + subtitleText = "Не разрешено"; + statusColor = Colors.orange; + } + + if (widget.isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar(title: const Text("Komet Misc")), + body: ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: Icon( + Icons.battery_charging_full_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Фоновая работа"), + subtitle: RichText( + text: TextSpan( + style: TextStyle(fontSize: 14, color: defaultTextColor), + children: [ + const TextSpan(text: 'Статус: '), + TextSpan( + text: subtitleText, + style: TextStyle( + fontWeight: FontWeight.bold, + color: statusColor, + ), + ), + ], + ), + ), + onTap: isDesktopOrIOS ? null : _requestDisableBatteryOptimization, + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + isDesktopOrIOS + ? 'Фоновая работа недоступна на данной платформе.' + : 'Для стабильной работы приложения в фоновом режиме рекомендуется отключить оптимизацию расхода заряда батареи.', + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), + fontSize: 12, + ), + ), + ), + + const Divider(height: 20), + + Card( + margin: const EdgeInsets.only(bottom: 10), + child: Column( + children: [ + SwitchListTile( + secondary: Icon( + Icons.wifi_find_outlined, + color: _enableWebVersionCheck + ? Theme.of(context).colorScheme.primary + : Colors.grey, + ), + title: const Text("Проверка версии через web"), + subtitle: Text( + _enableWebVersionCheck + ? "Проверяет актуальную версию на web.max.ru" + : "Проверка версии отключена", + ), + value: _enableWebVersionCheck, + onChanged: (bool value) { + setState(() { + _enableWebVersionCheck = value; + }); + _updateSettings('enable_web_version_check', value); + }, + ), + const Divider(height: 1), + SwitchListTile( + secondary: Icon( + Icons.system_update_alt_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Автообновление сессии"), + subtitle: const Text("Версия будет обновляться в фоне"), + value: _isAutoUpdateEnabled, + onChanged: (bool value) { + setState(() { + _isAutoUpdateEnabled = value; + }); + _updateSettings('auto_update_enabled', value); + }, + ), + + SwitchListTile( + secondary: Icon( + Icons.notifications_active_outlined, + + color: _isAutoUpdateEnabled + ? Colors.grey + : Theme.of(context).colorScheme.primary, + ), + title: const Text("Уведомлять о новой версии"), + subtitle: Text( + _isAutoUpdateEnabled + ? "Недоступно при автообновлении" + : "Показывать диалог при запуске", + ), + value: _showUpdateNotification, + + onChanged: _isAutoUpdateEnabled + ? null + : (bool value) { + setState(() { + _showUpdateNotification = value; + }); + _updateSettings('show_update_notification', value); + }, + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Text( + 'Автообновление автоматически изменит версию вашей сессии на последнюю доступную без дополнительных уведомлений.', + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6), + fontSize: 12, + ), + ), + ), + ], + ), + ); + } + + Widget _buildModalSettings( + BuildContext context, + String subtitleText, + Color statusColor, + Color? defaultTextColor, + ) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Komet Misc", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Card( + child: ListTile( + leading: const Icon(Icons.battery_charging_full), + title: const Text("Оптимизация батареи"), + subtitle: Text(subtitleText), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.circle, + color: statusColor, + size: 12, + ), + const SizedBox(width: 8), + const Icon(Icons.chevron_right), + ], + ), + onTap: + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux || + Platform.isIOS + ? null + : _requestDisableBatteryOptimization, + ), + ), + const SizedBox(height: 16), + Card( + child: Column( + children: [ + SwitchListTile( + title: const Text("Автообновления"), + subtitle: const Text( + "Автоматически проверять обновления", + ), + value: _isAutoUpdateEnabled, + onChanged: (value) { + setState(() { + _isAutoUpdateEnabled = value; + }); + _updateSettings('auto_update_enabled', value); + }, + ), + SwitchListTile( + title: const Text("Уведомления об обновлениях"), + subtitle: const Text( + "Показывать уведомления о доступных обновлениях", + ), + value: _showUpdateNotification, + onChanged: (value) { + setState(() { + _showUpdateNotification = value; + }); + _updateSettings( + 'show_update_notification', + value, + ); + }, + ), + SwitchListTile( + title: const Text("Проверка веб-версии"), + subtitle: const Text( + "Проверять обновления через веб-интерфейс", + ), + value: _enableWebVersionCheck, + onChanged: (value) { + setState(() { + _enableWebVersionCheck = value; + }); + _updateSettings( + 'enable_web_version_check', + value, + ); + }, + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + String subtitleText; + Color statusColor; + final defaultTextColor = Theme.of(context).textTheme.bodyMedium?.color; + + + final isDesktopOrIOS = + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux || + Platform.isIOS; + + if (isDesktopOrIOS) { + subtitleText = "Недоступно"; + statusColor = Colors.grey; + } else if (_isBatteryOptimizationDisabled == null) { + subtitleText = "Проверка статуса..."; + statusColor = Colors.grey; + } else if (_isBatteryOptimizationDisabled == true) { + subtitleText = "Разрешено"; + statusColor = Colors.green; + } else { + subtitleText = "Не разрешено"; + statusColor = Colors.orange; + } + + return ListView( + padding: const EdgeInsets.all(16.0), + children: [ + Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: Icon( + Icons.battery_charging_full_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Фоновая работа"), + subtitle: RichText( + text: TextSpan( + style: TextStyle(fontSize: 14, color: defaultTextColor), + children: [ + const TextSpan(text: 'Статус: '), + TextSpan( + text: subtitleText, + style: TextStyle( + color: statusColor, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: isDesktopOrIOS ? null : _requestDisableBatteryOptimization, + ), + ), + Card( + margin: const EdgeInsets.only(bottom: 10), + child: Column( + children: [ + SwitchListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + secondary: Icon( + Icons.system_update_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Автообновления"), + subtitle: const Text( + "Автоматически проверять и устанавливать обновления", + ), + value: _isAutoUpdateEnabled, + onChanged: (value) { + setState(() { + _isAutoUpdateEnabled = value; + }); + _updateSettings('auto_update_enabled', value); + }, + ), + SwitchListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + secondary: Icon( + Icons.notifications_active_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Уведомления об обновлениях"), + subtitle: const Text( + "Показывать уведомления о доступных обновлениях", + ), + value: _showUpdateNotification, + onChanged: (value) { + setState(() { + _showUpdateNotification = value; + }); + _updateSettings('show_update_notification', value); + }, + ), + SwitchListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + secondary: Icon( + Icons.web_rounded, + color: Theme.of(context).colorScheme.primary, + ), + title: const Text("Проверка веб-версии"), + subtitle: const Text( + "Проверять обновления веб-версии приложения", + ), + value: _enableWebVersionCheck, + onChanged: (value) { + setState(() { + _enableWebVersionCheck = value; + }); + _updateSettings('enable_web_version_check', value); + }, + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/screens/settings/network_screen.dart b/lib/screens/settings/network_screen.dart new file mode 100644 index 0000000..70c52ef --- /dev/null +++ b/lib/screens/settings/network_screen.dart @@ -0,0 +1,868 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; +import 'dart:math'; +import 'package:gwid/api_service.dart'; + +class NetworkScreen extends StatefulWidget { + const NetworkScreen({super.key}); + + @override + State createState() => _NetworkScreenState(); +} + +class _NetworkScreenState extends State + with TickerProviderStateMixin { + late AnimationController _animationController; + late Animation _animation; + + NetworkStats? _networkStats; + bool _isLoading = true; + Timer? _updateTimer; + bool _isMonitoring = false; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + duration: const Duration(milliseconds: 1500), + vsync: this, + ); + _animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), + ); + _loadNetworkStats(); + } + + @override + void dispose() { + _animationController.dispose(); + _updateTimer?.cancel(); + super.dispose(); + } + + Future _loadNetworkStats() async { + try { + final stats = await _getNetworkStats(); + setState(() { + _networkStats = stats; + _isLoading = false; + }); + _animationController.forward(); + } catch (e) { + setState(() { + _isLoading = false; + }); + } + } + + Future _getNetworkStats() async { + + final stats = await ApiService.instance.getNetworkStatistics(); + + + final totalDailyTraffic = stats['totalTraffic'] as double; + + + final messagesTraffic = stats['messagesTraffic'] as double; + final mediaTraffic = stats['mediaTraffic'] as double; + final syncTraffic = stats['syncTraffic'] as double; + final otherTraffic = stats['otherTraffic'] as double; + + + final currentSpeed = stats['currentSpeed'] as double; + + + final hourlyData = stats['hourlyStats'] as List; + final hourlyStats = List.generate(24, (index) { + if (index < hourlyData.length) { + return HourlyStats(hour: index, traffic: hourlyData[index] as double); + } + + final hour = index; + final isActive = hour >= 8 && hour <= 23; + final baseTraffic = isActive ? 20.0 * 1024 * 1024 : 2.0 * 1024 * 1024; + return HourlyStats(hour: hour, traffic: baseTraffic); + }); + + return NetworkStats( + totalDailyTraffic: totalDailyTraffic, + messagesTraffic: messagesTraffic, + mediaTraffic: mediaTraffic, + syncTraffic: syncTraffic, + otherTraffic: otherTraffic, + currentSpeed: currentSpeed, + hourlyStats: hourlyStats, + isConnected: stats['isConnected'] as bool, + connectionType: stats['connectionType'] as String, + signalStrength: stats['signalStrength'] as int, + ping: stats['ping'] as int, + jitter: stats['jitter'] as double, + packetLoss: stats['packetLoss'] as double, + ); + } + + void _startMonitoring() { + if (_isMonitoring) return; + + setState(() { + _isMonitoring = true; + }); + + _updateTimer = Timer.periodic(const Duration(seconds: 2), (timer) { + _loadNetworkStats(); + }); + } + + void _stopMonitoring() { + _updateTimer?.cancel(); + setState(() { + _isMonitoring = false; + }); + } + + void _resetStats() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Сбросить статистику'), + content: const Text( + 'Это действие сбросит всю статистику использования сети. ' + 'Это действие нельзя отменить.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: const Text('Сбросить'), + ), + ], + ), + ); + + if (confirmed == true) { + await _loadNetworkStats(); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Статистика сброшена'), + backgroundColor: Colors.green, + ), + ); + } + } + } + + String _formatBytes(double bytes) { + if (bytes < 1024) return '${bytes.toStringAsFixed(0)} B'; + if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB'; + if (bytes < 1024 * 1024 * 1024) + return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; + return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; + } + + String _formatSpeed(double bytesPerSecond) { + if (bytesPerSecond < 1024) + return '${bytesPerSecond.toStringAsFixed(0)} B/s'; + if (bytesPerSecond < 1024 * 1024) + return '${(bytesPerSecond / 1024).toStringAsFixed(1)} KB/s'; + return '${(bytesPerSecond / (1024 * 1024)).toStringAsFixed(1)} MB/s'; + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Сеть'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + elevation: 0, + actions: [ + IconButton( + icon: Icon(_isMonitoring ? Icons.pause : Icons.play_arrow), + onPressed: _isMonitoring ? _stopMonitoring : _startMonitoring, + tooltip: _isMonitoring + ? 'Остановить мониторинг' + : 'Начать мониторинг', + ), + ], + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _networkStats == null + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.wifi_off, + size: 64, + color: colors.onSurface.withOpacity(0.3), + ), + const SizedBox(height: 16), + Text( + 'Не удалось загрузить статистику сети', + style: TextStyle( + color: colors.onSurface.withOpacity(0.6), + fontSize: 16, + ), + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: _loadNetworkStats, + child: const Text('Повторить'), + ), + ], + ), + ) + : SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + _buildConnectionStatus(colors), + + const SizedBox(height: 24), + + + _buildNetworkChart(colors), + + const SizedBox(height: 24), + + + _buildCurrentSpeed(colors), + + const SizedBox(height: 24), + + + _buildTrafficDetails(colors), + + const SizedBox(height: 24), + + + _buildHourlyChart(colors), + + const SizedBox(height: 24), + + + _buildActionButtons(colors), + ], + ), + ), + ); + } + + Widget _buildConnectionStatus(ColorScheme colors) { + final stats = _networkStats!; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Row( + children: [ + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: stats.isConnected + ? colors.primary.withOpacity(0.1) + : colors.error.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Icon( + stats.isConnected ? Icons.wifi : Icons.wifi_off, + color: stats.isConnected ? colors.primary : colors.error, + size: 30, + ), + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + stats.isConnected ? 'Подключено' : 'Отключено', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 4), + Text( + stats.connectionType, + style: TextStyle( + fontSize: 14, + color: colors.onSurface.withOpacity(0.7), + ), + ), + if (stats.isConnected) ...[ + const SizedBox(height: 8), + Row( + children: [ + Icon( + Icons.signal_cellular_alt, + size: 16, + color: colors.primary, + ), + const SizedBox(width: 4), + Text( + '${stats.signalStrength}%', + style: TextStyle( + fontSize: 12, + color: colors.onSurface.withOpacity(0.6), + ), + ), + ], + ), + ], + ], + ), + ), + ], + ), + ); + } + + Widget _buildNetworkChart(ColorScheme colors) { + final stats = _networkStats!; + final totalTraffic = stats.totalDailyTraffic; + final usagePercentage = totalTraffic > 0 + ? (stats.messagesTraffic + + stats.mediaTraffic + + stats.syncTraffic + + stats.otherTraffic) / + totalTraffic + : 0.0; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + children: [ + Text( + 'Использование сети за день', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 24), + + + AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return SizedBox( + width: 200, + height: 200, + child: Stack( + children: [ + + Container( + width: 200, + height: 200, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: colors.surfaceContainerHighest, + ), + ), + + + CustomPaint( + size: const Size(200, 200), + painter: NetworkChartPainter( + progress: usagePercentage * _animation.value, + colors: colors, + ), + ), + + + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + _formatBytes(totalTraffic), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + Text( + 'использовано', + style: TextStyle( + fontSize: 12, + color: colors.onSurface.withOpacity(0.7), + ), + ), + ], + ), + ), + ], + ), + ); + }, + ), + + const SizedBox(height: 24), + + + Wrap( + spacing: 16, + runSpacing: 8, + children: [ + _buildLegendItem( + 'Медиа', + _formatBytes(stats.mediaTraffic), + colors.primary, + ), + _buildLegendItem( + 'Сообщения', + _formatBytes(stats.messagesTraffic), + colors.secondary, + ), + _buildLegendItem( + 'Синхронизация', + _formatBytes(stats.syncTraffic), + colors.tertiary, + ), + _buildLegendItem( + 'Другое', + _formatBytes(stats.otherTraffic), + colors.outline, + ), + ], + ), + ], + ), + ); + } + + Widget _buildLegendItem(String label, String value, Color color) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 12, + height: 12, + decoration: BoxDecoration(color: color, shape: BoxShape.circle), + ), + const SizedBox(width: 6), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, style: const TextStyle(fontSize: 12)), + Text( + value, + style: const TextStyle(fontSize: 10, fontWeight: FontWeight.w500), + ), + ], + ), + ], + ); + } + + Widget _buildCurrentSpeed(ColorScheme colors) { + final stats = _networkStats!; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.speed, color: colors.primary, size: 20), + const SizedBox(width: 8), + Text( + 'Текущая скорость', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + ], + ), + const SizedBox(height: 12), + Row( + children: [ + Text( + _formatSpeed(stats.currentSpeed), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: colors.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + '↓', + style: TextStyle( + fontSize: 12, + color: colors.primary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ], + ), + ); + } + + Widget _buildTrafficDetails(ColorScheme colors) { + final stats = _networkStats!; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Детали трафика', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 16), + + _buildTrafficItem( + 'Медиафайлы', + _formatBytes(stats.mediaTraffic), + Icons.photo_library_outlined, + colors.primary, + (stats.mediaTraffic / stats.totalDailyTraffic), + ), + + _buildTrafficItem( + 'Сообщения', + _formatBytes(stats.messagesTraffic), + Icons.message_outlined, + colors.secondary, + (stats.messagesTraffic / stats.totalDailyTraffic), + ), + + _buildTrafficItem( + 'Синхронизация', + _formatBytes(stats.syncTraffic), + Icons.sync, + colors.tertiary, + (stats.syncTraffic / stats.totalDailyTraffic), + ), + + _buildTrafficItem( + 'Другие данные', + _formatBytes(stats.otherTraffic), + Icons.folder_outlined, + colors.outline, + (stats.otherTraffic / stats.totalDailyTraffic), + ), + ], + ), + ); + } + + Widget _buildTrafficItem( + String title, + String size, + IconData icon, + Color color, + double percentage, + ) { + final colors = Theme.of(context).colorScheme; + + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(icon, color: color, size: 20), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: colors.onSurface, + ), + ), + const SizedBox(height: 2), + Text( + size, + style: TextStyle( + fontSize: 12, + color: colors.onSurface.withOpacity(0.6), + ), + ), + ], + ), + ), + Container( + width: 60, + height: 4, + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(2), + ), + child: FractionallySizedBox( + alignment: Alignment.centerLeft, + widthFactor: percentage, + child: Container( + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(2), + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildHourlyChart(ColorScheme colors) { + final stats = _networkStats!; + final maxTraffic = stats.hourlyStats + .map((e) => e.traffic) + .reduce((a, b) => a > b ? a : b); + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Активность по часам', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 16), + SizedBox( + height: 120, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: stats.hourlyStats.length, + itemBuilder: (context, index) { + final hourStats = stats.hourlyStats[index]; + final height = maxTraffic > 0 + ? (hourStats.traffic / maxTraffic) + : 0.0; + + return Container( + width: 20, + margin: const EdgeInsets.symmetric(horizontal: 2), + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + height: height * 100, + decoration: BoxDecoration( + color: colors.primary.withOpacity(0.7), + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(height: 4), + Text( + '${hourStats.hour}', + style: TextStyle( + fontSize: 10, + color: colors.onSurface.withOpacity(0.6), + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ); + } + + Widget _buildActionButtons(ColorScheme colors) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Действия', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 16), + + Row( + children: [ + Expanded( + child: OutlinedButton.icon( + onPressed: _isMonitoring ? _stopMonitoring : _startMonitoring, + icon: Icon(_isMonitoring ? Icons.pause : Icons.play_arrow), + label: Text( + _isMonitoring ? 'Остановить мониторинг' : 'Начать мониторинг', + ), + style: OutlinedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: ElevatedButton.icon( + onPressed: _resetStats, + icon: const Icon(Icons.refresh), + label: const Text('Сбросить статистику'), + style: ElevatedButton.styleFrom( + backgroundColor: colors.error, + foregroundColor: colors.onError, + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + ], + ), + ], + ); + } +} + +class NetworkStats { + final double totalDailyTraffic; + final double messagesTraffic; + final double mediaTraffic; + final double syncTraffic; + final double otherTraffic; + final double currentSpeed; + final List hourlyStats; + final bool isConnected; + final String connectionType; + final int signalStrength; + final int ping; + final double jitter; + final double packetLoss; + + NetworkStats({ + required this.totalDailyTraffic, + required this.messagesTraffic, + required this.mediaTraffic, + required this.syncTraffic, + required this.otherTraffic, + required this.currentSpeed, + required this.hourlyStats, + required this.isConnected, + required this.connectionType, + required this.signalStrength, + this.ping = 25, + this.jitter = 2.5, + this.packetLoss = 0.01, + }); +} + +class HourlyStats { + final int hour; + final double traffic; + + HourlyStats({required this.hour, required this.traffic}); +} + +class NetworkChartPainter extends CustomPainter { + final double progress; + final ColorScheme colors; + + NetworkChartPainter({required this.progress, required this.colors}); + + @override + void paint(Canvas canvas, Size size) { + final center = Offset(size.width / 2, size.height / 2); + final radius = size.width / 2 - 8; + + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 16 + ..strokeCap = StrokeCap.round; + + + paint.color = colors.surfaceContainerHighest; + canvas.drawCircle(center, radius, paint); + + + paint.color = colors.primary; + final sweepAngle = 2 * pi * progress; + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + -pi / 2, // Начинаем сверху + sweepAngle, + false, + paint, + ); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return oldDelegate is NetworkChartPainter && + oldDelegate.progress != progress; + } +} diff --git a/lib/screens/settings/network_settings_screen.dart b/lib/screens/settings/network_settings_screen.dart new file mode 100644 index 0000000..17d36d8 --- /dev/null +++ b/lib/screens/settings/network_settings_screen.dart @@ -0,0 +1,262 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/screens/settings/network_screen.dart'; +import 'package:gwid/screens/settings/proxy_settings_screen.dart'; +import 'package:gwid/screens/settings/socket_log_screen.dart'; + +class NetworkSettingsScreen extends StatelessWidget { + final bool isModal; + + const NetworkSettingsScreen({super.key, this.isModal = false}); + + @override + Widget build(BuildContext context) { + if (isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar(title: const Text("Сеть")), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + _buildNetworkOption( + context, + icon: Icons.bar_chart_outlined, + title: "Мониторинг сети", + subtitle: "Просмотр статистики использования и скорости соединения", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const NetworkScreen()), + ); + }, + ), + _buildNetworkOption( + context, + icon: Icons.shield_outlined, + title: "Настройки прокси", + subtitle: "Настроить подключение через прокси-сервер", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ProxySettingsScreen(), + ), + ); + }, + ), + _buildNetworkOption( + context, + icon: Icons.history_outlined, + title: "Журнал WebSocket", + subtitle: "Просмотр логов подключения WebSocket для отладки", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SocketLogScreen(), + ), + ); + }, + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + _buildNetworkOption( + context, + icon: Icons.bar_chart_outlined, + title: "Мониторинг сети", + subtitle: "Статистика подключений и производительности", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const NetworkScreen(), + ), + ); + }, + ), + const SizedBox(height: 16), + _buildNetworkOption( + context, + icon: Icons.vpn_key_outlined, + title: "Настройки прокси", + subtitle: "HTTP/HTTPS прокси, SOCKS", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ProxySettingsScreen(), + ), + ); + }, + ), + const SizedBox(height: 16), + _buildNetworkOption( + context, + icon: Icons.list_alt_outlined, + title: "Логи сокетов", + subtitle: "Отладочная информация о соединениях", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SocketLogScreen(), + ), + ); + }, + ), + ], + ); + } + + Widget _buildModalSettings(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Сеть", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + _buildNetworkOption( + context, + icon: Icons.bar_chart_outlined, + title: "Мониторинг сети", + subtitle: "Статистика подключений и производительности", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const NetworkScreen(), + ), + ); + }, + ), + const SizedBox(height: 16), + _buildNetworkOption( + context, + icon: Icons.vpn_key_outlined, + title: "Настройки прокси", + subtitle: "HTTP/HTTPS прокси, SOCKS", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ProxySettingsScreen(), + ), + ); + }, + ), + const SizedBox(height: 16), + _buildNetworkOption( + context, + icon: Icons.list_alt_outlined, + title: "Логи сокетов", + subtitle: "Отладочная информация о соединениях", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SocketLogScreen(), + ), + ); + }, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildNetworkOption( + BuildContext context, { + required IconData icon, + required String title, + required String subtitle, + required VoidCallback onTap, + }) { + return Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: Icon(icon), + title: Text(title), + subtitle: Text(subtitle), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: onTap, + ), + ); + } +} diff --git a/lib/screens/settings/notification_settings_screen.dart b/lib/screens/settings/notification_settings_screen.dart new file mode 100644 index 0000000..c5bd5a2 --- /dev/null +++ b/lib/screens/settings/notification_settings_screen.dart @@ -0,0 +1,591 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'dart:io' show Platform; + +class NotificationSettingsScreen extends StatefulWidget { + final bool isModal; + + const NotificationSettingsScreen({super.key, this.isModal = false}); + + @override + State createState() => + _NotificationSettingsScreenState(); +} + +class _NotificationSettingsScreenState + extends State { + + String _chatsPushNotification = 'ON'; + bool _mCallPushNotification = true; + bool _pushDetails = true; + String _chatsPushSound = 'DEFAULT'; + String _pushSound = 'DEFAULT'; + bool _isLoading = false; + + Widget buildModalContent(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + + final isDesktopOrIOS = + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux || + Platform.isIOS; + + if (isDesktopOrIOS) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + Icon(Icons.info_outline, size: 48, color: colors.primary), + const SizedBox(height: 16), + Text( + 'Фоновые уведомления недоступны', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + Platform.isIOS + ? 'На iOS фоновые уведомления не поддерживаются системой.' + : 'На настольных платформах (Windows, macOS, Linux) фоновые уведомления отключены.', + style: TextStyle(color: colors.onSurfaceVariant), + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ], + ); + } + + return _isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + children: [ + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.chat_bubble_outline), + title: const Text("Уведомления из чатов"), + value: _chatsPushNotification == 'ON', + onChanged: (value) => + _updateNotificationSetting(chatsPush: value), + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.phone_outlined), + title: const Text("Уведомления о звонках"), + value: _mCallPushNotification, + onChanged: (value) => + _updateNotificationSetting(mCallPush: value), + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.visibility_outlined), + title: const Text("Показывать текст"), + subtitle: const Text("Показывать превью сообщения"), + value: _pushDetails, + onChanged: (value) => + _updateNotificationSetting(pushDetails: value), + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + children: [ + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.music_note_outlined), + title: const Text("Звук в чатах"), + trailing: Text( + _getSoundDescription(_chatsPushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Звук уведомлений чатов", + _chatsPushSound, + (value) => + _updateNotificationSetting(chatsSound: value), + ), + ), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.notifications_active_outlined), + title: const Text("Общий звук"), + trailing: Text( + _getSoundDescription(_pushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Общий звук уведомлений", + _pushSound, + (value) => _updateNotificationSetting(pushSound: value), + ), + ), + ], + ), + ), + ], + ); + } + + @override + void initState() { + super.initState(); + _loadCurrentSettings(); + } + + Future _loadCurrentSettings() async { + setState(() => _isLoading = true); + + await Future.delayed( + const Duration(milliseconds: 500), + ); // Имитация загрузки + setState(() => _isLoading = false); + } + + + + Future _updateNotificationSetting({ + bool? chatsPush, + bool? mCallPush, + bool? pushDetails, + String? chatsSound, + String? pushSound, + }) async { + try { + await ApiService.instance.updatePrivacySettings( + chatsPushNotification: chatsPush, + mCallPushNotification: mCallPush, + pushDetails: pushDetails, + chatsPushSound: chatsSound, + pushSound: pushSound, + ); + + if (chatsPush != null) + setState(() => _chatsPushNotification = chatsPush ? 'ON' : 'OFF'); + if (mCallPush != null) setState(() => _mCallPushNotification = mCallPush); + if (pushDetails != null) setState(() => _pushDetails = pushDetails); + if (chatsSound != null) setState(() => _chatsPushSound = chatsSound); + if (pushSound != null) setState(() => _pushSound = pushSound); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Настройки уведомлений обновлены'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка обновления: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + + + + void _showSoundDialog( + String title, + String currentValue, + Function(String) onSelect, + ) { + showDialog( + context: context, + builder: (context) { + return SimpleDialog( + title: Text(title), + children: [ + RadioListTile( + title: const Text('Стандартный звук'), + value: 'DEFAULT', + groupValue: currentValue, + onChanged: (v) => Navigator.of(context).pop(v), + ), + RadioListTile( + title: const Text('Без звука'), + value: '_NONE_', + groupValue: currentValue, + onChanged: (v) => Navigator.of(context).pop(v), + ), + ], + ); + }, + ).then((selectedValue) { + if (selectedValue != null) { + onSelect(selectedValue); + } + }); + } + + String _getSoundDescription(String sound) { + switch (sound) { + case 'DEFAULT': + return 'Стандартный'; + case '_NONE_': + return 'Без звука'; + default: + return 'Неизвестно'; + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + if (widget.isModal) { + return buildModalContent(context); + } + + + final isDesktopOrIOS = + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux || + Platform.isIOS; + + if (isDesktopOrIOS) { + return Scaffold( + appBar: AppBar(title: const Text('Уведомления')), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + Icon(Icons.info_outline, size: 48, color: colors.primary), + const SizedBox(height: 16), + Text( + 'Фоновые уведомления недоступны', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + Platform.isIOS + ? 'На iOS фоновые уведомления не поддерживаются системой.' + : 'На настольных платформах (Windows, macOS, Linux) фоновые уведомления отключены.', + style: TextStyle(color: colors.onSurfaceVariant), + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ], + ), + ); + } + + return Scaffold( + appBar: AppBar(title: const Text('Уведомления')), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + children: [ + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.chat_bubble_outline), + title: const Text("Уведомления из чатов"), + value: _chatsPushNotification == 'ON', + onChanged: (value) => + _updateNotificationSetting(chatsPush: value), + ), + + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.phone_outlined), + title: const Text("Уведомления о звонках"), + value: _mCallPushNotification, + onChanged: (value) => + _updateNotificationSetting(mCallPush: value), + ), + + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.visibility_outlined), + title: const Text("Показывать текст"), + subtitle: const Text("Показывать превью сообщения"), + value: _pushDetails, + onChanged: (value) => + _updateNotificationSetting(pushDetails: value), + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + children: [ + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.music_note_outlined), + title: const Text("Звук в чатах"), + trailing: Text( + _getSoundDescription(_chatsPushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Звук в чатах", + _chatsPushSound, + (value) => + _updateNotificationSetting(chatsSound: value), + ), + ), + + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon( + Icons.notifications_active_outlined, + ), + title: const Text("Общий звук"), + trailing: Text( + _getSoundDescription(_pushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Общий звук уведомлений", + _pushSound, + (value) => + _updateNotificationSetting(pushSound: value), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildModalSettings(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Уведомления", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + _OutlinedSection( + child: Column( + children: [ + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon( + Icons.chat_bubble_outline, + ), + title: const Text("Уведомления из чатов"), + value: _chatsPushNotification == 'ON', + onChanged: (value) => + _updateNotificationSetting( + chatsPush: value, + ), + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon( + Icons.phone_outlined, + ), + title: const Text( + "Уведомления о звонках", + ), + value: _mCallPushNotification, + onChanged: (value) => + _updateNotificationSetting( + mCallPush: value, + ), + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon( + Icons.visibility_outlined, + ), + title: const Text("Показывать текст"), + subtitle: const Text( + "Показывать превью сообщения", + ), + value: _pushDetails, + onChanged: (value) => + _updateNotificationSetting( + pushDetails: value, + ), + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + children: [ + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon( + Icons.music_note_outlined, + ), + title: const Text("Звук в чатах"), + trailing: Text( + _getSoundDescription(_chatsPushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Звук уведомлений чатов", + _chatsPushSound, + (value) => _updateNotificationSetting( + chatsSound: value, + ), + ), + ), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon( + Icons.notifications_active_outlined, + ), + title: const Text("Общий звук"), + trailing: Text( + _getSoundDescription(_pushSound), + style: TextStyle(color: colors.primary), + ), + onTap: () => _showSoundDialog( + "Общий звук уведомлений", + _pushSound, + (value) => _updateNotificationSetting( + pushSound: value, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} + +class _OutlinedSection extends StatelessWidget { + final Widget child; + const _OutlinedSection({required this.child}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + border: Border.all(color: colors.outline.withOpacity(0.3)), + borderRadius: BorderRadius.circular(12), + ), + child: child, + ); + } +} diff --git a/lib/screens/settings/privacy_security_screen.dart b/lib/screens/settings/privacy_security_screen.dart new file mode 100644 index 0000000..e892aa8 --- /dev/null +++ b/lib/screens/settings/privacy_security_screen.dart @@ -0,0 +1,216 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/screens/settings/privacy_settings_screen.dart'; +import 'package:gwid/screens/settings/security_settings_screen.dart'; + +class PrivacySecurityScreen extends StatelessWidget { + final bool isModal; + + const PrivacySecurityScreen({super.key, this.isModal = false}); + + @override + Widget build(BuildContext context) { + if (isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar(title: const Text("Приватность и безопасность")), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + child: ListTile( + leading: const Icon(Icons.privacy_tip_outlined), + title: const Text("Приватность"), + subtitle: const Text("Статус онлайн, кто может вас найти"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const PrivacySettingsScreen(), + ), + ); + }, + ), + ), + const SizedBox(height: 10), + Card( + child: ListTile( + leading: const Icon(Icons.lock_outline), + title: const Text("Безопасность"), + subtitle: const Text("Пароль, сессии, заблокированные"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SecuritySettingsScreen(), + ), + ); + }, + ), + ), + ], + ), + ); + } + + Widget _buildModalSettings(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Приватность и безопасность", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + child: ListTile( + leading: const Icon(Icons.privacy_tip_outlined), + title: const Text("Приватность"), + subtitle: const Text("Статус онлайн, кто может вас найти"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const PrivacySettingsScreen(), + ), + ); + }, + ), + ), + const SizedBox(height: 16), + Card( + child: ListTile( + leading: const Icon(Icons.security_outlined), + title: const Text("Безопасность"), + subtitle: const Text("Пароли, сессии, двухфакторная аутентификация"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SecuritySettingsScreen(), + ), + ); + }, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget buildModalContent(BuildContext context) { + return ListView( + padding: const EdgeInsets.all(16), + children: [ + Card( + child: ListTile( + leading: const Icon(Icons.privacy_tip_outlined), + title: const Text("Приватность"), + subtitle: const Text("Статус онлайн, кто может вас найти"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const PrivacySettingsScreen(), + ), + ); + }, + ), + ), + const SizedBox(height: 16), + Card( + child: ListTile( + leading: const Icon(Icons.security_outlined), + title: const Text("Безопасность"), + subtitle: const Text("Пароли, сессии, двухфакторная аутентификация"), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SecuritySettingsScreen(), + ), + ); + }, + ), + ), + ], + ); + } +} diff --git a/lib/screens/settings/privacy_settings_screen.dart b/lib/screens/settings/privacy_settings_screen.dart new file mode 100644 index 0000000..ccd52b8 --- /dev/null +++ b/lib/screens/settings/privacy_settings_screen.dart @@ -0,0 +1,383 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:gwid/password_management_screen.dart'; + +class PrivacySettingsScreen extends StatefulWidget { + const PrivacySettingsScreen({super.key}); + + @override + State createState() => _PrivacySettingsScreenState(); +} + +class _PrivacySettingsScreenState extends State { + + bool _isHidden = false; + bool _isLoading = false; + String _searchByPhone = 'ALL'; // 'ALL', 'CONTACTS', 'NOBODY' + String _incomingCall = 'ALL'; // 'ALL', 'CONTACTS', 'NOBODY' + String _chatsInvite = 'ALL'; // 'ALL', 'CONTACTS', 'NOBODY' + + @override + void initState() { + super.initState(); + _loadCurrentSettings(); + + ApiService.instance.messages.listen((message) { + if (message['type'] == 'privacy_settings_updated' && mounted) { + _loadCurrentSettings(); + } + }); + } + + Future _loadCurrentSettings() async { + try { + final prefs = await SharedPreferences.getInstance(); + setState(() { + _isHidden = prefs.getBool('privacy_hidden') ?? false; + _searchByPhone = prefs.getString('privacy_search_by_phone') ?? 'ALL'; + _incomingCall = prefs.getString('privacy_incoming_call') ?? 'ALL'; + _chatsInvite = prefs.getString('privacy_chats_invite') ?? 'ALL'; + }); + } catch (e) { + print('Ошибка загрузки настроек приватности: $e'); + } + } + + Future _savePrivacySetting(String key, dynamic value) async { + try { + final prefs = await SharedPreferences.getInstance(); + if (value is bool) { + await prefs.setBool(key, value); + } else if (value is String) { + await prefs.setString(key, value); + } + } catch (e) { + print('Ошибка сохранения настройки $key: $e'); + } + } + + + + Future _updateHiddenStatus(bool hidden) async { + setState(() => _isLoading = true); + try { + await ApiService.instance.updatePrivacySettings( + hidden: hidden ? 'true' : 'false', + ); + await _savePrivacySetting('privacy_hidden', hidden); + if (mounted) { + setState(() => _isHidden = hidden); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + hidden ? 'Статус онлайн скрыт' : 'Статус онлайн виден', + ), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + _showErrorSnackBar(e); + } finally { + if (mounted) setState(() => _isLoading = false); + } + } + + Future _updatePrivacyOption({ + String? searchByPhone, + String? incomingCall, + String? chatsInvite, + }) async { + try { + await ApiService.instance.updatePrivacySettings( + searchByPhone: searchByPhone, + incomingCall: incomingCall, + chatsInvite: chatsInvite, + ); + + if (searchByPhone != null) { + await _savePrivacySetting('privacy_search_by_phone', searchByPhone); + if (mounted) setState(() => _searchByPhone = searchByPhone); + } + if (incomingCall != null) { + await _savePrivacySetting('privacy_incoming_call', incomingCall); + if (mounted) setState(() => _incomingCall = incomingCall); + } + if (chatsInvite != null) { + await _savePrivacySetting('privacy_chats_invite', chatsInvite); + if (mounted) setState(() => _chatsInvite = chatsInvite); + } + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Настройки приватности обновлены'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + _showErrorSnackBar(e); + } + } + + void _showErrorSnackBar(Object e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка обновления: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + + + + void _showOptionDialog( + String title, + String currentValue, + Function(String) onSelect, + ) { + showDialog( + context: context, + builder: (context) { + return SimpleDialog( + title: Text(title), + children: [ + _buildDialogOption( + 'Все пользователи', + 'ALL', + currentValue, + onSelect, + ), + _buildDialogOption( + 'Только контакты', + 'CONTACTS', + currentValue, + onSelect, + ), + _buildDialogOption('Никто', 'NOBODY', currentValue, onSelect), + ], + ); + }, + ); + } + + Widget _buildDialogOption( + String title, + String value, + String groupValue, + Function(String) onSelect, + ) { + return RadioListTile( + title: Text(title), + value: value, + groupValue: groupValue, + onChanged: (newValue) { + if (newValue != null) { + onSelect(newValue); + Navigator.of(context).pop(); + } + }, + ); + } + + + + String _getPrivacyDescription(String value) { + switch (value) { + case 'ALL': + return 'Все пользователи'; + case 'CONTACTS': + return 'Только контакты'; + case 'NOBODY': + return 'Никто'; + default: + return 'Неизвестно'; + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final theme = context.watch(); + return Scaffold( + appBar: AppBar(title: const Text('Приватность')), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Статус онлайн", colors), + if (_isLoading) const LinearProgressIndicator(), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: Icon( + _isHidden + ? Icons.visibility_off_outlined + : Icons.visibility_outlined, + ), + title: const Text("Скрыть статус онлайн"), + subtitle: Text( + _isHidden + ? "Другие не видят, что вы онлайн" + : "Другие видят ваш статус онлайн", + ), + value: _isHidden, + onChanged: _isLoading ? null : _updateHiddenStatus, + ), + ], + ), + ), + const SizedBox(height: 16), + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Взаимодействие", colors), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.search), + title: const Text("Кто может найти меня по номеру"), + subtitle: Text(_getPrivacyDescription(_searchByPhone)), + onTap: () => _showOptionDialog( + "Кто может найти вас?", + _searchByPhone, + (value) => _updatePrivacyOption(searchByPhone: value), + ), + ), + + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.phone_callback_outlined), + title: const Text("Кто может звонить мне"), + subtitle: Text(_getPrivacyDescription(_incomingCall)), + onTap: () => _showOptionDialog( + "Кто может вам звонить?", + _incomingCall, + (value) => _updatePrivacyOption(incomingCall: value), + ), + ), + + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.group_add_outlined), + title: const Text("Кто может приглашать в чаты"), + subtitle: Text(_getPrivacyDescription(_chatsInvite)), + onTap: () => _showOptionDialog( + "Кто может приглашать вас в чаты?", + _chatsInvite, + (value) => _updatePrivacyOption(chatsInvite: value), + ), + ), + ], + ), + ), + + const SizedBox(height: 16), + + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Пароль аккаунта", colors), + ListTile( + contentPadding: EdgeInsets.zero, + leading: const Icon(Icons.lock_outline), + title: const Text("Установить пароль"), + subtitle: const Text( + "Добавить пароль для дополнительной защиты аккаунта", + ), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + const PasswordManagementScreen(), + ), + ); + }, + ), + ], + ), + ), + + const SizedBox(height: 16), + + _OutlinedSection( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionTitle("Прочтение сообщений", colors), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.mark_chat_read_outlined), + title: const Text("Читать сообщения при входе"), + subtitle: const Text( + "Отмечать чат прочитанным при открытии", + ), + + value: theme.debugReadOnEnter, + onChanged: (value) => theme.setDebugReadOnEnter(value), + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + secondary: const Icon(Icons.send_and_archive_outlined), + title: const Text("Читать при отправке сообщения"), + subtitle: const Text( + "Отмечать чат прочитанным при отправке сообщения", + ), + + value: theme.debugReadOnAction, + onChanged: (value) => theme.setDebugReadOnAction(value), + ), + ], + ), + ), + ], + ), + ), + ); + } + + Widget _buildSectionTitle(String title, ColorScheme colors) { + return Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Text( + title, + style: TextStyle( + color: colors.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + ), + ); + } +} + +class _OutlinedSection extends StatelessWidget { + final Widget child; + const _OutlinedSection({required this.child}); + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border.all(color: colors.outline.withOpacity(0.3)), + borderRadius: BorderRadius.circular(12), + ), + child: child, + ); + } +} diff --git a/lib/screens/settings/proxy_settings_screen.dart b/lib/screens/settings/proxy_settings_screen.dart new file mode 100644 index 0000000..e6b2b42 --- /dev/null +++ b/lib/screens/settings/proxy_settings_screen.dart @@ -0,0 +1,263 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/proxy_service.dart'; +import 'package:gwid/proxy_settings.dart'; + +class ProxySettingsScreen extends StatefulWidget { + const ProxySettingsScreen({super.key}); + + @override + State createState() => _ProxySettingsScreenState(); +} + +class _ProxySettingsScreenState extends State { + final _formKey = GlobalKey(); + late ProxySettings _settings; + bool _isLoading = true; + bool _isTesting = false; // <-- НОВОЕ: Состояние для отслеживания проверки + + final _hostController = TextEditingController(); + final _portController = TextEditingController(); + final _usernameController = TextEditingController(); + final _passwordController = TextEditingController(); + + @override + void initState() { + super.initState(); + _loadSettings(); + } + + Future _loadSettings() async { + final settings = await ProxyService.instance.loadProxySettings(); + setState(() { + _settings = settings; + _hostController.text = _settings.host; + _portController.text = _settings.port.toString(); + _usernameController.text = _settings.username ?? ''; + _passwordController.text = _settings.password ?? ''; + _isLoading = false; + }); + } + + + Future _testProxyConnection() async { + if (_formKey.currentState?.validate() != true) { + return; + } + setState(() { + _isTesting = true; + }); + + + final settingsToTest = ProxySettings( + isEnabled: true, // Для теста прокси всегда должен быть включен + protocol: _settings.protocol, + host: _hostController.text.trim(), + port: int.tryParse(_portController.text.trim()) ?? 8080, + username: _usernameController.text.trim(), + password: _passwordController.text.trim(), + ); + + try { + await ProxyService.instance.checkProxy(settingsToTest); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Прокси доступен и работает'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка подключения: $e'), + backgroundColor: Colors.red, + ), + ); + } + } finally { + if (mounted) { + setState(() { + _isTesting = false; + }); + } + } + } + + Future _saveSettings() async { + if (_formKey.currentState!.validate()) { + final newSettings = ProxySettings( + isEnabled: _settings.isEnabled, + protocol: _settings.protocol, + host: _hostController.text.trim(), + port: int.tryParse(_portController.text.trim()) ?? 8080, + username: _usernameController.text.trim().isEmpty + ? null + : _usernameController.text.trim(), + password: _passwordController.text.trim().isEmpty + ? null + : _passwordController.text.trim(), + ); + + await ProxyService.instance.saveProxySettings(newSettings); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Настройки прокси сохранены. Перезайдите, чтобы применить.', + ), + backgroundColor: Colors.green, + ), + ); + Navigator.of(context).pop(); + } + } + } + + @override + void dispose() { + _hostController.dispose(); + _portController.dispose(); + _usernameController.dispose(); + _passwordController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Настройки прокси'), + actions: [ + IconButton( + icon: const Icon(Icons.save), + onPressed: _isLoading || _isTesting ? null : _saveSettings, + ), + ], + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : Form( + key: _formKey, + child: ListView( + padding: const EdgeInsets.all(16), + children: [ + SwitchListTile( + title: const Text('Включить прокси'), + value: _settings.isEnabled, + onChanged: (value) { + setState(() { + _settings = _settings.copyWith(isEnabled: value); + }); + }, + ), + const SizedBox(height: 16), + DropdownButtonFormField( + initialValue: _settings.protocol, + decoration: const InputDecoration( + labelText: 'Протокол', + border: OutlineInputBorder(), + ), + items: ProxyProtocol.values + + .where( + (p) => + p != ProxyProtocol.socks4 && + p != ProxyProtocol.socks5, + ) + .map( + (protocol) => DropdownMenuItem( + value: protocol, + child: Text(protocol.name.toUpperCase()), + ), + ) + .toList(), + onChanged: (value) { + if (value != null) { + setState(() { + _settings = _settings.copyWith(protocol: value); + }); + } + }, + ), + const SizedBox(height: 16), + TextFormField( + controller: _hostController, + decoration: const InputDecoration( + labelText: 'Хост', + border: OutlineInputBorder(), + ), + validator: (value) { + if (_settings.isEnabled && + (value == null || value.isEmpty)) { + return 'Укажите хост прокси-сервера'; + } + return null; + }, + ), + const SizedBox(height: 16), + TextFormField( + controller: _portController, + decoration: const InputDecoration( + labelText: 'Порт', + border: OutlineInputBorder(), + ), + keyboardType: TextInputType.number, + validator: (value) { + if (_settings.isEnabled) { + if (value == null || value.isEmpty) { + return 'Укажите порт'; + } + if (int.tryParse(value) == null) { + return 'Некорректный номер порта'; + } + } + return null; + }, + ), + const SizedBox(height: 24), + Text( + 'Аутентификация (необязательно)', + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 16), + TextFormField( + controller: _usernameController, + decoration: const InputDecoration( + labelText: 'Имя пользователя', + border: OutlineInputBorder(), + ), + ), + const SizedBox(height: 16), + TextFormField( + controller: _passwordController, + decoration: const InputDecoration( + labelText: 'Пароль', + border: OutlineInputBorder(), + ), + obscureText: true, + ), + const SizedBox(height: 24), + + ElevatedButton.icon( + onPressed: _isTesting ? null : _testProxyConnection, + icon: _isTesting + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : const Icon(Icons.shield_outlined), + label: Text(_isTesting ? 'Проверка...' : 'Проверить'), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/settings/qr_login_screen.dart b/lib/screens/settings/qr_login_screen.dart new file mode 100644 index 0000000..b7d4d2a --- /dev/null +++ b/lib/screens/settings/qr_login_screen.dart @@ -0,0 +1,301 @@ + + +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:gwid/api_service.dart'; +import 'dart:convert'; + +class QrLoginScreen extends StatefulWidget { + const QrLoginScreen({super.key}); + + @override + State createState() => _QrLoginScreenState(); +} + +class _QrLoginScreenState extends State { + String? _token; + String? _qrData; + bool _isLoading = true; + bool _isQrVisible = false; + String? _error; + + Timer? _qrRefreshTimer; // Таймер для регенерации QR-кода (1 раз в минуту) + Timer? + _countdownTimer; // 👈 1. Таймер для обратного отсчета (1 раз в секунду) + int _countdownSeconds = 60; // 👈 2. Переменная для хранения секунд + + @override + void initState() { + super.initState(); + _initializeAndStartTimers(); + } + + @override + void dispose() { + _qrRefreshTimer?.cancel(); + _countdownTimer?.cancel(); // 👈 3. Не забываем отменить второй таймер + super.dispose(); + } + + + Future _initializeAndStartTimers() async { + setState(() { + _isLoading = true; + _error = null; + }); + + try { + final token = ApiService.instance.token; + if (token == null || token.isEmpty) { + throw Exception("Не удалось получить токен авторизации."); + } + + if (mounted) { + _token = token; + _regenerateQrData(); // Первичная генерация + + + _qrRefreshTimer?.cancel(); + _qrRefreshTimer = Timer.periodic(const Duration(minutes: 1), (timer) { + _regenerateQrData(); + }); + + + _startCountdownTimer(); + + setState(() => _isLoading = false); + } + } catch (e) { + if (mounted) { + setState(() { + _error = e.toString(); + _isLoading = false; + }); + } + } + } + + + void _regenerateQrData() { + if (_token == null) return; + final data = { + "type": "komet_auth_v1", + "token": _token!, + "timestamp": DateTime.now().millisecondsSinceEpoch, + }; + if (mounted) { + setState(() { + _qrData = jsonEncode(data); + _countdownSeconds = 60; // Сбрасываем счетчик на 60 + }); + } + } + + + void _startCountdownTimer() { + _countdownTimer?.cancel(); + _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (mounted) { + setState(() { + if (_countdownSeconds > 0) { + _countdownSeconds--; + } else { + + + _countdownSeconds = 60; + } + }); + } + }); + } + + void _toggleQrVisibility() { + if (_token != null) { + setState(() { + _isQrVisible = !_isQrVisible; + }); + } + } + + + + Widget _buildContent() { + if (_isLoading) { + return const Center(child: CircularProgressIndicator()); + } + if (_error != null) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.error_outline, color: Colors.red, size: 60), + const SizedBox(height: 16), + const Text( + "Ошибка загрузки данных", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + Text(_error!, textAlign: TextAlign.center), + const SizedBox(height: 20), + FilledButton.icon( + onPressed: _initializeAndStartTimers, + icon: const Icon(Icons.refresh), + label: const Text("Повторить"), + ), + ], + ), + ); + } + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildQrDisplay(), + const SizedBox(height: 32), + FilledButton.icon( + onPressed: _toggleQrVisibility, + icon: Icon( + _isQrVisible + ? Icons.visibility_off_outlined + : Icons.visibility_outlined, + ), + label: Text( + _isQrVisible ? "Скрыть QR-код" : "Показать QR-код для входа", + ), + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 16), + textStyle: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ); + } + + Widget _buildQrDisplay() { + final colors = Theme.of(context).colorScheme; + + if (!_isQrVisible) { + return Center( + child: Column( + children: [ + Icon( + Icons.qr_code_scanner_rounded, + size: 150, + color: colors.onSurface.withOpacity(0.3), + ), + const SizedBox(height: 16), + Text( + "QR-код скрыт", + style: Theme.of(context).textTheme.headlineSmall, + ), + const SizedBox(height: 8), + Text( + "Нажмите кнопку ниже, чтобы отобразить его.", + style: TextStyle(color: colors.onSurfaceVariant), + textAlign: TextAlign.center, + ), + ], + ), + ); + } + + + return Center( + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(12.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(24.0), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + spreadRadius: 2, + blurRadius: 15, + offset: const Offset(0, 4), + ), + ], + ), + child: QrImageView( + data: _qrData!, + version: QrVersions.auto, + size: 280.0, + dataModuleStyle: QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.circle, + color: colors.primary, + ), + eyeStyle: QrEyeStyle( + eyeShape: QrEyeShape.circle, + color: colors.primary, + ), + errorCorrectionLevel: QrErrorCorrectLevel.H, + ), + ), + const SizedBox(height: 16), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.timer_outlined, + color: colors.onSurfaceVariant, + size: 20, + ), + const SizedBox(width: 8), + Text( + "Обновится через: $_countdownSeconds сек.", + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Scaffold( + appBar: AppBar(title: const Text("Вход по QR-коду")), + body: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.errorContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: const Row( + children: [ + Icon(Icons.gpp_bad_outlined, color: Colors.red, size: 32), + SizedBox(width: 16), + Expanded( + child: Text( + "Любой, кто отсканирует этот код, получит полный доступ к вашему аккаунту. Не показывайте его посторонним.", + style: TextStyle(fontWeight: FontWeight.w500), + ), + ), + ], + ), + ), + const Spacer(), + _buildContent(), + const Spacer(flex: 2), + ], + ), + ), + ); + } +} diff --git a/lib/screens/settings/qr_scanner_screen.dart b/lib/screens/settings/qr_scanner_screen.dart new file mode 100644 index 0000000..6425904 --- /dev/null +++ b/lib/screens/settings/qr_scanner_screen.dart @@ -0,0 +1,64 @@ + + +import 'package:flutter/material.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; + +class QrScannerScreen extends StatefulWidget { + const QrScannerScreen({super.key}); + + @override + State createState() => _QrScannerScreenState(); +} + +class _QrScannerScreenState extends State { + final MobileScannerController _scannerController = MobileScannerController( + detectionSpeed: DetectionSpeed.normal, + facing: CameraFacing.back, + ); + bool _isScanCompleted = false; + + @override + void dispose() { + _scannerController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("Сканировать QR-код"), + backgroundColor: Colors.black, + foregroundColor: Colors.white, + ), + body: Stack( + children: [ + MobileScanner( + controller: _scannerController, + onDetect: (capture) { + if (!_isScanCompleted) { + final String? code = capture.barcodes.first.rawValue; + if (code != null) { + setState(() => _isScanCompleted = true); + + Navigator.of(context).pop(code); + } + } + }, + ), + + Center( + child: Container( + width: 250, + height: 250, + decoration: BoxDecoration( + border: Border.all(color: Colors.white, width: 2), + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/settings/reconnection_screen.dart b/lib/screens/settings/reconnection_screen.dart new file mode 100644 index 0000000..f53a8c6 --- /dev/null +++ b/lib/screens/settings/reconnection_screen.dart @@ -0,0 +1,298 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/home_screen.dart'; + +class ReconnectionScreen extends StatefulWidget { + const ReconnectionScreen({super.key}); + + @override + State createState() => _ReconnectionScreenState(); +} + +class _ReconnectionScreenState extends State { + StreamSubscription? _apiSubscription; + String _statusMessage = 'Переподключение...'; + bool _isReconnecting = true; + Timer? _timeoutTimer; + + @override + void initState() { + super.initState(); + _startFullReconnection(); + _listenToApiMessages(); + } + + @override + void dispose() { + _apiSubscription?.cancel(); + _timeoutTimer?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + print( + 'ReconnectionScreen: Получено сообщение: opcode=${message['opcode']}, cmd=${message['cmd']}', + ); + + + if (message['opcode'] == 19 && message['cmd'] == 1) { + final payload = message['payload']; + print('ReconnectionScreen: Получен opcode 19, payload: $payload'); + if (payload != null && payload['token'] != null) { + print('ReconnectionScreen: Вызываем _onReconnectionSuccess()'); + _onReconnectionSuccess(); + return; + } + } + + + if (message['cmd'] == 3) { + final errorPayload = message['payload']; + String errorMessage = 'Ошибка переподключения'; + if (errorPayload != null) { + if (errorPayload['localizedMessage'] != null) { + errorMessage = errorPayload['localizedMessage']; + } else if (errorPayload['message'] != null) { + errorMessage = errorPayload['message']; + } + } + _onReconnectionError(errorMessage); + } + }); + } + + void _onReconnectionSuccess() { + if (!mounted) return; + + print('ReconnectionScreen: _onReconnectionSuccess() вызван'); + + + _timeoutTimer?.cancel(); + + setState(() { + _statusMessage = 'Переподключение успешно!'; + _isReconnecting = false; + }); + + print('ReconnectionScreen: Устанавливаем таймер для навигации...'); + + + Timer(const Duration(milliseconds: 1500), () { + if (mounted) { + print('ReconnectionScreen: Навигация к HomeScreen...'); + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const HomeScreen()), + (route) => false, + ); + } + }); + } + + void _onReconnectionError(String error) { + if (!mounted) return; + + + _timeoutTimer?.cancel(); + + setState(() { + _statusMessage = 'Ошибка: $error'; + _isReconnecting = false; + }); + + + Timer(const Duration(seconds: 3), () { + if (mounted) { + setState(() { + _statusMessage = 'Нажмите для повторной попытки'; + }); + } + }); + } + + Future _startFullReconnection() async { + try { + print('ReconnectionScreen: Начинаем полное переподключение...'); + + + _timeoutTimer = Timer(const Duration(seconds: 30), () { + if (mounted && _isReconnecting) { + _onReconnectionError('Таймаут переподключения'); + } + }); + + setState(() { + _statusMessage = 'Отключение от сервера...'; + }); + + + ApiService.instance.disconnect(); + + setState(() { + _statusMessage = 'Очистка кэшей...'; + }); + + + ApiService.instance.clearAllCaches(); + + setState(() { + _statusMessage = 'Подключение к серверу...'; + }); + + + await ApiService.instance.performFullReconnection(); + + setState(() { + _statusMessage = 'Аутентификация...'; + }); + + + final hasToken = await ApiService.instance.hasToken(); + if (hasToken) { + setState(() { + _statusMessage = 'Аутентификация...'; + }); + + + await ApiService.instance.getChatsAndContacts(); + + setState(() { + _statusMessage = 'Загрузка данных...'; + }); + } else { + _onReconnectionError('Токен аутентификации не найден'); + } + } catch (e) { + _onReconnectionError('Ошибка переподключения: ${e.toString()}'); + } + } + + void _retryReconnection() { + setState(() { + _statusMessage = 'Переподключение...'; + _isReconnecting = true; + }); + _startFullReconnection(); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return WillPopScope( + onWillPop: () async => false, // Блокируем кнопку "Назад" + child: Scaffold( + backgroundColor: colors.surface, + body: Container( + width: double.infinity, + height: double.infinity, + color: colors.surface.withOpacity(0.95), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + Container( + width: 120, + height: 120, + decoration: BoxDecoration( + color: colors.primaryContainer, + shape: BoxShape.circle, + ), + child: _isReconnecting + ? CircularProgressIndicator( + strokeWidth: 4, + valueColor: AlwaysStoppedAnimation( + colors.primary, + ), + ) + : Icon( + _statusMessage.contains('Ошибка') + ? Icons.error_outline + : Icons.check_circle_outline, + size: 60, + color: _statusMessage.contains('Ошибка') + ? colors.error + : colors.primary, + ), + ), + + const SizedBox(height: 32), + + + Text( + 'Переподключение', + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontWeight: FontWeight.bold, + color: colors.onSurface, + ), + ), + + const SizedBox(height: 16), + + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: Text( + _statusMessage, + style: Theme.of(context).textTheme.bodyLarge?.copyWith( + color: colors.onSurfaceVariant, + ), + textAlign: TextAlign.center, + ), + ), + + const SizedBox(height: 48), + + + if (!_isReconnecting && _statusMessage.contains('Нажмите')) + ElevatedButton.icon( + onPressed: _retryReconnection, + icon: const Icon(Icons.refresh), + label: const Text('Повторить'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 32, + vertical: 16, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + + const SizedBox(height: 32), + + + Container( + margin: const EdgeInsets.symmetric(horizontal: 32), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Row( + children: [ + Icon(Icons.info_outline, color: colors.primary, size: 20), + const SizedBox(width: 12), + Expanded( + child: Text( + 'Выполняется полное переподключение к серверу. Пожалуйста, подождите.', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: colors.onSurfaceVariant, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/settings/security_settings_screen.dart b/lib/screens/settings/security_settings_screen.dart new file mode 100644 index 0000000..10ca6c0 --- /dev/null +++ b/lib/screens/settings/security_settings_screen.dart @@ -0,0 +1,91 @@ + + +import 'package:flutter/material.dart'; +import 'package:gwid/screens/settings/session_spoofing_screen.dart'; +import 'package:gwid/screens/settings/sessions_screen.dart'; +import 'package:gwid/screens/settings/export_session_screen.dart'; +import 'package:gwid/screens/settings/qr_login_screen.dart'; + +class SecuritySettingsScreen extends StatelessWidget { + const SecuritySettingsScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text("Безопасность")), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + + _buildSecurityOption( + context, + icon: Icons.qr_code_scanner_outlined, + title: "Вход по QR-коду", + subtitle: "Показать QR-код для входа на другом устройстве", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const QrLoginScreen()), + ); + }, + ), + _buildSecurityOption( + context, + icon: Icons.history_toggle_off, + title: "Активные сессии", + subtitle: "Просмотр и управление активными сессиями", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const SessionsScreen()), + ); + }, + ), + _buildSecurityOption( + context, + icon: Icons.upload_file_outlined, + title: "Экспорт сессии", + subtitle: "Сохранить данные сессии для переноса", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ExportSessionScreen(), + ), + ); + }, + ), + _buildSecurityOption( + context, + icon: Icons.devices_other_outlined, + title: "Подмена данных сессии", + subtitle: "Изменение User-Agent, версии ОС и т.д.", + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const SessionSpoofingScreen(), + ), + ); + }, + ), + ], + ), + ); + } + + Widget _buildSecurityOption( + BuildContext context, { + required IconData icon, + required String title, + required String subtitle, + required VoidCallback onTap, + }) { + return Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: Icon(icon), + title: Text(title), + subtitle: Text(subtitle), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: onTap, + ), + ); + } +} diff --git a/lib/screens/settings/session_spoofing_screen.dart b/lib/screens/settings/session_spoofing_screen.dart new file mode 100644 index 0000000..8977dee --- /dev/null +++ b/lib/screens/settings/session_spoofing_screen.dart @@ -0,0 +1,754 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:math'; +import 'package:gwid/services/version_checker.dart'; +import 'package:flutter/material.dart'; +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter_timezone/flutter_timezone.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:gwid/api_service.dart'; +import 'package:uuid/uuid.dart'; +import 'package:gwid/device_presets.dart'; +import 'package:gwid/phone_entry_screen.dart'; + + +enum SpoofingMethod { partial, full } + + +enum PresetCategory { web, device } + +class SessionSpoofingScreen extends StatefulWidget { + const SessionSpoofingScreen({super.key}); + + @override + State createState() => _SessionSpoofingScreenState(); +} + +class _SessionSpoofingScreenState extends State { + final _random = Random(); + final _uuid = const Uuid(); + final _userAgentController = TextEditingController(); + final _deviceNameController = TextEditingController(); + final _osVersionController = TextEditingController(); + final _screenController = TextEditingController(); + final _timezoneController = TextEditingController(); + final _localeController = TextEditingController(); + final _deviceIdController = TextEditingController(); + final _appVersionController = TextEditingController(); + + String _selectedDeviceType = 'WEB'; + SpoofingMethod _selectedMethod = SpoofingMethod.partial; + PresetCategory _selectedCategory = PresetCategory.web; + bool _isCheckingVersion = false; + bool _isLoading = true; + + @override + void initState() { + super.initState(); + _loadInitialData(); + } + + + Future _loadInitialData() async { + setState(() => _isLoading = true); + final prefs = await SharedPreferences.getInstance(); + final isSpoofingEnabled = prefs.getBool('spoofing_enabled') ?? false; + + if (isSpoofingEnabled) { + _userAgentController.text = prefs.getString('spoof_useragent') ?? ''; + _deviceNameController.text = prefs.getString('spoof_devicename') ?? ''; + _osVersionController.text = prefs.getString('spoof_osversion') ?? ''; + _screenController.text = prefs.getString('spoof_screen') ?? ''; + _timezoneController.text = prefs.getString('spoof_timezone') ?? ''; + _localeController.text = prefs.getString('spoof_locale') ?? ''; + _deviceIdController.text = prefs.getString('spoof_deviceid') ?? ''; + _appVersionController.text = + prefs.getString('spoof_appversion') ?? '25.10.10'; + _selectedDeviceType = prefs.getString('spoof_devicetype') ?? 'WEB'; + + if (_selectedDeviceType == 'WEB') { + _selectedCategory = PresetCategory.web; + } else { + _selectedCategory = PresetCategory.device; + } + } else { + setState(() { + _selectedCategory = PresetCategory.web; + }); + await _applyGeneratedData(); + } + + setState(() => _isLoading = false); + } + + + Future _loadDeviceData() async { + setState(() => _isLoading = true); + + final deviceInfo = DeviceInfoPlugin(); + final pixelRatio = View.of(context).devicePixelRatio; + final size = View.of(context).physicalSize; + + _appVersionController.text = '25.10.10'; + _localeController.text = Platform.localeName.split('_').first; + _screenController.text = + '${size.width.round()}x${size.height.round()} ${pixelRatio.toStringAsFixed(1)}x'; + _deviceIdController.text = _uuid.v4(); + + try { + final timezoneInfo = await FlutterTimezone.getLocalTimezone(); + _timezoneController.text = timezoneInfo.identifier; + } catch (e) { + _timezoneController.text = 'Europe/Moscow'; + } + + if (Platform.isAndroid) { + final androidInfo = await deviceInfo.androidInfo; + _deviceNameController.text = + '${androidInfo.manufacturer} ${androidInfo.model}'; + _osVersionController.text = 'Android ${androidInfo.version.release}'; + _userAgentController.text = + 'Mozilla/5.0 (Linux; Android ${androidInfo.version.release}; ${androidInfo.model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36'; + _selectedDeviceType = 'ANDROID'; + } else if (Platform.isIOS) { + final iosInfo = await deviceInfo.iosInfo; + _deviceNameController.text = iosInfo.name; + _osVersionController.text = + '${iosInfo.systemName} ${iosInfo.systemVersion}'; + _userAgentController.text = + 'Mozilla/5.0 (iPhone; CPU iPhone OS ${iosInfo.systemVersion.replaceAll('.', '_')} like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1'; + _selectedDeviceType = 'IOS'; + } else { + setState(() => _selectedCategory = PresetCategory.device); + await _applyGeneratedData(); + } + + setState(() { + _selectedCategory = PresetCategory.device; + _isLoading = false; + }); + } + + + Future _applyGeneratedData() async { + final List filteredPresets; + if (_selectedCategory == PresetCategory.web) { + filteredPresets = devicePresets + .where((p) => p.deviceType == 'WEB') + .toList(); + } else { + filteredPresets = devicePresets + .where((p) => p.deviceType != 'WEB') + .toList(); + } + + if (filteredPresets.isEmpty) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Нет доступных пресетов для этой категории.'), + ), + ); + } + return; + } + + final preset = filteredPresets[_random.nextInt(filteredPresets.length)]; + await _applyPreset(preset); + } + + + Future _applyPreset(DevicePreset preset) async { + setState(() { + _userAgentController.text = preset.userAgent; + _deviceNameController.text = preset.deviceName; + _osVersionController.text = preset.osVersion; + _screenController.text = preset.screen; + _appVersionController.text = '25.10.10'; + _deviceIdController.text = _uuid.v4(); + + if (_selectedMethod == SpoofingMethod.partial) { + _selectedDeviceType = 'WEB'; + } else { + _selectedDeviceType = preset.deviceType; + _timezoneController.text = preset.timezone; + _localeController.text = preset.locale; + } + }); + + if (_selectedMethod == SpoofingMethod.partial) { + String timezone; + try { + final timezoneInfo = await FlutterTimezone.getLocalTimezone(); + timezone = timezoneInfo.identifier; + } catch (_) { + timezone = 'Europe/Moscow'; + } + final locale = Platform.localeName.split('_').first; + + if (mounted) { + setState(() { + _timezoneController.text = timezone; + _localeController.text = locale; + }); + } + } + } + + + Future _saveSpoofingSettings() async { + if (!mounted) return; + + final prefs = await SharedPreferences.getInstance(); + + + final oldValues = { + 'user_agent': prefs.getString('spoof_useragent') ?? '', + 'device_name': prefs.getString('spoof_devicename') ?? '', + 'os_version': prefs.getString('spoof_osversion') ?? '', + 'screen': prefs.getString('spoof_screen') ?? '', + 'timezone': prefs.getString('spoof_timezone') ?? '', + 'locale': prefs.getString('spoof_locale') ?? '', + 'device_id': prefs.getString('spoof_deviceid') ?? '', + 'device_type': prefs.getString('spoof_devicetype') ?? 'WEB', + }; + + final newValues = { + 'user_agent': _userAgentController.text, + 'device_name': _deviceNameController.text, + 'os_version': _osVersionController.text, + 'screen': _screenController.text, + 'timezone': _timezoneController.text, + 'locale': _localeController.text, + 'device_id': _deviceIdController.text, + 'device_type': _selectedDeviceType, + }; + + final oldAppVersion = prefs.getString('spoof_appversion') ?? '25.10.10'; + final newAppVersion = _appVersionController.text; + + + bool otherDataChanged = false; + for (final key in oldValues.keys) { + if (oldValues[key] != newValues[key]) { + otherDataChanged = true; + break; + } + } + + final appVersionChanged = oldAppVersion != newAppVersion; + + + + + if (appVersionChanged && !otherDataChanged) { + + await _saveAllData(prefs); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Настройки применятся при следующем входе в приложение.', + ), + duration: Duration(seconds: 3), + ), + ); + + Navigator.of(context).pop(); + } + } + + else { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Применить настройки?'), + content: const Text( + 'Для применения настроек потребуется перезайти в аккаунт. Вы уверены?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + child: const Text('Применить'), + ), + ], + ), + ); + + if (confirmed != true || !mounted) return; + + await _saveAllData(prefs); + + try { + if (mounted) { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const PhoneEntryScreen()), + (route) => false, + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при выходе: $e'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } + } + } + + + Future _saveAllData(SharedPreferences prefs) async { + await prefs.setBool('spoofing_enabled', true); + await prefs.setString('spoof_useragent', _userAgentController.text); + await prefs.setString('spoof_devicename', _deviceNameController.text); + await prefs.setString('spoof_osversion', _osVersionController.text); + await prefs.setString('spoof_screen', _screenController.text); + await prefs.setString('spoof_timezone', _timezoneController.text); + await prefs.setString('spoof_locale', _localeController.text); + await prefs.setString('spoof_deviceid', _deviceIdController.text); + await prefs.setString('spoof_devicetype', _selectedDeviceType); + await prefs.setString('spoof_appversion', _appVersionController.text); + } + + Future _handleVersionCheck() async { + if (_isCheckingVersion) return; + setState(() => _isCheckingVersion = true); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Проверяю последнюю версию...')), + ); + + try { + final latestVersion = await VersionChecker.getLatestVersion(); + if (mounted) { + setState(() => _appVersionController.text = latestVersion); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Найдена версия: $latestVersion'), + backgroundColor: Colors.green.shade700, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(e.toString()), // Показываем ошибку из VersionChecker + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + } + } finally { + if (mounted) { + setState(() => _isCheckingVersion = false); + } + } + } + + @override + void dispose() { + _userAgentController.dispose(); + _deviceNameController.dispose(); + _osVersionController.dispose(); + _screenController.dispose(); + _timezoneController.dispose(); + _localeController.dispose(); + _deviceIdController.dispose(); + _appVersionController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Подмена данных сессии'), + centerTitle: true, + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + + padding: const EdgeInsets.fromLTRB(16, 8, 16, 120), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _buildInfoCard(), + const SizedBox(height: 16), + _buildSpoofingMethodCard(), + const SizedBox(height: 16), + _buildPresetTypeCard(), + const SizedBox(height: 24), + _buildMainDataCard(), + const SizedBox(height: 16), + _buildRegionalDataCard(), + const SizedBox(height: 16), + _buildIdentifiersCard(), + ], + ), + ), + + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: _buildFloatingActionButtons(), + ); + } + + Widget _buildInfoCard() { + return Card( + color: Theme.of(context).colorScheme.secondaryContainer.withOpacity(0.5), + elevation: 0, + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Text.rich( + TextSpan( + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSecondaryContainer, + ), + children: const [ + TextSpan( + text: 'Нажмите ', + style: TextStyle(fontWeight: FontWeight.w500), + ), + WidgetSpan( + child: Icon(Icons.touch_app, size: 16), + alignment: PlaceholderAlignment.middle, + ), + TextSpan(text: ' "Сгенерировать":\n'), + TextSpan( + text: '• Короткое нажатие: ', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: 'случайный пресет.\n'), + TextSpan( + text: '• Длинное нажатие: ', + style: TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan(text: 'реальные данные.'), + ], + ), + textAlign: TextAlign.center, + ), + ), + ); + } + + Widget _buildSpoofingMethodCard() { + final theme = Theme.of(context); + Widget descriptionWidget; + + if (_selectedMethod == SpoofingMethod.partial) { + descriptionWidget = _buildDescriptionTile( + icon: Icons.check_circle_outline, + color: Colors.green.shade700, + text: + 'Рекомендуемый метод. Используются случайные данные, но ваш реальный часовой пояс и локаль для большей правдоподобности.', + ); + } else { + descriptionWidget = _buildDescriptionTile( + icon: Icons.warning_amber_rounded, + color: theme.colorScheme.error, + text: + 'Все данные, включая часовой пояс и локаль, генерируются случайно. Использование этого метода на ваш страх и риск!', + ); + } + + return Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Text("Метод подмены", style: theme.textTheme.titleMedium), + const SizedBox(height: 12), + SegmentedButton( + style: SegmentedButton.styleFrom(shape: const StadiumBorder()), + segments: const [ + ButtonSegment( + value: SpoofingMethod.partial, + label: Text('Частичный'), + icon: Icon(Icons.security_outlined), + ), + ButtonSegment( + value: SpoofingMethod.full, + label: Text('Полный'), + icon: Icon(Icons.public_outlined), + ), + ], + selected: {_selectedMethod}, + onSelectionChanged: (s) => + setState(() => _selectedMethod = s.first), + ), + const SizedBox(height: 12), + descriptionWidget, + ], + ), + ), + ); + } + + Widget _buildDescriptionTile({ + required IconData icon, + required Color color, + required String text, + }) { + return ListTile( + leading: Icon(icon, color: color), + contentPadding: EdgeInsets.zero, + title: Text( + text, + style: TextStyle( + fontSize: 13, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ); + } + + Widget _buildPresetTypeCard() { + return Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + Text( + "Тип пресетов для генерации", + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 12), + SegmentedButton( + style: SegmentedButton.styleFrom(shape: const StadiumBorder()), + segments: const >[ + ButtonSegment( + value: PresetCategory.web, + label: Text('Веб'), + icon: Icon(Icons.web_outlined), + ), + ButtonSegment( + value: PresetCategory.device, + label: Text('Устройства'), + icon: Icon(Icons.devices_outlined), + ), + ], + selected: {_selectedCategory}, + onSelectionChanged: (newSelection) { + setState(() => _selectedCategory = newSelection.first); + _applyGeneratedData(); + }, + ), + ], + ), + ), + ); + } + + Widget _buildSectionHeader(BuildContext context, String title) { + return Padding( + padding: const EdgeInsets.only(bottom: 16.0, top: 8.0), + child: Text( + title, + style: Theme.of(context).textTheme.titleLarge?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.w600, + ), + ), + ); + } + + Widget _buildMainDataCard() { + return Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionHeader(context, "Основные данные"), + TextField( + controller: _userAgentController, + decoration: _inputDecoration('User-Agent', Icons.http_outlined), + maxLines: 3, + minLines: 2, + ), + const SizedBox(height: 16), + TextField( + controller: _deviceNameController, + decoration: _inputDecoration( + 'Имя устройства', + Icons.smartphone_outlined, + ), + ), + const SizedBox(height: 16), + TextField( + controller: _osVersionController, + decoration: _inputDecoration('Версия ОС', Icons.layers_outlined), + ), + ], + ), + ), + ); + } + + Widget _buildRegionalDataCard() { + return Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionHeader(context, "Региональные данные"), + TextField( + controller: _screenController, + decoration: _inputDecoration( + 'Разрешение экрана', + Icons.fullscreen_outlined, + ), + ), + const SizedBox(height: 16), + TextField( + controller: _timezoneController, + enabled: _selectedMethod == SpoofingMethod.full, + decoration: _inputDecoration( + 'Часовой пояс', + Icons.public_outlined, + ), + ), + const SizedBox(height: 16), + TextField( + controller: _localeController, + enabled: _selectedMethod == SpoofingMethod.full, + decoration: _inputDecoration('Локаль', Icons.language_outlined), + ), + ], + ), + ), + ); + } + + Widget _buildIdentifiersCard() { + return Card( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionHeader(context, "Идентификаторы"), + TextField( + controller: _deviceIdController, + decoration: _inputDecoration('ID Устройства', Icons.tag_outlined), + ), + const SizedBox(height: 16), + TextField( + controller: _appVersionController, + decoration: + _inputDecoration( + 'Версия приложения', + Icons.info_outline_rounded, + ).copyWith( + + suffixIcon: _isCheckingVersion + ? const Padding( + + padding: EdgeInsets.all(12.0), + child: SizedBox( + height: 24, + width: 24, + child: CircularProgressIndicator( + strokeWidth: 2.5, + ), + ), + ) + : IconButton( + + icon: const Icon(Icons.cloud_sync_outlined), + tooltip: 'Проверить последнюю версию', + onPressed: + _handleVersionCheck, // Вот здесь вызывается ваша функция + ), + ), + ), + const SizedBox(height: 16), + DropdownButtonFormField( + value: _selectedDeviceType, + decoration: _inputDecoration( + 'Тип устройства', + Icons.devices_other_outlined, + ), + items: const [ + DropdownMenuItem(value: 'ANDROID', child: Text('ANDROID')), + DropdownMenuItem(value: 'IOS', child: Text('IOS')), + DropdownMenuItem(value: 'DESKTOP', child: Text('DESKTOP')), + DropdownMenuItem(value: 'WEB', child: Text('WEB')), + ], + onChanged: (v) => + v != null ? setState(() => _selectedDeviceType = v) : null, + ), + ], + ), + ), + ); + } + + InputDecoration _inputDecoration(String label, IconData icon) { + return InputDecoration( + labelText: label, + prefixIcon: Icon(icon), + border: OutlineInputBorder(borderRadius: BorderRadius.circular(16)), + filled: true, + fillColor: Theme.of(context).colorScheme.surfaceContainerHighest, + ); + } + + Widget _buildFloatingActionButtons() { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + Expanded( + flex: 3, + child: FilledButton.tonal( + onPressed: _applyGeneratedData, + onLongPress: _loadDeviceData, + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric( + vertical: 16, + horizontal: 16, + ), + shape: const StadiumBorder(), + ), + child: const Text('Сгенерировать'), + ), + ), + const SizedBox(width: 12), + Expanded( + flex: 4, + child: FilledButton( + onPressed: _saveSpoofingSettings, + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric( + vertical: 16, + horizontal: 16, + ), + shape: const StadiumBorder(), + ), + child: const Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.save_alt_outlined), + SizedBox(width: 8), + Text('Применить'), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/settings/sessions_screen.dart b/lib/screens/settings/sessions_screen.dart new file mode 100644 index 0000000..1f7e21b --- /dev/null +++ b/lib/screens/settings/sessions_screen.dart @@ -0,0 +1,251 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'dart:async'; +import 'package:intl/intl.dart'; + +class Session { + final String client; + final String location; + final bool current; + final int time; + final String info; + + Session({ + required this.client, + required this.location, + required this.current, + required this.time, + required this.info, + }); + + factory Session.fromJson(Map json) { + return Session( + client: json['client'] ?? 'Неизвестное устройство', + location: json['location'] ?? 'Неизвестное местоположение', + current: json['current'] ?? false, + time: json['time'] ?? 0, + info: json['info'] ?? 'Нет дополнительной информации', + ); + } +} + +class SessionsScreen extends StatefulWidget { + const SessionsScreen({super.key}); + + @override + State createState() => _SessionsScreenState(); +} + +class _SessionsScreenState extends State { + List _sessions = []; + bool _isLoading = true; + StreamSubscription? _apiSubscription; + + @override + void initState() { + super.initState(); + _listenToApi(); + _loadSessions(); + } + + void _listenToApi() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (message['opcode'] == 96 && mounted) { + final payload = message['payload']; + if (payload != null && payload['sessions'] != null) { + final sessionsList = payload['sessions'] as List; + setState(() { + _sessions = sessionsList + .map((session) => Session.fromJson(session)) + .toList(); + _isLoading = false; + }); + } + } + }); + } + + void _loadSessions() { + setState(() => _isLoading = true); + ApiService.instance.requestSessions(); + } + + void _terminateAllSessions() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Завершить другие сессии?'), + content: const Text( + 'Все сессии, кроме текущей, будут завершены. Вы уверены?', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => Navigator.of(context).pop(true), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.error, + ), + child: const Text('Завершить'), + ), + ], + ), + ); + + if (confirmed == true) { + ApiService.instance.terminateAllSessions(); + Future.delayed(const Duration(seconds: 1), _loadSessions); + } + } + + String _formatTime(int timestamp) { + final date = DateTime.fromMillisecondsSinceEpoch(timestamp); + final now = DateTime.now(); + final difference = now.difference(date); + + if (difference.inDays > 0) { + return '${difference.inDays} д. назад'; + } else if (difference.inHours > 0) { + return '${difference.inHours} ч. назад'; + } else if (difference.inMinutes > 0) { + return '${difference.inMinutes} м. назад'; + } else { + return 'Только что'; + } + } + + IconData _getDeviceIcon(String clientInfo) { + final lowerInfo = clientInfo.toLowerCase(); + if (lowerInfo.contains('windows') || + lowerInfo.contains('linux') || + lowerInfo.contains('macos')) { + return Icons.computer_outlined; + } else if (lowerInfo.contains('iphone') || lowerInfo.contains('ios')) { + return Icons.phone_iphone; + } else if (lowerInfo.contains('android')) { + return Icons.phone_android; + } + return Icons.web_asset; + } + + @override + void dispose() { + _apiSubscription?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text("Активные сессии"), + actions: [ + IconButton(onPressed: _loadSessions, icon: const Icon(Icons.refresh)), + ], + ), + body: Column( + children: [ + if (_sessions.any((s) => !s.current)) + Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), + child: SizedBox( + width: double.infinity, + child: FilledButton.icon( + onPressed: _terminateAllSessions, + icon: const Icon(Icons.logout), + label: const Text("Завершить другие сессии"), + style: FilledButton.styleFrom( + backgroundColor: colors.errorContainer, + foregroundColor: colors.onErrorContainer, + ), + ), + ), + ), + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _sessions.isEmpty + ? Center( + child: Text( + "Активных сессий не найдено.", + style: TextStyle(color: colors.onSurfaceVariant), + ), + ) + : ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: _sessions.length, + separatorBuilder: (context, index) => + const SizedBox(height: 12), + itemBuilder: (context, index) { + final session = _sessions[index]; + final deviceIcon = _getDeviceIcon(session.client); + + return Card( + elevation: session.current ? 4 : 1, + shape: RoundedRectangleBorder( + side: BorderSide( + color: session.current + ? colors.primary + : Colors.transparent, + width: 1.5, + ), + borderRadius: BorderRadius.circular(12), + ), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + children: [ + Icon(deviceIcon, size: 40, color: colors.primary), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + session.client, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 4), + Text( + session.location, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + const SizedBox(height: 4), + Text( + "Последняя активность: ${_formatTime(session.time)}", + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 12, + ), + ), + ], + ), + ), + if (session.current) + const Icon( + Icons.check_circle, + color: Colors.green, + size: 24, + ), + ], + ), + ), + ); + }, + ), + ), + ], + ), + ); + } +} diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart new file mode 100644 index 0000000..e17107d --- /dev/null +++ b/lib/screens/settings/settings_screen.dart @@ -0,0 +1,610 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/models/profile.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/manage_account_screen.dart'; +import 'package:gwid/screens/settings/appearance_settings_screen.dart'; +import 'package:gwid/screens/settings/notification_settings_screen.dart'; +import 'package:gwid/screens/settings/privacy_security_screen.dart'; +import 'package:gwid/screens/settings/storage_screen.dart'; +import 'package:gwid/screens/settings/network_settings_screen.dart'; +import 'package:gwid/screens/settings/bypass_screen.dart'; +import 'package:gwid/screens/settings/about_screen.dart'; +import 'package:gwid/debug_screen.dart'; +import 'package:gwid/screens/settings/komet_misc_screen.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:provider/provider.dart'; + +class SettingsScreen extends StatefulWidget { + final bool showBackToChats; + final VoidCallback? onBackToChats; + final Profile? myProfile; + final bool isModal; + + const SettingsScreen({ + super.key, + this.showBackToChats = false, + this.onBackToChats, + this.myProfile, + this.isModal = false, + }); + + @override + State createState() => _SettingsScreenState(); +} + +class _SettingsScreenState extends State { + Profile? _myProfile; + bool _isProfileLoading = true; + int _versionTapCount = 0; + DateTime? _lastTapTime; + bool _isReconnecting = false; + + + String _currentModalScreen = 'main'; + + @override + void initState() { + super.initState(); + if (widget.myProfile != null) { + + _myProfile = widget.myProfile; + _isProfileLoading = false; + } else { + + _loadMyProfile(); + } + } + + Future _loadMyProfile() async { + if (!mounted) return; + setState(() => _isProfileLoading = true); + + + final cachedProfileData = ApiService.instance.lastChatsPayload?['profile']; + if (cachedProfileData != null && mounted) { + setState(() { + _myProfile = Profile.fromJson(cachedProfileData); + _isProfileLoading = false; + }); + return; // Нашли в кеше, выходим + } + + + try { + final result = await ApiService.instance.getChatsAndContacts(force: true); + if (mounted) { + final profileJson = result['profile']; + if (profileJson != null) { + setState(() { + _myProfile = Profile.fromJson(profileJson); + _isProfileLoading = false; + }); + } else { + setState(() => _isProfileLoading = false); + } + } + } catch (e) { + if (mounted) { + setState(() => _isProfileLoading = false); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text("Ошибка загрузки профиля: $e"))); + } + } + } + + Future _handleReconnection() async { + if (_isReconnecting) return; + + setState(() { + _isReconnecting = true; + }); + + try { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Переподключение...'), + duration: Duration(seconds: 2), + ), + ); + } + + await ApiService.instance.performFullReconnection(); + await _loadMyProfile(); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Переподключение выполнено успешно'), + backgroundColor: Colors.green, + duration: Duration(seconds: 2), + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка переподключения: $e'), + backgroundColor: Colors.red, + duration: Duration(seconds: 3), + ), + ); + } + } finally { + if (mounted) { + setState(() { + _isReconnecting = false; + }); + } + } + } + + Widget _buildReconnectionButton() { + return Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + leading: Icon( + Icons.sync, + color: _isReconnecting + ? Colors.grey + : Theme.of(context).colorScheme.primary, + ), + title: const Text( + "Переподключиться к серверу", + style: TextStyle(fontWeight: FontWeight.w500), + ), + subtitle: const Text("Сбросить соединение и переподключиться"), + trailing: _isReconnecting + ? const SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator(strokeWidth: 2), + ) + : Icon( + Icons.chevron_right_rounded, + color: Theme.of(context).colorScheme.primary, + ), + onTap: _isReconnecting ? null : _handleReconnection, + ), + ); + } + + void _handleVersionTap() { + final now = DateTime.now(); + if (_lastTapTime != null && now.difference(_lastTapTime!).inSeconds > 2) { + _versionTapCount = 0; + } + _lastTapTime = now; + _versionTapCount++; + + if (_versionTapCount >= 7) { + _versionTapCount = 0; + Navigator.of( + context, + ).push(MaterialPageRoute(builder: (context) => const DebugScreen())); + } + } + + @override + Widget build(BuildContext context) { + final themeProvider = context.watch(); + final isDesktop = themeProvider.useDesktopLayout; + + if (widget.isModal || isDesktop) { + return _buildModalSettings(context); + } + + return Scaffold( + appBar: AppBar( + title: const Text("Настройки"), + leading: widget.showBackToChats + ? IconButton( + icon: const Icon(Icons.arrow_back), + onPressed: widget.onBackToChats, + ) + : null, + ), + body: _buildSettingsContent(), + ); + } + + Widget _buildModalSettings(BuildContext context) { + final colors = Theme.of(context).colorScheme; + final screenSize = MediaQuery.of(context).size; + final screenWidth = screenSize.width; + final screenHeight = screenSize.height; + + final isSmallScreen = screenWidth < 600 || screenHeight < 800; + + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withValues(alpha: 0.3), + ), + ), + + Center( + child: isSmallScreen + ? Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration(color: colors.surface), + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration(color: colors.surface), + child: Row( + children: [ + if (_currentModalScreen != 'main') + IconButton( + onPressed: () { + setState(() { + _currentModalScreen = 'main'; + }); + }, + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + Expanded( + child: Text( + _getModalTitle(), + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded(child: _buildModalContent()), + ], + ), + ) + : Container( + width: 400, + height: 900, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + if (_currentModalScreen != 'main') + IconButton( + onPressed: () { + setState(() { + _currentModalScreen = 'main'; + }); + }, + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + Expanded( + child: Text( + _getModalTitle(), + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded(child: _buildModalContent()), + ], + ), + ), + ), + ], + ), + ); + } + + String _getModalTitle() { + switch (_currentModalScreen) { + case 'notifications': + return 'Уведомления'; + case 'appearance': + return 'Внешний вид'; + case 'privacy': + return 'Приватность и безопасность'; + case 'storage': + return 'Хранилище'; + case 'network': + return 'Сеть'; + case 'bypass': + return 'Bypass'; + case 'about': + return 'О приложении'; + case 'komet': + return 'Komet Misc'; + default: + return 'Настройки'; + } + } + + Widget _buildModalContent() { + switch (_currentModalScreen) { + case 'notifications': + return const NotificationSettingsScreen(isModal: true); + case 'appearance': + return const AppearanceSettingsScreen(isModal: true); + case 'privacy': + return const PrivacySecurityScreen(isModal: true); + case 'storage': + return const StorageScreen(isModal: true); + case 'network': + return const NetworkSettingsScreen(isModal: true); + case 'bypass': + return const BypassScreen(isModal: true); + case 'about': + return const AboutScreen(isModal: true); + case 'komet': + return const KometMiscScreen(isModal: true); + default: + return _buildSettingsContent(); + } + } + + Widget _buildSettingsContent() { + return ListView( + padding: const EdgeInsets.all(16.0), + children: [ + + _buildProfileSection(), + const SizedBox(height: 16), + + _buildReconnectionButton(), + const SizedBox(height: 16), + + _buildSettingsCategory( + context, + icon: Icons.rocket_launch_outlined, + title: "Komet Misc", + subtitle: "Дополнительные настройки", + screen: KometMiscScreen(isModal: widget.isModal), + ), + + _buildSettingsCategory( + context, + icon: Icons.palette_outlined, + title: "Внешний вид", + subtitle: "Темы, анимации, производительность", + screen: AppearanceSettingsScreen(isModal: widget.isModal), + ), + _buildSettingsCategory( + context, + icon: Icons.notifications_outlined, + title: "Уведомления", + subtitle: "Звуки, чаты, звонки", + screen: NotificationSettingsScreen(isModal: widget.isModal), + ), + _buildSettingsCategory( + context, + icon: Icons.security_outlined, + title: "Приватность и безопасность", + subtitle: "Статус, сессии, пароль, блокировки", + screen: PrivacySecurityScreen(isModal: widget.isModal), + ), + _buildSettingsCategory( + context, + icon: Icons.storage_outlined, + title: "Данные и хранилище", + subtitle: "Использование хранилища, очистка кэша", + screen: StorageScreen(isModal: widget.isModal), + ), + _buildSettingsCategory( + context, + icon: Icons.wifi_outlined, + title: "Сеть", + subtitle: "Прокси, мониторинг, логи", + screen: NetworkSettingsScreen(isModal: widget.isModal), + ), + _buildSettingsCategory( + context, + icon: Icons.psychology_outlined, + title: "Специальные возможности", + subtitle: "Обход ограничений", + screen: const BypassScreen(), + ), + _buildSettingsCategory( + context, + icon: Icons.info_outline, + title: "О приложении", + subtitle: "Команда, соглашение", + screen: const AboutScreen(), + ), + + + GestureDetector( + onTap: _handleVersionTap, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 24.0), + child: Text( + 'v0.3.0-beta.1', + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.onSurface.withValues(alpha: 0.4), + fontSize: 12, + ), + ), + ), + ), + ], + ); + } + + Widget _buildProfileSection() { + if (_isProfileLoading) { + return const Card( + child: ListTile( + leading: CircleAvatar(radius: 28), + title: Text("Загрузка профиля..."), + subtitle: Text("Пожалуйста, подождите"), + ), + ); + } + + if (_myProfile == null) { + return Card( + child: ListTile( + leading: const CircleAvatar( + radius: 28, + child: Icon(Icons.error_outline), + ), + title: const Text("Не удалось загрузить профиль"), + trailing: IconButton( + icon: const Icon(Icons.refresh), + onPressed: _loadMyProfile, + ), + ), + ); + } + + return Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + leading: CircleAvatar( + radius: 28, + backgroundImage: _myProfile!.photoBaseUrl != null + ? NetworkImage(_myProfile!.photoBaseUrl!) + : null, + child: _myProfile!.photoBaseUrl == null + ? Text( + _myProfile!.displayName.isNotEmpty + ? _myProfile!.displayName[0].toUpperCase() + : '', + style: const TextStyle(fontSize: 24), + ) + : null, + ), + title: Text( + _myProfile!.displayName, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(_myProfile!.formattedPhone), + const SizedBox(height: 2), + Text( + 'ID: ${_myProfile!.id}', + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ManageAccountScreen(myProfile: _myProfile!), + ), + ); + }, + ), + ); + } + + Widget _buildSettingsCategory( + BuildContext context, { + required IconData icon, + required String title, + required String subtitle, + required Widget screen, + }) { + return Card( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + leading: Icon(icon, color: Theme.of(context).colorScheme.primary), + title: Text(title), + subtitle: Text(subtitle), + trailing: const Icon(Icons.chevron_right_rounded), + onTap: () { + if (widget.isModal) { + + String screenKey = ''; + if (screen is NotificationSettingsScreen) + screenKey = 'notifications'; + else if (screen is AppearanceSettingsScreen) + screenKey = 'appearance'; + else if (screen is PrivacySecurityScreen) + screenKey = 'privacy'; + else if (screen is StorageScreen) + screenKey = 'storage'; + else if (screen is NetworkSettingsScreen) + screenKey = 'network'; + else if (screen is BypassScreen) + screenKey = 'bypass'; + else if (screen is AboutScreen) + screenKey = 'about'; + else if (screen is KometMiscScreen) + screenKey = 'komet'; + + setState(() { + _currentModalScreen = screenKey; + }); + } else { + + Navigator.of( + context, + ).push(MaterialPageRoute(builder: (context) => screen)); + } + }, + ), + ); + } +} diff --git a/lib/screens/settings/socket_log_screen.dart b/lib/screens/settings/socket_log_screen.dart new file mode 100644 index 0000000..efd2559 --- /dev/null +++ b/lib/screens/settings/socket_log_screen.dart @@ -0,0 +1,513 @@ + + +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/api_service.dart'; +import 'package:intl/intl.dart'; +import 'package:share_plus/share_plus.dart'; + + +enum LogType { send, receive, status, pingpong } + + +class LogEntry { + final DateTime timestamp; + final String message; + final int id; + final LogType type; + + LogEntry({ + required this.timestamp, + required this.message, + required this.id, + required this.type, + }); +} + +class SocketLogScreen extends StatefulWidget { + const SocketLogScreen({super.key}); + + @override + State createState() => _SocketLogScreenState(); +} + +class _SocketLogScreenState extends State { + final List _allLogEntries = []; + List _filteredLogEntries = []; + StreamSubscription? _logSubscription; + final ScrollController _scrollController = ScrollController(); + int _logIdCounter = 0; + bool _isAutoScrollEnabled = true; + + + bool _isSearchActive = false; + final TextEditingController _searchController = TextEditingController(); + String _searchQuery = ''; + + + final Set _activeFilters = { + LogType.send, + LogType.receive, + LogType.status, + LogType.pingpong, + }; + + @override + void initState() { + super.initState(); + + _searchController.addListener(() { + if (_searchQuery != _searchController.text) { + setState(() { + _searchQuery = _searchController.text; + _applyFiltersAndSearch(); + }); + } + }); + _loadInitialLogs(); + _subscribeToNewLogs(); + } + + LogType _getLogType(String message) { + if (message.contains('(ping)') || message.contains('(pong)')) { + return LogType.pingpong; + } + if (message.startsWith('➡️ SEND')) return LogType.send; + if (message.startsWith('⬅️ RECV')) return LogType.receive; + return LogType.status; + } + + + void _addLogEntry(String logMessage, {bool isInitial = false}) { + final newEntry = LogEntry( + id: _logIdCounter++, + timestamp: DateTime.now(), + message: logMessage, + type: _getLogType(logMessage), + ); + _allLogEntries.add(newEntry); + + + if (!isInitial) { + _applyFiltersAndSearch(); + if (_isAutoScrollEnabled) _scrollToBottom(); + } + } + + void _loadInitialLogs() { + final cachedLogs = ApiService.instance.connectionLogCache; + for (var log in cachedLogs) { + _addLogEntry(log, isInitial: true); + } + _applyFiltersAndSearch(); + setState( + () {}, + ); // Однократное обновление UI после загрузки всех кэшированных логов + } + + void _subscribeToNewLogs() { + _logSubscription = ApiService.instance.connectionLog.listen((logMessage) { + if (mounted) { + if (_allLogEntries.isNotEmpty && + _allLogEntries.last.message == logMessage) { + return; + } + setState(() => _addLogEntry(logMessage)); + } + }); + } + + void _scrollToBottom() { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (_scrollController.hasClients) { + _scrollController.animateTo( + _scrollController.position.maxScrollExtent, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOut, + ); + } + }); + } + + + void _applyFiltersAndSearch() { + List tempFiltered = _allLogEntries.where((entry) { + return _activeFilters.contains(entry.type); + }).toList(); + + if (_searchQuery.isNotEmpty) { + tempFiltered = tempFiltered.where((entry) { + return entry.message.toLowerCase().contains(_searchQuery.toLowerCase()); + }).toList(); + } + + setState(() { + _filteredLogEntries = tempFiltered; + }); + } + + void _copyLogsToClipboard() { + final logText = _filteredLogEntries + .map( + (entry) => + "[${DateFormat('HH:mm:ss.SSS').format(entry.timestamp)}] ${entry.message}", + ) + .join('\n\n'); + Clipboard.setData(ClipboardData(text: logText)); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Отфильтрованный журнал скопирован')), + ); + } + + void _shareLogs() async { + final logText = _filteredLogEntries + .map( + (entry) => + "[${DateFormat('HH:mm:ss.SSS').format(entry.timestamp)}] ${entry.message}", + ) + .join('\n\n'); + await Share.share(logText, subject: 'Gwid Connection Log'); + } + + void _clearLogs() { + setState(() { + _allLogEntries.clear(); + _filteredLogEntries.clear(); + + + }); + } + + void _showFilterDialog() { + showModalBottomSheet( + context: context, + builder: (context) { + return StatefulBuilder( + builder: (context, setSheetState) { + + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "Фильтры логов", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + SwitchListTile( + title: const Text('Исходящие (SEND)'), + value: _activeFilters.contains(LogType.send), + onChanged: (val) { + setSheetState( + () => val + ? _activeFilters.add(LogType.send) + : _activeFilters.remove(LogType.send), + ); + _applyFiltersAndSearch(); + }, + ), + SwitchListTile( + title: const Text('Входящие (RECV)'), + value: _activeFilters.contains(LogType.receive), + onChanged: (val) { + setSheetState( + () => val + ? _activeFilters.add(LogType.receive) + : _activeFilters.remove(LogType.receive), + ); + _applyFiltersAndSearch(); + }, + ), + SwitchListTile( + title: const Text('Статус подключения'), + value: _activeFilters.contains(LogType.status), + onChanged: (val) { + setSheetState( + () => val + ? _activeFilters.add(LogType.status) + : _activeFilters.remove(LogType.status), + ); + _applyFiltersAndSearch(); + }, + ), + SwitchListTile( + title: const Text('Ping/Pong'), + value: _activeFilters.contains(LogType.pingpong), + onChanged: (val) { + setSheetState( + () => val + ? _activeFilters.add(LogType.pingpong) + : _activeFilters.remove(LogType.pingpong), + ); + _applyFiltersAndSearch(); + }, + ), + ], + ), + ); + }, + ); + }, + ); + } + + @override + void dispose() { + _logSubscription?.cancel(); + _scrollController.dispose(); + _searchController.dispose(); + super.dispose(); + } + + + AppBar _buildDefaultAppBar() { + return AppBar( + title: const Text("Журнал подключения"), + actions: [ + IconButton( + icon: const Icon(Icons.search), + tooltip: "Поиск", + onPressed: () => setState(() => _isSearchActive = true), + ), + IconButton( + icon: Icon( + _activeFilters.length == 4 + ? Icons.filter_list + : Icons.filter_list_off, + ), + tooltip: "Фильтры", + onPressed: _showFilterDialog, + ), + IconButton( + icon: const Icon(Icons.delete_sweep), + tooltip: "Очистить", + onPressed: _allLogEntries.isNotEmpty ? _clearLogs : null, + ), + ], + ); + } + + + AppBar _buildSearchAppBar() { + return AppBar( + leading: IconButton( + icon: const Icon(Icons.close), + onPressed: () { + setState(() { + _isSearchActive = false; + _searchController.clear(); + }); + }, + ), + title: TextField( + controller: _searchController, + autofocus: true, + decoration: const InputDecoration( + hintText: 'Поиск по логам...', + border: InputBorder.none, + ), + style: const TextStyle(color: Colors.white), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: _isSearchActive ? _buildSearchAppBar() : _buildDefaultAppBar(), + body: _filteredLogEntries.isEmpty + ? Center( + child: Text( + _allLogEntries.isEmpty ? "Журнал пуст." : "Записей не найдено.", + ), + ) + : ListView.builder( + controller: _scrollController, + padding: const EdgeInsets.fromLTRB( + 8, + 8, + 8, + 80, + ), // Оставляем место для FAB + itemCount: _filteredLogEntries.length, + itemBuilder: (context, index) { + return LogEntryCard( + key: ValueKey(_filteredLogEntries[index].id), + entry: _filteredLogEntries[index], + ); + }, + ), + floatingActionButton: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FloatingActionButton( + onPressed: () => + setState(() => _isAutoScrollEnabled = !_isAutoScrollEnabled), + mini: true, + tooltip: _isAutoScrollEnabled + ? 'Остановить автопрокрутку' + : 'Возобновить автопрокрутку', + child: Icon( + _isAutoScrollEnabled ? Icons.pause : Icons.arrow_downward, + ), + ), + const SizedBox(height: 8), + FloatingActionButton.extended( + onPressed: _shareLogs, + icon: const Icon(Icons.share), + label: const Text("Поделиться"), + tooltip: "Поделиться отфильтрованными логами", + ), + ], + ), + ); + } +} + + +class LogEntryCard extends StatelessWidget { + final LogEntry entry; + + const LogEntryCard({super.key, required this.entry}); + + (IconData, Color) _getVisuals( + LogType type, + String message, + BuildContext context, + ) { + final theme = Theme.of(context); + switch (type) { + case LogType.send: + return (Icons.arrow_upward, theme.colorScheme.primary); + case LogType.receive: + return (Icons.arrow_downward, Colors.green); + case LogType.pingpong: + return (Icons.sync_alt, Colors.grey); + case LogType.status: + if (message.startsWith('✅')) return (Icons.check_circle, Colors.green); + if (message.startsWith('❌')) { + return (Icons.error, theme.colorScheme.error); + } + return (Icons.info, Colors.orange.shade600); + } + } + + void _showJsonViewer(BuildContext context, String message) { + final jsonRegex = RegExp(r'(\{.*\})'); + final match = jsonRegex.firstMatch(message); + if (match == null) return; + + try { + final jsonPart = match.group(0)!; + final decoded = jsonDecode(jsonPart); + final prettyJson = const JsonEncoder.withIndent(' ').convert(decoded); + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text("Содержимое пакета (JSON)"), + content: SizedBox( + width: double.maxFinite, + child: SingleChildScrollView( + child: SelectableText( + prettyJson, + style: const TextStyle(fontFamily: 'monospace'), + ), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text("Закрыть"), + ), + ], + ), + ); + } catch (_) {} + } + + (String?, String?) _extractInfo(String message) { + try { + final jsonRegex = RegExp(r'(\{.*\})'); + final match = jsonRegex.firstMatch(message); + if (match == null) return (null, null); + final jsonPart = match.group(0)!; + final decoded = jsonDecode(jsonPart) as Map; + final opcode = decoded['opcode']?.toString(); + final seq = decoded['seq']?.toString(); + return (opcode, seq); + } catch (e) { + return (null, null); + } + } + + @override + Widget build(BuildContext context) { + final (icon, color) = _getVisuals(entry.type, entry.message, context); + final (opcode, seq) = _extractInfo(entry.message); + final formattedTime = DateFormat('HH:mm:ss.SSS').format(entry.timestamp); + final theme = Theme.of(context); + + return Card( + clipBehavior: Clip.antiAlias, + margin: const EdgeInsets.symmetric(vertical: 5), + child: InkWell( + onTap: () => _showJsonViewer(context, entry.message), + child: Container( + decoration: BoxDecoration( + border: Border(left: BorderSide(color: color, width: 4)), + ), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(icon, color: color, size: 20), + const SizedBox(width: 8), + Text( + formattedTime, + style: theme.textTheme.labelMedium?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + ), + const Spacer(), + if (opcode != null) + Chip( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + padding: EdgeInsets.zero, + label: Text( + 'OP: $opcode', + style: theme.textTheme.labelSmall, + ), + ), + const SizedBox(width: 4), + if (seq != null) + Chip( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + padding: EdgeInsets.zero, + label: Text( + 'SEQ: $seq', + style: theme.textTheme.labelSmall, + ), + ), + ], + ), + const SizedBox(height: 8), + SelectableText( + entry.message, + style: theme.textTheme.bodySmall?.copyWith( + fontFamily: 'monospace', + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/screens/settings/storage_screen.dart b/lib/screens/settings/storage_screen.dart new file mode 100644 index 0000000..f151d2d --- /dev/null +++ b/lib/screens/settings/storage_screen.dart @@ -0,0 +1,805 @@ +import 'package:flutter/material.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io'; +import 'dart:math'; + +class StorageScreen extends StatefulWidget { + final bool isModal; + + const StorageScreen({super.key, this.isModal = false}); + + @override + State createState() => _StorageScreenState(); +} + +class _StorageScreenState extends State + with TickerProviderStateMixin { + late AnimationController _animationController; + late Animation _animation; + + StorageInfo? _storageInfo; + bool _isLoading = true; + + Widget buildModalContent(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return _isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + + _buildStorageChart(colors), + const SizedBox(height: 20), + + + _buildStorageDetails(colors), + const SizedBox(height: 20), + + + _buildActionButtons(colors), + ], + ), + ); + } + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + duration: const Duration(milliseconds: 1500), + vsync: this, + ); + _animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), + ); + _loadStorageInfo(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + Future _loadStorageInfo() async { + try { + final info = await _getStorageInfo(); + setState(() { + _storageInfo = info; + _isLoading = false; + }); + _animationController.forward(); + } catch (e) { + setState(() { + _isLoading = false; + }); + } + } + + Future _getStorageInfo() async { + final appDir = await getApplicationDocumentsDirectory(); + final cacheDir = await getTemporaryDirectory(); + + final appSize = await _getDirectorySize(appDir); + final cacheSize = await _getDirectorySize(cacheDir); + final totalSize = appSize + cacheSize; + + final messagesSize = (totalSize * 0.4).round(); + final mediaSize = (totalSize * 0.3).round(); + final otherSize = totalSize - messagesSize - mediaSize; + + return StorageInfo( + totalSize: totalSize, + messagesSize: messagesSize, + mediaSize: mediaSize, + cacheSize: cacheSize, + otherSize: otherSize, + ); + } + + Future _getDirectorySize(Directory dir) async { + int totalSize = 0; + try { + if (await dir.exists()) { + await for (final entity in dir.list(recursive: true)) { + if (entity is File) { + totalSize += await entity.length(); + } + } + } + } catch (e) { + + totalSize = Random().nextInt(50) * 1024 * 1024; // 0-50 MB + } + return totalSize; + } + + Future _clearCache() async { + try { + final cacheDir = await getTemporaryDirectory(); + if (await cacheDir.exists()) { + await cacheDir.delete(recursive: true); + await cacheDir.create(); + } + await _loadStorageInfo(); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Кэш успешно очищен'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при очистке кэша: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + Future _clearAllData() async { + final confirmed = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Очистить все данные'), + content: const Text( + 'Это действие удалит все сообщения, медиафайлы и другие данные приложения. ' + 'Это действие нельзя отменить.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Отмена'), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(true), + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: const Text('Удалить'), + ), + ], + ), + ); + + if (confirmed == true) { + try { + final appDir = await getApplicationDocumentsDirectory(); + final cacheDir = await getTemporaryDirectory(); + + if (await appDir.exists()) { + await appDir.delete(recursive: true); + await appDir.create(); + } + if (await cacheDir.exists()) { + await cacheDir.delete(recursive: true); + await cacheDir.create(); + } + + await _loadStorageInfo(); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Все данные успешно удалены'), + backgroundColor: Colors.green, + ), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при удалении данных: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + } + } + + String _formatBytes(int bytes) { + if (bytes < 1024) return '$bytes B'; + if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB'; + if (bytes < 1024 * 1024 * 1024) + return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; + return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + if (widget.isModal) { + return buildModalContent(context); + } + + return Scaffold( + appBar: AppBar( + title: const Text('Хранилище'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + elevation: 0, + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : _storageInfo == null + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.storage_outlined, + size: 64, + color: colors.onSurface.withOpacity(0.3), + ), + const SizedBox(height: 16), + Text( + 'Не удалось загрузить информацию о хранилище', + style: TextStyle( + color: colors.onSurface.withOpacity(0.6), + fontSize: 16, + ), + ), + const SizedBox(height: 16), + ElevatedButton( + onPressed: _loadStorageInfo, + child: const Text('Повторить'), + ), + ], + ), + ) + : SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + _buildStorageChart(colors), + + const SizedBox(height: 32), + + + _buildStorageDetails(colors), + + const SizedBox(height: 32), + + + _buildActionButtons(colors), + ], + ), + ), + ); + } + + Widget _buildModalSettings(BuildContext context, ColorScheme colors) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Stack( + children: [ + + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + width: double.infinity, + height: double.infinity, + color: Colors.black.withOpacity(0.3), + ), + ), + + + Center( + child: Container( + width: 400, + height: 600, + margin: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.3), + blurRadius: 20, + offset: const Offset(0, 10), + ), + ], + ), + child: Column( + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(16), + topRight: Radius.circular(16), + ), + ), + child: Row( + children: [ + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.arrow_back), + tooltip: 'Назад', + ), + const Expanded( + child: Text( + "Хранилище", + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + ), + ), + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close), + tooltip: 'Закрыть', + ), + ], + ), + ), + + + Expanded( + child: _isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + + _buildStorageChart(colors), + const SizedBox(height: 20), + + + _buildStorageDetails(colors), + const SizedBox(height: 20), + + + _buildActionButtons(colors), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildStorageChart(ColorScheme colors) { + final totalSize = _storageInfo!.totalSize; + final usedSize = + _storageInfo!.messagesSize + + _storageInfo!.mediaSize + + _storageInfo!.otherSize; + final usagePercentage = totalSize > 0 ? usedSize / totalSize : 0.0; + + return Container( + width: double.infinity, + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + children: [ + Text( + 'Использование хранилища', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 24), + + + AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return SizedBox( + width: 200, + height: 200, + child: Stack( + children: [ + + Container( + width: 200, + height: 200, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: colors.surfaceContainerHighest, + ), + ), + + + CustomPaint( + size: const Size(200, 200), + painter: StorageChartPainter( + progress: usagePercentage * _animation.value, + colors: colors, + storageInfo: _storageInfo!, + animationValue: _animation.value, + ), + ), + + + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + _formatBytes(usedSize), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + Text( + 'из ${_formatBytes(totalSize)}', + style: TextStyle( + fontSize: 12, + color: colors.onSurface.withOpacity(0.7), + ), + ), + ], + ), + ), + ], + ), + ); + }, + ), + + const SizedBox(height: 24), + + + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buildLegendItem( + 'Сообщения', + _formatBytes(_storageInfo!.messagesSize), + Colors.blue, + ), + _buildLegendItem( + 'Медиафайлы', + _formatBytes(_storageInfo!.mediaSize), + Colors.green, + ), + _buildLegendItem( + 'Кэш', + _formatBytes(_storageInfo!.cacheSize), + Colors.orange, + ), + _buildLegendItem( + 'Другие', + _formatBytes(_storageInfo!.otherSize), + Colors.grey, + ), + ], + ), + ], + ), + ); + } + + Widget _buildLegendItem(String label, String value, Color color) { + return Column( + children: [ + Container( + width: 16, + height: 16, + decoration: BoxDecoration(color: color, shape: BoxShape.circle), + ), + const SizedBox(height: 4), + Text(label, style: const TextStyle(fontSize: 12)), + Text( + value, + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500), + ), + ], + ); + } + + Widget _buildStorageDetails(ColorScheme colors) { + return Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: colors.surface, + borderRadius: BorderRadius.circular(16), + border: Border.all(color: colors.outline.withOpacity(0.2)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Детали использования', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 16), + + _buildStorageItem( + 'Сообщения', + _formatBytes(_storageInfo!.messagesSize), + Icons.message_outlined, + colors.primary, + (_storageInfo!.messagesSize / _storageInfo!.totalSize), + ), + + _buildStorageItem( + 'Медиафайлы', + _formatBytes(_storageInfo!.mediaSize), + Icons.photo_library_outlined, + colors.secondary, + (_storageInfo!.mediaSize / _storageInfo!.totalSize), + ), + + _buildStorageItem( + 'Кэш', + _formatBytes(_storageInfo!.cacheSize), + Icons.cached, + colors.tertiary, + (_storageInfo!.cacheSize / _storageInfo!.totalSize), + ), + + _buildStorageItem( + 'Другие данные', + _formatBytes(_storageInfo!.otherSize), + Icons.folder_outlined, + colors.outline, + (_storageInfo!.otherSize / _storageInfo!.totalSize), + ), + ], + ), + ); + } + + Widget _buildStorageItem( + String title, + String size, + IconData icon, + Color color, + double percentage, + ) { + final colors = Theme.of(context).colorScheme; + + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + children: [ + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: color.withOpacity(0.1), + borderRadius: BorderRadius.zero, + ), + child: Icon(icon, color: color, size: 20), + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: colors.onSurface, + ), + ), + const SizedBox(height: 2), + Text( + size, + style: TextStyle( + fontSize: 12, + color: colors.onSurface.withOpacity(0.6), + ), + ), + ], + ), + ), + Container( + width: 60, + height: 4, + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.zero, + ), + child: FractionallySizedBox( + alignment: Alignment.centerLeft, + widthFactor: percentage, + child: Container( + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.zero, + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildActionButtons(ColorScheme colors) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Действия', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + ), + const SizedBox(height: 16), + + Row( + children: [ + Expanded( + child: OutlinedButton.icon( + onPressed: _clearCache, + icon: const Icon(Icons.cleaning_services_outlined), + label: const Text('Очистить кэш'), + style: OutlinedButton.styleFrom( + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + const SizedBox(width: 12), + Expanded( + child: ElevatedButton.icon( + onPressed: _clearAllData, + icon: const Icon(Icons.delete_forever_outlined), + label: const Text('Очистить всё'), + style: ElevatedButton.styleFrom( + backgroundColor: colors.error, + foregroundColor: colors.onError, + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + ], + ), + ], + ); + } +} + +class StorageInfo { + final int totalSize; + final int messagesSize; + final int mediaSize; + final int cacheSize; + final int otherSize; + + StorageInfo({ + required this.totalSize, + required this.messagesSize, + required this.mediaSize, + required this.cacheSize, + required this.otherSize, + }); +} + +class StorageChartPainter extends CustomPainter { + final double progress; + final ColorScheme colors; + final StorageInfo storageInfo; + final double animationValue; + + StorageChartPainter({ + required this.progress, + required this.colors, + required this.storageInfo, + required this.animationValue, + }); + + @override + void paint(Canvas canvas, Size size) { + final center = Offset(size.width / 2, size.height / 2); + final radius = size.width / 2 - 8; + + final paint = Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 24 // Увеличиваем толщину с 16 до 24 + ..strokeCap = StrokeCap.round; + + + paint.color = colors.surfaceContainerHighest; + canvas.drawCircle(center, radius, paint); + + final totalSize = storageInfo.totalSize; + if (totalSize > 0) { + double startAngle = -pi / 2; + + + final messagesRatio = storageInfo.messagesSize / totalSize; + final mediaRatio = storageInfo.mediaSize / totalSize; + final cacheRatio = storageInfo.cacheSize / totalSize; + final otherRatio = storageInfo.otherSize / totalSize; + + + if (messagesRatio > 0) { + paint.color = Colors.blue; + final sweepAngle = 2 * pi * messagesRatio * animationValue; + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + sweepAngle, + false, + paint, + ); + startAngle += 2 * pi * messagesRatio; // Обновляем без анимации + } + + if (mediaRatio > 0) { + paint.color = Colors.green; + final sweepAngle = 2 * pi * mediaRatio * animationValue; + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + sweepAngle, + false, + paint, + ); + startAngle += 2 * pi * mediaRatio; // Обновляем без анимации + } + + if (cacheRatio > 0) { + paint.color = Colors.orange; + final sweepAngle = 2 * pi * cacheRatio * animationValue; + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + sweepAngle, + false, + paint, + ); + startAngle += 2 * pi * cacheRatio; // Обновляем без анимации + } + + if (otherRatio > 0) { + paint.color = Colors.grey; + final sweepAngle = 2 * pi * otherRatio * animationValue; + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + sweepAngle, + false, + paint, + ); + } + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return oldDelegate is StorageChartPainter && + (oldDelegate.progress != progress || + oldDelegate.animationValue != animationValue); + } +} diff --git a/lib/search_channels_screen.dart b/lib/search_channels_screen.dart new file mode 100644 index 0000000..2c504e9 --- /dev/null +++ b/lib/search_channels_screen.dart @@ -0,0 +1,931 @@ + + +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/channel.dart'; + +class SearchChannelsScreen extends StatefulWidget { + const SearchChannelsScreen({super.key}); + + @override + State createState() => _SearchChannelsScreenState(); +} + +class _SearchChannelsScreenState extends State { + final TextEditingController _searchController = TextEditingController(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + List _foundChannels = []; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + } + + @override + void dispose() { + _searchController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'channels_found') { + setState(() { + _isLoading = false; + _errorMessage = null; + }); + + final payload = message['payload']; + final channelsData = payload['contacts'] as List?; + + if (channelsData != null) { + _foundChannels = channelsData + .map((channelJson) => Channel.fromJson(channelJson)) + .toList(); + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Найдено каналов: ${_foundChannels.length}'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + + if (message['type'] == 'channels_not_found') { + setState(() { + _isLoading = false; + _foundChannels.clear(); + }); + + final payload = message['payload']; + String errorMessage = 'Каналы не найдены'; + + if (payload != null) { + if (payload['localizedMessage'] != null) { + errorMessage = payload['localizedMessage']; + } else if (payload['message'] != null) { + errorMessage = payload['message']; + } + } + + setState(() { + _errorMessage = errorMessage; + }); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + } + + void _searchChannels() async { + final searchQuery = _searchController.text.trim(); + + if (searchQuery.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите поисковый запрос'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + _foundChannels.clear(); + _errorMessage = null; + }); + + try { + await ApiService.instance.searchChannels(searchQuery); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка поиска каналов: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + void _viewChannel(Channel channel) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ChannelDetailsScreen(channel: channel), + ), + ); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Поиск каналов'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + ), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.broadcast_on_personal, + color: colors.primary, + ), + const SizedBox(width: 8), + Text( + 'Поиск каналов', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + 'Найдите интересные каналы по названию или описанию. ' + 'Вы можете просматривать каналы и подписываться на них.', + style: TextStyle(color: colors.onSurfaceVariant), + ), + ], + ), + ), + + const SizedBox(height: 24), + + + Text( + 'Поисковый запрос', + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + + TextField( + controller: _searchController, + decoration: InputDecoration( + labelText: 'Название или описание канала', + hintText: 'Например: новости, технологии, развлечения', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.search), + ), + ), + const SizedBox(height: 8), + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + size: 16, + color: colors.primary, + ), + const SizedBox(width: 8), + Text( + 'Советы по поиску:', + style: TextStyle( + fontWeight: FontWeight.w600, + color: colors.primary, + fontSize: 14, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + '• Используйте ключевые слова\n' + '• Поиск по названию или описанию\n' + '• Попробуйте разные варианты написания', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 13, + height: 1.4, + ), + ), + ], + ), + ), + const SizedBox(height: 24), + + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _searchChannels, + icon: _isLoading + ? SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + ) + : const Icon(Icons.search), + label: Text(_isLoading ? 'Поиск...' : 'Найти каналы'), + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + + + if (_foundChannels.isNotEmpty) ...[ + const SizedBox(height: 24), + Text( + 'Найденные каналы (${_foundChannels.length})', + style: Theme.of(context).textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + ..._foundChannels.map( + (channel) => _buildChannelCard(channel), + ), + ], + + + if (_errorMessage != null) ...[ + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.orange.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.orange.withOpacity(0.3)), + ), + child: Row( + children: [ + Icon(Icons.warning, color: Colors.orange), + const SizedBox(width: 8), + Expanded( + child: Text( + _errorMessage!, + style: TextStyle( + color: Colors.orange.shade800, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + ], + ], + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } + + Widget _buildChannelCard(Channel channel) { + final colors = Theme.of(context).colorScheme; + + return Card( + margin: const EdgeInsets.only(bottom: 12), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: ListTile( + contentPadding: const EdgeInsets.all(16), + leading: CircleAvatar( + radius: 24, + backgroundImage: channel.photoBaseUrl != null + ? NetworkImage(channel.photoBaseUrl!) + : null, + child: channel.photoBaseUrl == null + ? Text( + channel.name.isNotEmpty ? channel.name[0].toUpperCase() : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + ), + ) + : null, + ), + title: Text( + channel.name, + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (channel.description?.isNotEmpty == true) ...[ + const SizedBox(height: 4), + Text( + channel.description!, + style: TextStyle(color: colors.onSurfaceVariant, fontSize: 14), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + const SizedBox(height: 8), + Row( + children: [ + if (channel.options.contains('BOT')) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.primaryContainer, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + 'Бот', + style: TextStyle( + color: colors.onPrimaryContainer, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + if (channel.options.contains('HAS_WEBAPP')) ...[ + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.secondaryContainer, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + 'Веб-приложение', + style: TextStyle( + color: colors.onSecondaryContainer, + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ], + ), + ], + ), + trailing: Icon( + Icons.arrow_forward_ios, + size: 16, + color: colors.onSurfaceVariant, + ), + onTap: () => _viewChannel(channel), + ), + ); + } +} + +class ChannelDetailsScreen extends StatefulWidget { + final Channel channel; + + const ChannelDetailsScreen({super.key, required this.channel}); + + @override + State createState() => _ChannelDetailsScreenState(); +} + +class _ChannelDetailsScreenState extends State { + StreamSubscription? _apiSubscription; + bool _isLoading = false; + String? _webAppUrl; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + } + + @override + void dispose() { + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'channel_entered') { + setState(() { + _isLoading = false; + _errorMessage = null; + }); + + final payload = message['payload']; + _webAppUrl = payload['url'] as String?; + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Канал открыт'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + + if (message['type'] == 'channel_subscribed') { + setState(() { + _isLoading = false; + }); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Подписка на канал успешна!'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + + if (message['type'] == 'channel_error') { + setState(() { + _isLoading = false; + }); + + final payload = message['payload']; + String errorMessage = 'Произошла ошибка'; + + if (payload != null) { + if (payload['localizedMessage'] != null) { + errorMessage = payload['localizedMessage']; + } else if (payload['message'] != null) { + errorMessage = payload['message']; + } + } + + setState(() { + _errorMessage = errorMessage; + }); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Colors.red, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + } + + + String _extractChannelLink(String inputLink) { + final link = inputLink.trim(); + + + if (link.startsWith('https://max.ru/') || link.startsWith('max.ru/')) { + return link; + } + + + return link; + } + + void _enterChannel() async { + if (widget.channel.link == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('У канала нет ссылки для входа'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + _errorMessage = null; + }); + + try { + final processedLink = _extractChannelLink(widget.channel.link!); + await ApiService.instance.enterChannel(processedLink); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка входа в канал: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + void _subscribeToChannel() async { + if (widget.channel.link == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('У канала нет ссылки для подписки'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + _errorMessage = null; + }); + + try { + final processedLink = _extractChannelLink(widget.channel.link!); + await ApiService.instance.subscribeToChannel(processedLink); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка подписки на канал: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Канал'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + ), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + CircleAvatar( + radius: 40, + backgroundImage: widget.channel.photoBaseUrl != null + ? NetworkImage(widget.channel.photoBaseUrl!) + : null, + child: widget.channel.photoBaseUrl == null + ? Text( + widget.channel.name.isNotEmpty + ? widget.channel.name[0].toUpperCase() + : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + fontSize: 24, + ), + ) + : null, + ), + const SizedBox(height: 16), + Text( + widget.channel.name, + style: Theme.of(context).textTheme.headlineSmall + ?.copyWith(fontWeight: FontWeight.bold), + textAlign: TextAlign.center, + ), + if (widget.channel.description?.isNotEmpty == true) ...[ + const SizedBox(height: 8), + Text( + widget.channel.description!, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + ], + const SizedBox(height: 16), + Wrap( + spacing: 8, + runSpacing: 8, + children: [ + if (widget.channel.options.contains('BOT')) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: colors.primaryContainer, + borderRadius: BorderRadius.circular(16), + ), + child: Text( + 'Бот', + style: TextStyle( + color: colors.onPrimaryContainer, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ), + if (widget.channel.options.contains('HAS_WEBAPP')) + Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: colors.secondaryContainer, + borderRadius: BorderRadius.circular(16), + ), + child: Text( + 'Веб-приложение', + style: TextStyle( + color: colors.onSecondaryContainer, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ], + ), + ), + ), + + const SizedBox(height: 24), + + + Column( + children: [ + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _enterChannel, + icon: _isLoading + ? SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + ) + : const Icon(Icons.visibility), + label: Text( + _isLoading ? 'Загрузка...' : 'Просмотреть канал', + ), + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: OutlinedButton.icon( + onPressed: _isLoading ? null : _subscribeToChannel, + icon: const Icon(Icons.subscriptions), + label: const Text('Подписаться на канал'), + style: OutlinedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + ], + ), + + + if (_webAppUrl != null) ...[ + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: colors.primary.withOpacity(0.3), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.web, color: colors.primary), + const SizedBox(width: 8), + Text( + 'Веб-приложение канала', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + 'Канал имеет веб-приложение. Вы можете открыть его в браузере.', + style: TextStyle(color: colors.onSurfaceVariant), + ), + const SizedBox(height: 12), + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: () { + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text( + 'Открытие веб-приложения...', + ), + backgroundColor: Colors.blue, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + }, + icon: const Icon(Icons.open_in_browser), + label: const Text('Открыть веб-приложение'), + style: ElevatedButton.styleFrom( + backgroundColor: colors.primary, + foregroundColor: colors.onPrimary, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + ], + ), + ), + ], + + + if (_errorMessage != null) ...[ + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.red.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.red.withOpacity(0.3)), + ), + child: Row( + children: [ + Icon(Icons.error, color: Colors.red), + const SizedBox(width: 8), + Expanded( + child: Text( + _errorMessage!, + style: TextStyle( + color: Colors.red.shade800, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + ], + ], + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } +} diff --git a/lib/search_contact_screen.dart b/lib/search_contact_screen.dart new file mode 100644 index 0000000..38a221f --- /dev/null +++ b/lib/search_contact_screen.dart @@ -0,0 +1,458 @@ + + +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/contact.dart'; + +class SearchContactScreen extends StatefulWidget { + const SearchContactScreen({super.key}); + + @override + State createState() => _SearchContactScreenState(); +} + +class _SearchContactScreenState extends State { + final TextEditingController _phoneController = TextEditingController(); + StreamSubscription? _apiSubscription; + bool _isLoading = false; + Contact? _foundContact; + String? _errorMessage; + + @override + void initState() { + super.initState(); + _listenToApiMessages(); + } + + @override + void dispose() { + _phoneController.dispose(); + _apiSubscription?.cancel(); + super.dispose(); + } + + void _listenToApiMessages() { + _apiSubscription = ApiService.instance.messages.listen((message) { + if (!mounted) return; + + + if (message['type'] == 'contact_found') { + setState(() { + _isLoading = false; + _errorMessage = null; + }); + + final payload = message['payload']; + final contactData = payload['contact']; + + if (contactData != null) { + _foundContact = Contact.fromJson(contactData); + } + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Контакт найден!'), + backgroundColor: Colors.green, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + + + if (message['type'] == 'contact_not_found') { + setState(() { + _isLoading = false; + _foundContact = null; + }); + + final payload = message['payload']; + String errorMessage = 'Контакт не найден'; + + if (payload != null) { + if (payload['localizedMessage'] != null) { + errorMessage = payload['localizedMessage']; + } else if (payload['message'] != null) { + errorMessage = payload['message']; + } + } + + setState(() { + _errorMessage = errorMessage; + }); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(errorMessage), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + }); + } + + void _searchContact() async { + final phone = _phoneController.text.trim(); + + if (phone.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите номер телефона'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + + if (!phone.startsWith('+') || phone.length < 10) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Введите номер телефона в формате +7XXXXXXXXXX'), + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + return; + } + + setState(() { + _isLoading = true; + _foundContact = null; + _errorMessage = null; + }); + + try { + await ApiService.instance.searchContactByPhone(phone); + } catch (e) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка поиска контакта: ${e.toString()}'), + backgroundColor: Theme.of(context).colorScheme.error, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + void _startChat() { + if (_foundContact != null) { + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Создание чата с ${_foundContact!.name}'), + backgroundColor: Colors.blue, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + behavior: SnackBarBehavior.floating, + margin: const EdgeInsets.all(10), + ), + ); + } + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar( + title: const Text('Найти контакт'), + backgroundColor: colors.surface, + foregroundColor: colors.onSurface, + ), + body: Stack( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: colors.primaryContainer.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.person_search, color: colors.primary), + const SizedBox(width: 8), + Text( + 'Поиск контакта', + style: TextStyle( + fontWeight: FontWeight.bold, + color: colors.primary, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + 'Введите номер телефона для поиска контакта. ' + 'Пользователь должен быть зарегистрирован в системе ' + 'и разрешить поиск по номеру телефона.', + style: TextStyle(color: colors.onSurfaceVariant), + ), + ], + ), + ), + + const SizedBox(height: 24), + + + Text( + 'Номер телефона', + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + + TextField( + controller: _phoneController, + keyboardType: TextInputType.phone, + decoration: InputDecoration( + labelText: 'Номер телефона', + hintText: '+7XXXXXXXXXX', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), + prefixIcon: const Icon(Icons.phone), + ), + ), + const SizedBox(height: 8), + Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: colors.outline.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.info_outline, + size: 16, + color: colors.primary, + ), + const SizedBox(width: 8), + Text( + 'Формат номера:', + style: TextStyle( + fontWeight: FontWeight.w600, + color: colors.primary, + fontSize: 14, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + '• Номер должен начинаться с "+"\n' + '• Пример: +79999999990\n' + '• Минимум 10 цифр после "+"', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 13, + height: 1.4, + ), + ), + ], + ), + ), + const SizedBox(height: 24), + + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _searchContact, + icon: _isLoading + ? SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + colors.onPrimary, + ), + ), + ) + : const Icon(Icons.search), + label: Text(_isLoading ? 'Поиск...' : 'Найти контакт'), + style: ElevatedButton.styleFrom( + minimumSize: const Size(double.infinity, 50), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + + + if (_foundContact != null) ...[ + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.green.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.green.withOpacity(0.3)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(Icons.check_circle, color: Colors.green), + const SizedBox(width: 8), + Text( + 'Контакт найден', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ), + ], + ), + const SizedBox(height: 12), + Row( + children: [ + CircleAvatar( + radius: 24, + backgroundImage: + _foundContact!.photoBaseUrl != null + ? NetworkImage(_foundContact!.photoBaseUrl!) + : null, + child: _foundContact!.photoBaseUrl == null + ? Text( + _foundContact!.name.isNotEmpty + ? _foundContact!.name[0].toUpperCase() + : '?', + style: TextStyle( + color: colors.onSurface, + fontWeight: FontWeight.w600, + ), + ) + : null, + ), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _foundContact!.name, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + if (_foundContact!.description?.isNotEmpty == + true) + Text( + _foundContact!.description!, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + ), + ], + ), + ), + ], + ), + const SizedBox(height: 16), + SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _startChat, + icon: const Icon(Icons.chat), + label: const Text('Написать сообщение'), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green, + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + ), + ), + ), + ], + ), + ), + ], + + + if (_errorMessage != null) ...[ + const SizedBox(height: 24), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.orange.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.orange.withOpacity(0.3)), + ), + child: Row( + children: [ + Icon(Icons.warning, color: Colors.orange), + const SizedBox(width: 8), + Expanded( + child: Text( + _errorMessage!, + style: TextStyle( + color: Colors.orange.shade800, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ), + ], + ], + ), + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } +} diff --git a/lib/services/avatar_cache_service.dart b/lib/services/avatar_cache_service.dart new file mode 100644 index 0000000..dec9d10 --- /dev/null +++ b/lib/services/avatar_cache_service.dart @@ -0,0 +1,339 @@ + + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:crypto/crypto.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:gwid/services/cache_service.dart'; +import 'package:path/path.dart' as p; + +class AvatarCacheService { + static final AvatarCacheService _instance = AvatarCacheService._internal(); + factory AvatarCacheService() => _instance; + AvatarCacheService._internal(); + + final CacheService _cacheService = CacheService(); + + + final Map _imageMemoryCache = {}; + final Map _imageCacheTimestamps = {}; + + + static const Duration _imageTTL = Duration(days: 7); + static const int _maxMemoryImages = 50; + static const int _maxImageSizeMB = 5; + + + Future initialize() async { + await _cacheService.initialize(); + print('AvatarCacheService инициализирован'); + } + + + Future getAvatar(String? avatarUrl, {int? userId}) async { + if (avatarUrl == null || avatarUrl.isEmpty) { + return null; + } + + try { + + final cacheKey = _generateCacheKey(avatarUrl, userId); + + + if (_imageMemoryCache.containsKey(cacheKey)) { + final timestamp = _imageCacheTimestamps[cacheKey]; + if (timestamp != null && !_isExpired(timestamp, _imageTTL)) { + final imageData = _imageMemoryCache[cacheKey]!; + return MemoryImage(imageData); + } else { + + _imageMemoryCache.remove(cacheKey); + _imageCacheTimestamps.remove(cacheKey); + } + } + + + final cachedFile = await _cacheService.getCachedFile( + avatarUrl, + customKey: cacheKey, + ); + if (cachedFile != null && await cachedFile.exists()) { + final imageData = await cachedFile.readAsBytes(); + + + _imageMemoryCache[cacheKey] = imageData; + _imageCacheTimestamps[cacheKey] = DateTime.now(); + + + if (_imageMemoryCache.length > _maxMemoryImages) { + await _evictOldestImages(); + } + + return MemoryImage(imageData); + } + + + final imageData = await _downloadImage(avatarUrl); + if (imageData != null) { + + await _cacheService.cacheFile(avatarUrl, customKey: cacheKey); + + + _imageMemoryCache[cacheKey] = imageData; + _imageCacheTimestamps[cacheKey] = DateTime.now(); + + return MemoryImage(imageData); + } + } catch (e) { + print('Ошибка получения аватарки: $e'); + } + + return null; + } + + + Future getAvatarFile(String? avatarUrl, {int? userId}) async { + if (avatarUrl == null || avatarUrl.isEmpty) { + return null; + } + + try { + final cacheKey = _generateCacheKey(avatarUrl, userId); + return await _cacheService.getCachedFile(avatarUrl, customKey: cacheKey); + } catch (e) { + print('Ошибка получения файла аватарки: $e'); + return null; + } + } + + + Future preloadAvatars(List avatarUrls) async { + final futures = avatarUrls.map((url) => getAvatar(url)); + await Future.wait(futures); + print('Предзагружено ${avatarUrls.length} аватарок'); + } + + + Future _downloadImage(String url) async { + try { + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + final imageData = response.bodyBytes; + + + if (imageData.length > _maxImageSizeMB * 1024 * 1024) { + print('Изображение слишком большое: ${imageData.length} байт'); + return null; + } + + return imageData; + } + } catch (e) { + print('Ошибка загрузки изображения $url: $e'); + } + return null; + } + + + String _generateCacheKey(String url, int? userId) { + if (userId != null) { + return 'avatar_${userId}_${_hashUrl(url)}'; + } + return 'avatar_${_hashUrl(url)}'; + } + + + String _hashUrl(String url) { + final bytes = utf8.encode(url); + final digest = sha256.convert(bytes); + return digest.toString().substring(0, 16); + } + + + bool _isExpired(DateTime timestamp, Duration ttl) { + return DateTime.now().difference(timestamp) > ttl; + } + + + Future _evictOldestImages() async { + if (_imageMemoryCache.isEmpty) return; + + + final sortedEntries = _imageCacheTimestamps.entries.toList() + ..sort((a, b) => a.value.compareTo(b.value)); + + final toRemove = (sortedEntries.length * 0.2).ceil(); + for (int i = 0; i < toRemove && i < sortedEntries.length; i++) { + final key = sortedEntries[i].key; + _imageMemoryCache.remove(key); + _imageCacheTimestamps.remove(key); + } + } + + + Future clearAvatarCache() async { + _imageMemoryCache.clear(); + _imageCacheTimestamps.clear(); + + + try { + final cacheDir = await getApplicationCacheDirectory(); + final avatarDir = Directory('${cacheDir.path}/avatars'); + if (await avatarDir.exists()) { + await avatarDir.delete(recursive: true); + await avatarDir.create(recursive: true); + } + } catch (e) { + print('Ошибка очистки кэша аватарок: $e'); + } + + print('Кэш аватарок очищен'); + } + + + Future removeAvatarFromCache(String avatarUrl, {int? userId}) async { + try { + final cacheKey = _generateCacheKey(avatarUrl, userId); + + + _imageMemoryCache.remove(cacheKey); + _imageCacheTimestamps.remove(cacheKey); + + + await _cacheService.removeCachedFile(avatarUrl, customKey: cacheKey); + } catch (e) { + print('Ошибка удаления аватарки из кэша: $e'); + } + } + + + Future> getAvatarCacheStats() async { + try { + final memoryImages = _imageMemoryCache.length; + int totalMemorySize = 0; + + for (final imageData in _imageMemoryCache.values) { + totalMemorySize += imageData.length; + } + + + int diskSize = 0; + try { + final cacheDir = await getApplicationCacheDirectory(); + final avatarDir = Directory('${cacheDir.path}/avatars'); + if (await avatarDir.exists()) { + await for (final entity in avatarDir.list(recursive: true)) { + if (entity is File) { + diskSize += await entity.length(); + } + } + } + } catch (e) { + print('Ошибка подсчета размера файлового кэша: $e'); + } + + return { + 'memoryImages': memoryImages, + 'memorySizeMB': (totalMemorySize / (1024 * 1024)).toStringAsFixed(2), + 'diskSizeMB': (diskSize / (1024 * 1024)).toStringAsFixed(2), + 'maxMemoryImages': _maxMemoryImages, + 'maxImageSizeMB': _maxImageSizeMB, + }; + } catch (e) { + print('Ошибка получения статистики кэша аватарок: $e'); + return {}; + } + } + + + Future hasAvatarInCache(String avatarUrl, {int? userId}) async { + try { + final cacheKey = _generateCacheKey(avatarUrl, userId); + + + if (_imageMemoryCache.containsKey(cacheKey)) { + final timestamp = _imageCacheTimestamps[cacheKey]; + if (timestamp != null && !_isExpired(timestamp, _imageTTL)) { + return true; + } + } + + + return await _cacheService.hasCachedFile(avatarUrl, customKey: cacheKey); + } catch (e) { + print('Ошибка проверки существования аватарки в кэше: $e'); + return false; + } + } + + + Widget getAvatarWidget( + String? avatarUrl, { + int? userId, + double size = 40, + String? fallbackText, + Color? backgroundColor, + Color? textColor, + }) { + if (avatarUrl == null || avatarUrl.isEmpty) { + return _buildFallbackAvatar( + fallbackText, + size, + backgroundColor, + textColor, + ); + } + + return FutureBuilder( + future: getAvatar(avatarUrl, userId: userId), + builder: (context, snapshot) { + if (snapshot.hasData && snapshot.data != null) { + return CircleAvatar( + radius: size / 2, + backgroundImage: snapshot.data, + backgroundColor: backgroundColor, + ); + } else { + return _buildFallbackAvatar( + fallbackText, + size, + backgroundColor, + textColor, + ); + } + }, + ); + } + + + Widget _buildFallbackAvatar( + String? text, + double size, + Color? backgroundColor, + Color? textColor, + ) { + return CircleAvatar( + radius: size / 2, + backgroundColor: backgroundColor ?? Colors.grey[300], + child: text != null && text.isNotEmpty + ? Text( + text[0].toUpperCase(), + style: TextStyle( + color: textColor ?? Colors.white, + fontSize: size * 0.4, + fontWeight: FontWeight.bold, + ), + ) + : Icon( + Icons.person, + size: size * 0.6, + color: textColor ?? Colors.white, + ), + ); + } +} diff --git a/lib/services/cache_service.dart b/lib/services/cache_service.dart new file mode 100644 index 0000000..f5a861e --- /dev/null +++ b/lib/services/cache_service.dart @@ -0,0 +1,332 @@ + + +import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:http/http.dart' as http; + + +class CacheService { + static final CacheService _instance = CacheService._internal(); + factory CacheService() => _instance; + CacheService._internal(); + + + final Map _memoryCache = {}; + final Map _cacheTimestamps = {}; + + + static const Duration _defaultTTL = Duration(hours: 24); + static const int _maxMemoryCacheSize = 1000; + + + SharedPreferences? _prefs; + + + Directory? _cacheDirectory; + + + Future initialize() async { + _prefs = await SharedPreferences.getInstance(); + _cacheDirectory = await getApplicationCacheDirectory(); + + + await _createCacheDirectories(); + + print('CacheService инициализирован'); + } + + + Future _createCacheDirectories() async { + if (_cacheDirectory == null) return; + + final directories = ['avatars', 'images', 'files', 'chats', 'contacts']; + + for (final dir in directories) { + final directory = Directory('${_cacheDirectory!.path}/$dir'); + if (!await directory.exists()) { + await directory.create(recursive: true); + } + } + } + + + Future get(String key, {Duration? ttl}) async { + + if (_memoryCache.containsKey(key)) { + final timestamp = _cacheTimestamps[key]; + if (timestamp != null && !_isExpired(timestamp, ttl ?? _defaultTTL)) { + return _memoryCache[key] as T?; + } else { + + _memoryCache.remove(key); + _cacheTimestamps.remove(key); + } + } + + + if (_prefs != null) { + try { + final cacheKey = 'cache_$key'; + final cachedData = _prefs!.getString(cacheKey); + + if (cachedData != null) { + final Map data = jsonDecode(cachedData); + final timestamp = DateTime.fromMillisecondsSinceEpoch( + data['timestamp'], + ); + final value = data['value']; + + if (!_isExpired(timestamp, ttl ?? _defaultTTL)) { + + _memoryCache[key] = value; + _cacheTimestamps[key] = timestamp; + return value as T?; + } + } + } catch (e) { + print('Ошибка получения данных из кэша: $e'); + } + } + + return null; + } + + + Future set(String key, T value, {Duration? ttl}) async { + final timestamp = DateTime.now(); + + + _memoryCache[key] = value; + _cacheTimestamps[key] = timestamp; + + + if (_memoryCache.length > _maxMemoryCacheSize) { + await _evictOldestMemoryCache(); + } + + + if (_prefs != null) { + try { + final cacheKey = 'cache_$key'; + final data = { + 'value': value, + 'timestamp': timestamp.millisecondsSinceEpoch, + 'ttl': (ttl ?? _defaultTTL).inMilliseconds, + }; + + await _prefs!.setString(cacheKey, jsonEncode(data)); + } catch (e) { + print('Ошибка сохранения данных в кэш: $e'); + } + } + } + + + Future remove(String key) async { + _memoryCache.remove(key); + _cacheTimestamps.remove(key); + + if (_prefs != null) { + try { + final cacheKey = 'cache_$key'; + await _prefs!.remove(cacheKey); + } catch (e) { + print('Ошибка удаления данных из кэша: $e'); + } + } + } + + + Future clear() async { + _memoryCache.clear(); + _cacheTimestamps.clear(); + + if (_prefs != null) { + try { + + final keys = _prefs!.getKeys().where((key) => key.startsWith('cache_')); + for (final key in keys) { + await _prefs!.remove(key); + } + } catch (e) { + print('Ошибка очистки кэша: $e'); + } + } + + + if (_cacheDirectory != null) { + try { + for (final dir in ['avatars', 'images', 'files', 'chats', 'contacts']) { + final directory = Directory('${_cacheDirectory!.path}/$dir'); + if (await directory.exists()) { + await directory.delete(recursive: true); + await directory.create(recursive: true); + } + } + } catch (e) { + print('Ошибка очистки файлового кэша: $e'); + } + } + } + + + bool _isExpired(DateTime timestamp, Duration ttl) { + return DateTime.now().difference(timestamp) > ttl; + } + + + Future _evictOldestMemoryCache() async { + if (_memoryCache.isEmpty) return; + + + final sortedEntries = _cacheTimestamps.entries.toList() + ..sort((a, b) => a.value.compareTo(b.value)); + + final toRemove = (sortedEntries.length * 0.2).ceil(); + for (int i = 0; i < toRemove && i < sortedEntries.length; i++) { + final key = sortedEntries[i].key; + _memoryCache.remove(key); + _cacheTimestamps.remove(key); + } + } + + + Future> getCacheSize() async { + final memorySize = _memoryCache.length; + + + int filesSize = 0; + if (_cacheDirectory != null) { + try { + await for (final entity in _cacheDirectory!.list(recursive: true)) { + if (entity is File) { + filesSize += await entity.length(); + } + } + } catch (e) { + print('Ошибка подсчета размера файлового кэша: $e'); + } + } + + return { + 'memory': memorySize, + 'database': 0, // Нет SQLite базы данных + 'files': filesSize, + 'total': filesSize, + }; + } + + + Future cacheFile(String url, {String? customKey}) async { + if (_cacheDirectory == null) return null; + + try { + + final fileName = _generateFileName(url, customKey); + final filePath = '${_cacheDirectory!.path}/images/$fileName'; + + + final existingFile = File(filePath); + if (await existingFile.exists()) { + return filePath; + } + + + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + + await existingFile.writeAsBytes(response.bodyBytes); + return filePath; + } + } catch (e) { + print('Ошибка кэширования файла $url: $e'); + } + + return null; + } + + + Future getCachedFile(String url, {String? customKey}) async { + if (_cacheDirectory == null) return null; + + try { + final fileName = _generateFileName(url, customKey); + final filePath = '${_cacheDirectory!.path}/images/$fileName'; + + final file = File(filePath); + if (await file.exists()) { + return file; + } + } catch (e) { + print('Ошибка получения кэшированного файла: $e'); + } + + return null; + } + + + String _generateFileName(String url, String? customKey) { + final key = customKey ?? url; + final hash = key.hashCode.abs().toString().substring(0, 16); + final extension = _getFileExtension(url); + return '$hash$extension'; + } + + + String _getFileExtension(String url) { + try { + final uri = Uri.parse(url); + final path = uri.path; + final extension = path.substring(path.lastIndexOf('.')); + return extension.isNotEmpty && extension.length < 10 ? extension : '.jpg'; + } catch (e) { + return '.jpg'; + } + } + + + Future hasCachedFile(String url, {String? customKey}) async { + final file = await getCachedFile(url, customKey: customKey); + return file != null; + } + + + Future> getDetailedCacheStats() async { + final memorySize = _memoryCache.length; + final cacheSize = await getCacheSize(); + + return { + 'memory': {'items': memorySize, 'max_items': _maxMemoryCacheSize}, + 'filesystem': { + 'total_size': cacheSize['total'], + 'files_size': cacheSize['files'], + }, + 'timestamp': DateTime.now().millisecondsSinceEpoch, + }; + } + + + Future removeCachedFile(String url, {String? customKey}) async { + + + } + + + Future> getCacheStats() async { + final sizes = await getCacheSize(); + final memoryEntries = _memoryCache.length; + final diskEntries = + _prefs?.getKeys().where((key) => key.startsWith('cache_')).length ?? 0; + + return { + 'memoryEntries': memoryEntries, + 'diskEntries': diskEntries, + 'memorySize': sizes['memory'], + 'filesSizeMB': (sizes['files']! / (1024 * 1024)).toStringAsFixed(2), + 'maxMemorySize': _maxMemoryCacheSize, + }; + } +} diff --git a/lib/services/chat_cache_service.dart b/lib/services/chat_cache_service.dart new file mode 100644 index 0000000..1705764 --- /dev/null +++ b/lib/services/chat_cache_service.dart @@ -0,0 +1,334 @@ + + +import 'dart:async'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/services/cache_service.dart'; + +class ChatCacheService { + static final ChatCacheService _instance = ChatCacheService._internal(); + factory ChatCacheService() => _instance; + ChatCacheService._internal(); + + final CacheService _cacheService = CacheService(); + + + Future initialize() async { + await _cacheService.initialize(); + print('ChatCacheService инициализирован'); + } + + + static const String _chatsKey = 'cached_chats'; + static const String _contactsKey = 'cached_contacts'; + static const String _messagesKey = 'cached_messages'; + static const String _chatMessagesKey = 'cached_chat_messages'; + + + static const Duration _chatsTTL = Duration(hours: 1); + static const Duration _contactsTTL = Duration(hours: 6); + static const Duration _messagesTTL = Duration(hours: 2); + + + Future cacheChats(List> chats) async { + try { + await _cacheService.set(_chatsKey, chats, ttl: _chatsTTL); + print('Кэшировано ${chats.length} чатов'); + } catch (e) { + print('Ошибка кэширования чатов: $e'); + } + } + + + Future>?> getCachedChats() async { + try { + final cached = await _cacheService.get>( + _chatsKey, + ttl: _chatsTTL, + ); + if (cached != null) { + return cached.cast>(); + } + } catch (e) { + print('Ошибка получения кэшированных чатов: $e'); + } + return null; + } + + + Future cacheContacts(List contacts) async { + try { + final contactsData = contacts + .map( + (contact) => { + 'id': contact.id, + 'name': contact.name, + 'firstName': contact.firstName, + 'lastName': contact.lastName, + 'photoBaseUrl': contact.photoBaseUrl, + 'isBlocked': contact.isBlocked, + 'isBlockedByMe': contact.isBlockedByMe, + 'accountStatus': contact.accountStatus, + 'status': contact.status, + }, + ) + .toList(); + + await _cacheService.set(_contactsKey, contactsData, ttl: _contactsTTL); + print('Кэшировано ${contacts.length} контактов'); + } catch (e) { + print('Ошибка кэширования контактов: $e'); + } + } + + + Future?> getCachedContacts() async { + try { + final cached = await _cacheService.get>( + _contactsKey, + ttl: _contactsTTL, + ); + if (cached != null) { + return cached.map((data) => Contact.fromJson(data)).toList(); + } + } catch (e) { + print('Ошибка получения кэшированных контактов: $e'); + } + return null; + } + + + Future cacheChatMessages(int chatId, List messages) async { + try { + final key = '$_chatMessagesKey$chatId'; + final messagesData = messages + .map( + (message) => { + 'id': message.id, + 'sender': message.senderId, + 'text': message.text, + 'time': message.time, + 'status': message.status, + 'updateTime': message.updateTime, + 'attaches': message.attaches, + 'cid': message.cid, + 'reactionInfo': message.reactionInfo, + 'link': message.link, + }, + ) + .toList(); + + await _cacheService.set(key, messagesData, ttl: _messagesTTL); + print('Кэшировано ${messages.length} сообщений для чата $chatId'); + } catch (e) { + print('Ошибка кэширования сообщений для чата $chatId: $e'); + } + } + + + Future?> getCachedChatMessages(int chatId) async { + try { + final key = '$_chatMessagesKey$chatId'; + final cached = await _cacheService.get>( + key, + ttl: _messagesTTL, + ); + if (cached != null) { + return cached.map((data) => Message.fromJson(data)).toList(); + } + } catch (e) { + print('Ошибка получения кэшированных сообщений для чата $chatId: $e'); + } + return null; + } + + + Future addMessageToCache(int chatId, Message message) async { + try { + final cached = await getCachedChatMessages(chatId); + + if (cached != null) { + + final updatedMessages = [message, ...cached]; + await cacheChatMessages(chatId, updatedMessages); + } else { + + await cacheChatMessages(chatId, [message]); + } + } catch (e) { + print('Ошибка добавления сообщения в кэш: $e'); + } + } + + + Future updateMessageInCache(int chatId, Message updatedMessage) async { + try { + final cached = await getCachedChatMessages(chatId); + + if (cached != null) { + final updatedMessages = cached.map((message) { + if (message.id == updatedMessage.id) { + return updatedMessage; + } + return message; + }).toList(); + + await cacheChatMessages(chatId, updatedMessages); + } + } catch (e) { + print('Ошибка обновления сообщения в кэше: $e'); + } + } + + + Future removeMessageFromCache(int chatId, String messageId) async { + try { + final cached = await getCachedChatMessages(chatId); + + if (cached != null) { + final updatedMessages = cached + .where((message) => message.id != messageId) + .toList(); + await cacheChatMessages(chatId, updatedMessages); + } + } catch (e) { + print('Ошибка удаления сообщения из кэша: $e'); + } + } + + + Future cacheChatInfo(int chatId, Map chatInfo) async { + try { + final key = 'chat_info_$chatId'; + await _cacheService.set(key, chatInfo, ttl: _chatsTTL); + } catch (e) { + print('Ошибка кэширования информации о чате $chatId: $e'); + } + } + + + Future?> getCachedChatInfo(int chatId) async { + try { + final key = 'chat_info_$chatId'; + return await _cacheService.get>(key, ttl: _chatsTTL); + } catch (e) { + print('Ошибка получения кэшированной информации о чате $chatId: $e'); + return null; + } + } + + + Future cacheLastMessage(int chatId, Message? lastMessage) async { + try { + final key = 'last_message_$chatId'; + if (lastMessage != null) { + final messageData = { + 'id': lastMessage.id, + 'sender': lastMessage.senderId, + 'text': lastMessage.text, + 'time': lastMessage.time, + 'status': lastMessage.status, + 'updateTime': lastMessage.updateTime, + 'attaches': lastMessage.attaches, + 'cid': lastMessage.cid, + 'reactionInfo': lastMessage.reactionInfo, + 'link': lastMessage.link, + }; + await _cacheService.set(key, messageData, ttl: _chatsTTL); + } else { + await _cacheService.remove(key); + } + } catch (e) { + print('Ошибка кэширования последнего сообщения для чата $chatId: $e'); + } + } + + + Future getCachedLastMessage(int chatId) async { + try { + final key = 'last_message_$chatId'; + final cached = await _cacheService.get>( + key, + ttl: _chatsTTL, + ); + if (cached != null) { + return Message.fromJson(cached); + } + } catch (e) { + print( + 'Ошибка получения кэшированного последнего сообщения для чата $chatId: $e', + ); + } + return null; + } + + + Future clearChatCache(int chatId) async { + try { + final keys = [ + '$_chatMessagesKey$chatId', + 'chat_info_$chatId', + 'last_message_$chatId', + ]; + + for (final key in keys) { + await _cacheService.remove(key); + } + + print('Кэш для чата $chatId очищен'); + } catch (e) { + print('Ошибка очистки кэша для чата $chatId: $e'); + } + } + + + Future clearAllChatCache() async { + try { + await _cacheService.remove(_chatsKey); + await _cacheService.remove(_contactsKey); + await _cacheService.remove(_messagesKey); + + + + print('Весь кэш чатов очищен'); + } catch (e) { + print('Ошибка очистки всего кэша чатов: $e'); + } + } + + + Future> getChatCacheStats() async { + try { + final cacheStats = await _cacheService.getCacheStats(); + final chats = await getCachedChats(); + final contacts = await getCachedContacts(); + + return { + 'cachedChats': chats?.length ?? 0, + 'cachedContacts': contacts?.length ?? 0, + 'cacheStats': cacheStats, + }; + } catch (e) { + print('Ошибка получения статистики кэша чатов: $e'); + return {}; + } + } + + + Future isCacheValid(String cacheType) async { + try { + switch (cacheType) { + case 'chats': + return await _cacheService.get(_chatsKey, ttl: _chatsTTL) != null; + case 'contacts': + return await _cacheService.get(_contactsKey, ttl: _contactsTTL) != + null; + default: + return false; + } + } catch (e) { + print('Ошибка проверки актуальности кэша: $e'); + return false; + } + } +} diff --git a/lib/services/version_checker.dart b/lib/services/version_checker.dart new file mode 100644 index 0000000..4c19818 --- /dev/null +++ b/lib/services/version_checker.dart @@ -0,0 +1,121 @@ +import 'package:http/http.dart' as http; + +class VersionChecker { + + + + + static Future getLatestVersion() async { + try { + + final html = await _fetchPage('https://web.max.ru/'); + + + final mainChunkUrl = _extractMainChunkUrl(html); + print('[INFO] Загружаем главный chunk: $mainChunkUrl'); + + + final mainChunkCode = await _fetchPage(mainChunkUrl); + + + final chunkPaths = _extractChunkPaths(mainChunkCode); + + + for (final path in chunkPaths) { + if (path.contains('/chunks/')) { + final url = _buildChunkUrl(path); + print('[INFO] Загружаем chunk: $url'); + + try { + final jsCode = await _fetchPage(url); + final version = _extractVersion(jsCode); + + if (version != null) { + print('[SUCCESS] Версия: $version из $url'); + return version; + } + } catch (e) { + print('[WARN] Не удалось скачать $url: $e'); + continue; + } + } + } + + throw Exception('Версия не найдена ни в одном из чанков'); + } catch (e) { + throw Exception('Не удалось проверить версию: $e'); + } + } + + + static Future _fetchPage(String url) async { + final response = await http + .get(Uri.parse(url)) + .timeout(const Duration(seconds: 10)); + + if (response.statusCode != 200) { + throw Exception('Ошибка загрузки $url (${response.statusCode})'); + } + + return response.body; + } + + + static String _extractMainChunkUrl(String html) { + final parts = html.split('import('); + if (parts.length < 3) { + throw Exception('Не найден import() в HTML'); + } + + final mainChunkImport = parts[2] + .split(')')[0] + .replaceAll('"', '') + .replaceAll("'", ''); + + return 'https://web.max.ru$mainChunkImport'; + } + + + static List _extractChunkPaths(String mainChunkCode) { + final firstLine = mainChunkCode.split('\n')[0]; + final arrayContent = firstLine.split('[')[1].split(']')[0]; + + return arrayContent.split(','); + } + + + static String _buildChunkUrl(String path) { + final cleanPath = path.substring(3, path.length - 1); + return 'https://web.max.ru/_app/immutable$cleanPath'; + } + + + static String? _extractVersion(String jsCode) { + const wsAnchor = 'wss://ws-api.oneme.ru/websocket'; + final pos = jsCode.indexOf(wsAnchor); + + if (pos == -1) { + print('[INFO] ws-якорь не найден'); + return null; + } + + print('[INFO] Найден ws-якорь на позиции $pos'); + + + final snippet = jsCode.substring(pos, (pos + 2000).clamp(0, jsCode.length)); + + print('[INFO] Анализируем snippet (первые 500 символов):'); + print('${snippet.substring(0, 500.clamp(0, snippet.length))}...\n'); + + + final versionRegex = RegExp(r'[:=]\s*"(\d{1,2}\.\d{1,2}\.\d{1,2})"'); + final match = versionRegex.firstMatch(snippet); + + if (match != null) { + return match.group(1); + } + + print('[INFO] Версия не найдена в snippet'); + return null; + } +} diff --git a/lib/spoofing_service.dart b/lib/spoofing_service.dart new file mode 100644 index 0000000..6843d6f --- /dev/null +++ b/lib/spoofing_service.dart @@ -0,0 +1,28 @@ +import 'package:shared_preferences/shared_preferences.dart'; + +class SpoofingService { + + + static Future?> getSpoofedSessionData() async { + final prefs = await SharedPreferences.getInstance(); + + final isEnabled = prefs.getBool('spoofing_enabled') ?? false; + + if (!isEnabled) { + return null; // Если подмена выключена, возвращаем null + } + + + return { + 'user_agent': prefs.getString('spoof_useragent'), + 'device_name': prefs.getString('spoof_devicename'), + 'os_version': prefs.getString('spoof_osversion'), + 'screen': prefs.getString('spoof_screen'), + 'timezone': prefs.getString('spoof_timezone'), + 'locale': prefs.getString('spoof_locale'), + 'device_id': prefs.getString('spoof_deviceid'), + 'device_type': prefs.getString('spoof_devicetype'), + 'app_version': prefs.getString('spoof_appversion') ?? '25.10.10', + }; + } +} diff --git a/lib/theme_provider.dart b/lib/theme_provider.dart new file mode 100644 index 0000000..77a886f --- /dev/null +++ b/lib/theme_provider.dart @@ -0,0 +1,1250 @@ +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'dart:convert'; + +enum AppTheme { system, light, dark, black } + +enum ChatWallpaperType { solid, gradient, image, video } + +enum TransitionOption { systemDefault, slide } + +enum UIMode { both, burgerOnly, panelOnly } + +enum MessageBubbleType { solid } + +extension MessageBubbleTypeExtension on MessageBubbleType { + String get displayName { + switch (this) { + case MessageBubbleType.solid: + return 'Цвет'; + } + } +} + +extension TransitionOptionExtension on TransitionOption { + String get displayName { + switch (this) { + case TransitionOption.systemDefault: + return 'Default'; + case TransitionOption.slide: + return 'Slide'; + } + } +} + +extension ChatWallpaperTypeExtension on ChatWallpaperType { + String get displayName { + switch (this) { + case ChatWallpaperType.solid: + return 'Цвет'; + case ChatWallpaperType.gradient: + return 'Градиент'; + case ChatWallpaperType.image: + return 'Фото'; + case ChatWallpaperType.video: + return 'Видео'; + } + } +} + +class CustomThemePreset { + String id; + String name; + + AppTheme appTheme; + Color accentColor; + + bool useCustomChatWallpaper; + ChatWallpaperType chatWallpaperType; + Color chatWallpaperColor1; + Color chatWallpaperColor2; + String? chatWallpaperImagePath; + String? chatWallpaperVideoPath; + bool chatWallpaperBlur; + double chatWallpaperBlurSigma; + double chatWallpaperImageBlur; + + bool useGlassPanels; + double topBarBlur; + double topBarOpacity; + double bottomBarBlur; + double bottomBarOpacity; + + double messageMenuOpacity; + double messageMenuBlur; + double profileDialogBlur; + double profileDialogOpacity; + + UIMode uiMode; + bool showSeconds; + double messageBubbleOpacity; + String messageStyle; + double messageBackgroundBlur; + double messageTextOpacity; + double messageShadowIntensity; + double messageBorderRadius; + + double messageFontSize; + Color? myBubbleColorLight; + Color? theirBubbleColorLight; + Color? myBubbleColorDark; + Color? theirBubbleColorDark; + MessageBubbleType messageBubbleType; + bool sendOnEnter; + + TransitionOption chatTransition; + TransitionOption tabTransition; + TransitionOption messageTransition; + TransitionOption extraTransition; + double messageSlideDistance; + double extraAnimationStrength; + bool animatePhotoMessages; + bool optimizeChats; + bool ultraOptimizeChats; + bool useDesktopLayout; + bool useAutoReplyColor; + Color? customReplyColor; + + CustomThemePreset({ + required this.id, + required this.name, + this.appTheme = AppTheme.system, + this.accentColor = Colors.blue, + this.useCustomChatWallpaper = false, + this.chatWallpaperType = ChatWallpaperType.solid, + this.chatWallpaperColor1 = const Color(0xFF101010), + this.chatWallpaperColor2 = const Color(0xFF202020), + this.chatWallpaperImagePath, + this.chatWallpaperVideoPath, + this.chatWallpaperBlur = false, + this.chatWallpaperBlurSigma = 12.0, + this.chatWallpaperImageBlur = 0.0, + this.useGlassPanels = true, + this.topBarBlur = 10.0, + this.topBarOpacity = 0.6, + this.bottomBarBlur = 10.0, + this.bottomBarOpacity = 0.7, + this.messageMenuOpacity = 0.95, + this.messageMenuBlur = 4.0, + this.profileDialogBlur = 12.0, + this.profileDialogOpacity = 0.26, + this.uiMode = UIMode.both, + this.showSeconds = false, + this.messageBubbleOpacity = 0.12, + this.messageStyle = 'glass', + this.messageBackgroundBlur = 0.0, + this.messageTextOpacity = 1.0, + this.messageShadowIntensity = 0.1, + this.messageBorderRadius = 20.0, + this.messageFontSize = 16.0, + this.myBubbleColorLight, + this.theirBubbleColorLight, + this.myBubbleColorDark, + this.theirBubbleColorDark, + this.messageBubbleType = MessageBubbleType.solid, + this.sendOnEnter = false, + this.chatTransition = TransitionOption.systemDefault, + this.tabTransition = TransitionOption.systemDefault, + this.messageTransition = TransitionOption.systemDefault, + this.extraTransition = TransitionOption.systemDefault, + this.messageSlideDistance = 96.0, + this.extraAnimationStrength = 32.0, + this.animatePhotoMessages = false, + this.optimizeChats = false, + this.ultraOptimizeChats = false, + this.useDesktopLayout = true, + this.useAutoReplyColor = true, + this.customReplyColor, + }); + + factory CustomThemePreset.createDefault() { + return CustomThemePreset(id: 'default', name: 'По умолчанию'); + } + + CustomThemePreset copyWith({ + String? id, + String? name, + AppTheme? appTheme, + Color? accentColor, + bool? useCustomChatWallpaper, + ChatWallpaperType? chatWallpaperType, + Color? chatWallpaperColor1, + Color? chatWallpaperColor2, + String? chatWallpaperImagePath, + String? chatWallpaperVideoPath, + bool? chatWallpaperBlur, + double? chatWallpaperBlurSigma, + double? chatWallpaperImageBlur, + bool? useGlassPanels, + double? topBarBlur, + double? topBarOpacity, + double? bottomBarBlur, + double? bottomBarOpacity, + double? messageMenuOpacity, + double? messageMenuBlur, + double? profileDialogBlur, + double? profileDialogOpacity, + UIMode? uiMode, + bool? showSeconds, + double? messageBubbleOpacity, + String? messageStyle, + double? messageBackgroundBlur, + double? messageTextOpacity, + double? messageShadowIntensity, + double? messageBorderRadius, + double? messageFontSize, + Color? myBubbleColorLight, + Color? theirBubbleColorLight, + Color? myBubbleColorDark, + Color? theirBubbleColorDark, + MessageBubbleType? messageBubbleType, + bool? sendOnEnter, + TransitionOption? chatTransition, + TransitionOption? tabTransition, + TransitionOption? messageTransition, + TransitionOption? extraTransition, + double? messageSlideDistance, + double? extraAnimationStrength, + bool? animatePhotoMessages, + bool? optimizeChats, + bool? ultraOptimizeChats, + bool? useDesktopLayout, + bool? useAutoReplyColor, + Color? customReplyColor, + }) { + return CustomThemePreset( + id: id ?? this.id, + name: name ?? this.name, + appTheme: appTheme ?? this.appTheme, + accentColor: accentColor ?? this.accentColor, + useCustomChatWallpaper: + useCustomChatWallpaper ?? this.useCustomChatWallpaper, + chatWallpaperType: chatWallpaperType ?? this.chatWallpaperType, + chatWallpaperColor1: chatWallpaperColor1 ?? this.chatWallpaperColor1, + chatWallpaperColor2: chatWallpaperColor2 ?? this.chatWallpaperColor2, + chatWallpaperImagePath: + chatWallpaperImagePath ?? this.chatWallpaperImagePath, + chatWallpaperVideoPath: + chatWallpaperVideoPath ?? this.chatWallpaperVideoPath, + chatWallpaperBlur: chatWallpaperBlur ?? this.chatWallpaperBlur, + chatWallpaperBlurSigma: + chatWallpaperBlurSigma ?? this.chatWallpaperBlurSigma, + chatWallpaperImageBlur: + chatWallpaperImageBlur ?? this.chatWallpaperImageBlur, + useGlassPanels: useGlassPanels ?? this.useGlassPanels, + topBarBlur: topBarBlur ?? this.topBarBlur, + topBarOpacity: topBarOpacity ?? this.topBarOpacity, + bottomBarBlur: bottomBarBlur ?? this.bottomBarBlur, + bottomBarOpacity: bottomBarOpacity ?? this.bottomBarOpacity, + messageMenuOpacity: messageMenuOpacity ?? this.messageMenuOpacity, + messageMenuBlur: messageMenuBlur ?? this.messageMenuBlur, + profileDialogBlur: profileDialogBlur ?? this.profileDialogBlur, + profileDialogOpacity: profileDialogOpacity ?? this.profileDialogOpacity, + uiMode: uiMode ?? this.uiMode, + showSeconds: showSeconds ?? this.showSeconds, + messageBubbleOpacity: messageBubbleOpacity ?? this.messageBubbleOpacity, + messageStyle: messageStyle ?? this.messageStyle, + messageBackgroundBlur: + messageBackgroundBlur ?? this.messageBackgroundBlur, + messageTextOpacity: messageTextOpacity ?? this.messageTextOpacity, + messageShadowIntensity: + messageShadowIntensity ?? this.messageShadowIntensity, + messageBorderRadius: messageBorderRadius ?? this.messageBorderRadius, + messageFontSize: messageFontSize ?? this.messageFontSize, + myBubbleColorLight: myBubbleColorLight ?? this.myBubbleColorLight, + theirBubbleColorLight: + theirBubbleColorLight ?? this.theirBubbleColorLight, + myBubbleColorDark: myBubbleColorDark ?? this.myBubbleColorDark, + theirBubbleColorDark: theirBubbleColorDark ?? this.theirBubbleColorDark, + messageBubbleType: messageBubbleType ?? this.messageBubbleType, + sendOnEnter: sendOnEnter ?? this.sendOnEnter, + chatTransition: chatTransition ?? this.chatTransition, + tabTransition: tabTransition ?? this.tabTransition, + messageTransition: messageTransition ?? this.messageTransition, + extraTransition: extraTransition ?? this.extraTransition, + messageSlideDistance: messageSlideDistance ?? this.messageSlideDistance, + extraAnimationStrength: + extraAnimationStrength ?? this.extraAnimationStrength, + animatePhotoMessages: animatePhotoMessages ?? this.animatePhotoMessages, + optimizeChats: optimizeChats ?? this.optimizeChats, + ultraOptimizeChats: ultraOptimizeChats ?? this.ultraOptimizeChats, + useDesktopLayout: useDesktopLayout ?? this.useDesktopLayout, + useAutoReplyColor: useAutoReplyColor ?? this.useAutoReplyColor, + customReplyColor: customReplyColor ?? this.customReplyColor, + ); + } + + Map toJson() { + return { + 'id': id, + 'name': name, + 'appTheme': appTheme.index, + 'accentColor': accentColor.value, + 'useCustomChatWallpaper': useCustomChatWallpaper, + 'chatWallpaperType': chatWallpaperType.index, + 'chatWallpaperColor1': chatWallpaperColor1.value, + 'chatWallpaperColor2': chatWallpaperColor2.value, + 'chatWallpaperImagePath': chatWallpaperImagePath, + 'chatWallpaperVideoPath': chatWallpaperVideoPath, + 'chatWallpaperBlur': chatWallpaperBlur, + 'chatWallpaperBlurSigma': chatWallpaperBlurSigma, + 'chatWallpaperImageBlur': chatWallpaperImageBlur, + 'useGlassPanels': useGlassPanels, + 'topBarBlur': topBarBlur, + 'topBarOpacity': topBarOpacity, + 'bottomBarBlur': bottomBarBlur, + 'bottomBarOpacity': bottomBarOpacity, + 'messageMenuOpacity': messageMenuOpacity, + 'messageMenuBlur': messageMenuBlur, + 'profileDialogBlur': profileDialogBlur, + 'profileDialogOpacity': profileDialogOpacity, + 'uiMode': uiMode.index, + 'showSeconds': showSeconds, + 'messageBubbleOpacity': messageBubbleOpacity, + 'messageStyle': messageStyle, + 'messageBackgroundBlur': messageBackgroundBlur, + 'messageTextOpacity': messageTextOpacity, + 'messageShadowIntensity': messageShadowIntensity, + 'messageBorderRadius': messageBorderRadius, + 'messageFontSize': messageFontSize, + 'myBubbleColorLight': myBubbleColorLight?.value, + 'theirBubbleColorLight': theirBubbleColorLight?.value, + 'myBubbleColorDark': myBubbleColorDark?.value, + 'theirBubbleColorDark': theirBubbleColorDark?.value, + 'messageBubbleType': messageBubbleType.index, + 'sendOnEnter': sendOnEnter, + 'chatTransition': chatTransition.index, + 'tabTransition': tabTransition.index, + 'messageTransition': messageTransition.index, + 'extraTransition': extraTransition.index, + 'messageSlideDistance': messageSlideDistance, + 'extraAnimationStrength': extraAnimationStrength, + 'animatePhotoMessages': animatePhotoMessages, + 'optimizeChats': optimizeChats, + 'ultraOptimizeChats': ultraOptimizeChats, + 'useDesktopLayout': useDesktopLayout, + 'useAutoReplyColor': useAutoReplyColor, + 'customReplyColor': customReplyColor?.value, + }; + } + + factory CustomThemePreset.fromJson(Map json) { + return CustomThemePreset( + id: json['id'] as String, + name: json['name'] as String, + appTheme: AppTheme.values[json['appTheme'] as int? ?? 0], + accentColor: Color(json['accentColor'] as int? ?? Colors.blue.value), + useCustomChatWallpaper: json['useCustomChatWallpaper'] as bool? ?? false, + chatWallpaperType: + ChatWallpaperType.values[json['chatWallpaperType'] as int? ?? 0], + chatWallpaperColor1: Color( + json['chatWallpaperColor1'] as int? ?? const Color(0xFF101010).value, + ), + chatWallpaperColor2: Color( + json['chatWallpaperColor2'] as int? ?? const Color(0xFF202020).value, + ), + chatWallpaperImagePath: json['chatWallpaperImagePath'] as String?, + chatWallpaperVideoPath: json['chatWallpaperVideoPath'] as String?, + chatWallpaperBlur: json['chatWallpaperBlur'] as bool? ?? false, + chatWallpaperBlurSigma: + (json['chatWallpaperBlurSigma'] as double? ?? 12.0).clamp(0.0, 20.0), + chatWallpaperImageBlur: (json['chatWallpaperImageBlur'] as double? ?? 0.0) + .clamp(0.0, 10.0), + useGlassPanels: json['useGlassPanels'] as bool? ?? true, + topBarBlur: json['topBarBlur'] as double? ?? 10.0, + topBarOpacity: json['topBarOpacity'] as double? ?? 0.6, + bottomBarBlur: json['bottomBarBlur'] as double? ?? 10.0, + bottomBarOpacity: json['bottomBarOpacity'] as double? ?? 0.7, + messageMenuOpacity: json['messageMenuOpacity'] as double? ?? 0.95, + messageMenuBlur: json['messageMenuBlur'] as double? ?? 4.0, + profileDialogBlur: (json['profileDialogBlur'] as double? ?? 12.0).clamp( + 0.0, + 30.0, + ), + profileDialogOpacity: (json['profileDialogOpacity'] as double? ?? 0.26) + .clamp(0.0, 1.0), + uiMode: UIMode.values[json['uiMode'] as int? ?? 0], + showSeconds: json['showSeconds'] as bool? ?? false, + messageBubbleOpacity: (json['messageBubbleOpacity'] as double? ?? 0.12) + .clamp(0.0, 1.0), + messageStyle: json['messageStyle'] as String? ?? 'glass', + messageBackgroundBlur: (json['messageBackgroundBlur'] as double? ?? 0.0) + .clamp(0.0, 10.0), + messageTextOpacity: (json['messageTextOpacity'] as double? ?? 1.0).clamp( + 0.1, + 1.0, + ), + messageShadowIntensity: (json['messageShadowIntensity'] as double? ?? 0.1) + .clamp(0.0, 0.5), + messageBorderRadius: (json['messageBorderRadius'] as double? ?? 20.0) + .clamp(4.0, 50.0), + messageFontSize: json['messageFontSize'] as double? ?? 16.0, + myBubbleColorLight: json['myBubbleColorLight'] != null + ? Color(json['myBubbleColorLight'] as int) + : null, + theirBubbleColorLight: json['theirBubbleColorLight'] != null + ? Color(json['theirBubbleColorLight'] as int) + : null, + myBubbleColorDark: json['myBubbleColorDark'] != null + ? Color(json['myBubbleColorDark'] as int) + : null, + theirBubbleColorDark: json['theirBubbleColorDark'] != null + ? Color(json['theirBubbleColorDark'] as int) + : null, + messageBubbleType: () { + final bubbleTypeIndex = json['messageBubbleType'] as int?; + if (bubbleTypeIndex == null) { + return MessageBubbleType.solid; + } + if (bubbleTypeIndex >= MessageBubbleType.values.length) { + return MessageBubbleType.solid; + } + return MessageBubbleType.values[bubbleTypeIndex]; + }(), + sendOnEnter: json['sendOnEnter'] as bool? ?? false, + chatTransition: + TransitionOption.values[json['chatTransition'] as int? ?? 0], + tabTransition: + TransitionOption.values[json['tabTransition'] as int? ?? 0], + messageTransition: + TransitionOption.values[json['messageTransition'] as int? ?? 0], + extraTransition: + TransitionOption.values[json['extraTransition'] as int? ?? 0], + messageSlideDistance: (json['messageSlideDistance'] as double? ?? 96.0) + .clamp(1.0, 200.0), + extraAnimationStrength: + (json['extraAnimationStrength'] as double? ?? 32.0).clamp(1.0, 400.0), + animatePhotoMessages: json['animatePhotoMessages'] as bool? ?? false, + optimizeChats: json['optimizeChats'] as bool? ?? false, + ultraOptimizeChats: json['ultraOptimizeChats'] as bool? ?? false, + useDesktopLayout: json['useDesktopLayout'] as bool? ?? false, + useAutoReplyColor: json['useAutoReplyColor'] as bool? ?? true, + customReplyColor: json['customReplyColor'] != null + ? Color(json['customReplyColor'] as int) + : null, + ); + } +} + +class ThemeProvider with ChangeNotifier { + CustomThemePreset _activeTheme = CustomThemePreset.createDefault(); + List _savedThemes = []; + + Color? _myBubbleColorLight; + Color? _theirBubbleColorLight; + Color? _myBubbleColorDark; + Color? _theirBubbleColorDark; + + final Map _chatSpecificWallpapers = {}; + + bool _debugShowPerformanceOverlay = false; + bool _debugShowChatsRefreshPanel = false; + bool _debugShowMessageCount = false; + bool _debugReadOnEnter = true; + bool _debugReadOnAction = true; + + bool _blockBypass = false; + bool _highQualityPhotos = true; + + AppTheme get appTheme => _activeTheme.appTheme; + Color get accentColor => _activeTheme.accentColor; + + ThemeMode get themeMode { + switch (_activeTheme.appTheme) { + case AppTheme.system: + return ThemeMode.system; + case AppTheme.light: + return ThemeMode.light; + case AppTheme.dark: + case AppTheme.black: + return ThemeMode.dark; + } + } + + bool get useCustomChatWallpaper => _activeTheme.useCustomChatWallpaper; + ChatWallpaperType get chatWallpaperType => _activeTheme.chatWallpaperType; + Color get chatWallpaperColor1 => _activeTheme.chatWallpaperColor1; + Color get chatWallpaperColor2 => _activeTheme.chatWallpaperColor2; + String? get chatWallpaperImagePath => _activeTheme.chatWallpaperImagePath; + String? get chatWallpaperVideoPath => _activeTheme.chatWallpaperVideoPath; + bool get chatWallpaperBlur => _activeTheme.chatWallpaperBlur; + double get chatWallpaperBlurSigma => _activeTheme.chatWallpaperBlurSigma; + double get chatWallpaperImageBlur => _activeTheme.chatWallpaperImageBlur; + + bool get useGlassPanels => _activeTheme.useGlassPanels; + double get topBarBlur => _activeTheme.topBarBlur; + double get topBarOpacity => _activeTheme.topBarOpacity; + double get bottomBarBlur => _activeTheme.bottomBarBlur; + double get bottomBarOpacity => _activeTheme.bottomBarOpacity; + + double get messageMenuOpacity => _activeTheme.messageMenuOpacity; + double get messageMenuBlur => _activeTheme.messageMenuBlur; + + double get profileDialogBlur => _activeTheme.profileDialogBlur; + double get profileDialogOpacity => _activeTheme.profileDialogOpacity; + + UIMode get uiMode => _activeTheme.uiMode; + bool get showSeconds => _activeTheme.showSeconds; + double get messageBubbleOpacity => _activeTheme.messageBubbleOpacity; + String get messageStyle => _activeTheme.messageStyle; + double get messageBackgroundBlur => _activeTheme.messageBackgroundBlur; + double get messageTextOpacity => _activeTheme.messageTextOpacity; + double get messageShadowIntensity => _activeTheme.messageShadowIntensity; + double get messageBorderRadius => _activeTheme.messageBorderRadius; + + double get messageFontSize => _activeTheme.messageFontSize; + bool get sendOnEnter => _activeTheme.sendOnEnter; + + MessageBubbleType get messageBubbleType => _activeTheme.messageBubbleType; + + Color? get myBubbleColorLight => _myBubbleColorLight; + Color? get theirBubbleColorLight => _theirBubbleColorLight; + Color? get myBubbleColorDark => _myBubbleColorDark; + Color? get theirBubbleColorDark => _theirBubbleColorDark; + + Color? get myBubbleColor { + if (appTheme == AppTheme.light) return _myBubbleColorLight; + if (appTheme == AppTheme.dark || appTheme == AppTheme.black) { + return _myBubbleColorDark; + } + return null; + } + + Color? get theirBubbleColor { + if (appTheme == AppTheme.light) return _theirBubbleColorLight; + if (appTheme == AppTheme.dark || appTheme == AppTheme.black) { + return _theirBubbleColorDark; + } + return null; + } + + bool get debugShowBottomBar => + _activeTheme.uiMode == UIMode.both || + _activeTheme.uiMode == UIMode.panelOnly; + bool get debugShowBurgerMenu => + _activeTheme.uiMode == UIMode.both || + _activeTheme.uiMode == UIMode.burgerOnly; + bool get debugShowPerformanceOverlay => _debugShowPerformanceOverlay; + bool get debugShowChatsRefreshPanel => _debugShowChatsRefreshPanel; + bool get debugShowMessageCount => _debugShowMessageCount; + bool get debugReadOnEnter => _debugReadOnEnter; + bool get debugReadOnAction => _debugReadOnAction; + + TransitionOption get chatTransition => _activeTheme.ultraOptimizeChats + ? TransitionOption.systemDefault + : _activeTheme.chatTransition; + TransitionOption get tabTransition => _activeTheme.ultraOptimizeChats + ? TransitionOption.systemDefault + : _activeTheme.tabTransition; + TransitionOption get messageTransition => _activeTheme.ultraOptimizeChats + ? TransitionOption.systemDefault + : _activeTheme.messageTransition; + TransitionOption get extraTransition => _activeTheme.ultraOptimizeChats + ? TransitionOption.systemDefault + : _activeTheme.extraTransition; + double get messageSlideDistance => _activeTheme.messageSlideDistance; + double get extraAnimationStrength => _activeTheme.extraAnimationStrength; + bool get animatePhotoMessages => _activeTheme.ultraOptimizeChats + ? false + : _activeTheme.animatePhotoMessages; + bool get optimizeChats => _activeTheme.optimizeChats; + bool get ultraOptimizeChats => _activeTheme.ultraOptimizeChats; + bool get useDesktopLayout => _activeTheme.useDesktopLayout; + bool get useAutoReplyColor => _activeTheme.useAutoReplyColor; + Color? get customReplyColor => _activeTheme.customReplyColor; + bool get highQualityPhotos => _highQualityPhotos; + bool get blockBypass => _blockBypass; + + List get savedThemes => _savedThemes; + CustomThemePreset get activeTheme => _activeTheme; + + ThemeProvider() { + loadSettings(); + } + + Future loadSettings() async { + final prefs = await SharedPreferences.getInstance(); + + final themesJson = prefs.getStringList('saved_themes') ?? []; + _savedThemes = themesJson + .map((jsonString) { + try { + return CustomThemePreset.fromJson(jsonDecode(jsonString)); + } catch (e) { + print('Ошибка загрузки темы: $e'); + return null; + } + }) + .whereType() + .toList(); + + if (_savedThemes.isEmpty) { + _savedThemes.add(CustomThemePreset.createDefault()); + } + + final activeId = + prefs.getString('active_theme_id') ?? _savedThemes.first.id; + + _activeTheme = _savedThemes.firstWhere( + (t) => t.id == activeId, + orElse: () => _savedThemes.first, + ); + + if (_activeTheme.myBubbleColorLight == null || + _activeTheme.theirBubbleColorLight == null || + _activeTheme.myBubbleColorDark == null || + _activeTheme.theirBubbleColorDark == null) { + _updateBubbleColorsFromAccent(_activeTheme.accentColor); + _activeTheme = _activeTheme.copyWith( + myBubbleColorLight: _myBubbleColorLight, + theirBubbleColorLight: _theirBubbleColorLight, + myBubbleColorDark: _myBubbleColorDark, + theirBubbleColorDark: _theirBubbleColorDark, + ); + await _saveActiveTheme(); + } else { + _myBubbleColorLight = _activeTheme.myBubbleColorLight; + _theirBubbleColorLight = _activeTheme.theirBubbleColorLight; + _myBubbleColorDark = _activeTheme.myBubbleColorDark; + _theirBubbleColorDark = _activeTheme.theirBubbleColorDark; + } + + _debugShowPerformanceOverlay = prefs.getBool('debug_perf_overlay') ?? false; + _debugShowChatsRefreshPanel = + prefs.getBool('debug_show_chats_refresh_panel') ?? false; + _debugShowMessageCount = prefs.getBool('debug_show_message_count') ?? false; + _debugReadOnEnter = prefs.getBool('debug_read_on_enter') ?? true; + _debugReadOnAction = prefs.getBool('debug_read_on_action') ?? true; + _highQualityPhotos = prefs.getBool('high_quality_photos') ?? true; + _blockBypass = prefs.getBool('block_bypass') ?? false; + + await loadChatSpecificWallpapers(); + + notifyListeners(); + } + + Future _saveThemeListToPrefs() async { + final prefs = await SharedPreferences.getInstance(); + final themesJson = _savedThemes + .map((theme) => jsonEncode(theme.toJson())) + .toList(); + await prefs.setStringList('saved_themes', themesJson); + } + + Future _saveActiveTheme() async { + final index = _savedThemes.indexWhere((t) => t.id == _activeTheme.id); + if (index != -1) { + _savedThemes[index] = _activeTheme; + } else { + _savedThemes.add(_activeTheme); + } + await _saveThemeListToPrefs(); + } + + Future applyTheme(String themeId) async { + final themeToApply = _savedThemes.firstWhere((t) => t.id == themeId); + _activeTheme = themeToApply; + + _myBubbleColorLight = _activeTheme.myBubbleColorLight; + _theirBubbleColorLight = _activeTheme.theirBubbleColorLight; + _myBubbleColorDark = _activeTheme.myBubbleColorDark; + _theirBubbleColorDark = _activeTheme.theirBubbleColorDark; + + notifyListeners(); + + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('active_theme_id', themeId); + } + + Future saveCurrentThemeAs(String name) async { + final newTheme = _activeTheme.copyWith( + id: DateTime.now().millisecondsSinceEpoch.toString(), + name: name.trim().isEmpty ? 'Новая тема' : name.trim(), + ); + + _savedThemes.add(newTheme); + await _saveThemeListToPrefs(); + await applyTheme(newTheme.id); + } + + Future deleteTheme(String themeId) async { + if (themeId == 'default') return; + _savedThemes.removeWhere((t) => t.id == themeId); + + if (_activeTheme.id == themeId) { + await applyTheme('default'); + } else { + await _saveThemeListToPrefs(); + notifyListeners(); + } + } + + Future renameTheme(String themeId, String newName) async { + if (themeId == 'default') return; + + final index = _savedThemes.indexWhere((t) => t.id == themeId); + if (index != -1) { + final String finalName = newName.trim().isEmpty + ? _savedThemes[index].name + : newName.trim(); + _savedThemes[index] = _savedThemes[index].copyWith(name: finalName); + + if (_activeTheme.id == themeId) { + _activeTheme = _activeTheme.copyWith(name: finalName); + } + + await _saveThemeListToPrefs(); + notifyListeners(); + } + } + + Future importThemeFromJson(String jsonString) async { + try { + final Map jsonMap = jsonDecode(jsonString); + + if (!jsonMap.containsKey('id') || !jsonMap.containsKey('name')) { + debugPrint("Ошибка импорта: JSON не содержит ключи 'id' или 'name'."); + return false; + } + + final importedPreset = CustomThemePreset.fromJson(jsonMap); + + final newPreset = importedPreset.copyWith( + id: DateTime.now().millisecondsSinceEpoch.toString(), + name: "Импорт: ${importedPreset.name}", + ); + + _savedThemes.add(newPreset); + await _saveThemeListToPrefs(); + notifyListeners(); + return true; // Успех + } catch (e) { + debugPrint("Ошибка импорта темы: $e"); + return false; // Неудача + } + } + + Future setTheme(AppTheme theme) async { + _activeTheme = _activeTheme.copyWith(appTheme: theme); + + if (theme != AppTheme.system) { + _updateBubbleColorsFromAccent(_activeTheme.accentColor); + _activeTheme = _activeTheme.copyWith( + myBubbleColorLight: _myBubbleColorLight, + theirBubbleColorLight: _theirBubbleColorLight, + myBubbleColorDark: _myBubbleColorDark, + theirBubbleColorDark: _theirBubbleColorDark, + ); + } + + notifyListeners(); + await _saveActiveTheme(); + } + + Future setAccentColor(Color color) async { + _updateBubbleColorsFromAccent(color); + _activeTheme = _activeTheme.copyWith( + accentColor: color, + myBubbleColorLight: _myBubbleColorLight, + theirBubbleColorLight: _theirBubbleColorLight, + myBubbleColorDark: _myBubbleColorDark, + theirBubbleColorDark: _theirBubbleColorDark, + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future updateBubbleColorsForSystemTheme(Color systemAccentColor) async { + _updateBubbleColorsFromAccent(systemAccentColor); + notifyListeners(); + } + + void _updateBubbleColorsFromAccent(Color accent) { + final Color myColorDark = accent; + + final hslDark = HSLColor.fromColor(accent); + final double theirSatDark = (hslDark.saturation * 0.4).clamp(0.0, 1.0); + final double theirLightDark = (hslDark.lightness * 0.7).clamp(0.1, 0.85); + final Color theirColorDark = HSLColor.fromAHSL( + hslDark.alpha, + hslDark.hue, + theirSatDark, + theirLightDark, + ).toColor(); + + final hslLight = HSLColor.fromColor(accent); + + final double myLightSat = (hslLight.saturation * 0.6).clamp(0.3, 0.7); + final double myLightLight = (hslLight.lightness * 0.3 + 0.6).clamp( + 0.6, + 0.9, + ); + final Color myColorLight = HSLColor.fromAHSL( + hslLight.alpha, + hslLight.hue, + myLightSat, + myLightLight, + ).toColor(); + + final double theirLightSat = (hslLight.saturation * 0.2).clamp(0.05, 0.25); + final double theirLightLight = (hslLight.lightness * 0.1 + 0.85).clamp( + 0.85, + 0.98, + ); + final Color theirColorLight = HSLColor.fromAHSL( + hslLight.alpha, + hslLight.hue, + theirLightSat, + theirLightLight, + ).toColor(); + + if (_myBubbleColorLight == myColorLight && + _theirBubbleColorLight == theirColorLight && + _myBubbleColorDark == myColorDark && + _theirBubbleColorDark == theirColorDark) { + return; + } + + _myBubbleColorLight = myColorLight; + _theirBubbleColorLight = theirColorLight; + _myBubbleColorDark = myColorDark; + _theirBubbleColorDark = theirColorDark; + } + + Future setUseGlassPanels(bool value) async { + _activeTheme = _activeTheme.copyWith(useGlassPanels: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setTopBarBlur(double value) async { + _activeTheme = _activeTheme.copyWith(topBarBlur: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setTopBarOpacity(double value) async { + _activeTheme = _activeTheme.copyWith(topBarOpacity: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setBottomBarBlur(double value) async { + _activeTheme = _activeTheme.copyWith(bottomBarBlur: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setBottomBarOpacity(double value) async { + _activeTheme = _activeTheme.copyWith(bottomBarOpacity: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageFontSize(double value) async { + _activeTheme = _activeTheme.copyWith(messageFontSize: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMyBubbleColorLight(Color? color) async { + _myBubbleColorLight = color; + _activeTheme = _activeTheme.copyWith(myBubbleColorLight: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setTheirBubbleColorLight(Color? color) async { + _theirBubbleColorLight = color; + _activeTheme = _activeTheme.copyWith(theirBubbleColorLight: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMyBubbleColorDark(Color? color) async { + _myBubbleColorDark = color; + _activeTheme = _activeTheme.copyWith(myBubbleColorDark: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setTheirBubbleColorDark(Color? color) async { + _theirBubbleColorDark = color; + _activeTheme = _activeTheme.copyWith(theirBubbleColorDark: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageBubbleType(MessageBubbleType value) async { + _activeTheme = _activeTheme.copyWith(messageBubbleType: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setSendOnEnter(bool value) async { + _activeTheme = _activeTheme.copyWith(sendOnEnter: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setUseCustomChatWallpaper(bool value) async { + _activeTheme = _activeTheme.copyWith(useCustomChatWallpaper: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperType(ChatWallpaperType type) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperType: type); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperColor1(Color color) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperColor1: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperColor2(Color color) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperColor2: color); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperImagePath(String? path) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperImagePath: path); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperVideoPath(String? path) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperVideoPath: path); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setProfileDialogBlur(double value) async { + _activeTheme = _activeTheme.copyWith( + profileDialogBlur: value.clamp(0.0, 30.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setProfileDialogOpacity(double value) async { + _activeTheme = _activeTheme.copyWith( + profileDialogOpacity: value.clamp(0.0, 1.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperBlur(bool value) async { + _activeTheme = _activeTheme.copyWith(chatWallpaperBlur: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperBlurSigma(double value) async { + _activeTheme = _activeTheme.copyWith( + chatWallpaperBlurSigma: value.clamp(0.0, 20.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatWallpaperImageBlur(double value) async { + _activeTheme = _activeTheme.copyWith( + chatWallpaperImageBlur: value.clamp(0.0, 10.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future resetChatWallpaperToDefaults() async { + _activeTheme = _activeTheme.copyWith( + useCustomChatWallpaper: false, + chatWallpaperType: ChatWallpaperType.solid, + chatWallpaperColor1: const Color(0xFF101010), + chatWallpaperColor2: const Color(0xFF202020), + chatWallpaperImagePath: null, + chatWallpaperBlur: false, + chatWallpaperImageBlur: 0.0, + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setChatSpecificWallpaper(int chatId, String? imagePath) async { + if (imagePath == null || imagePath.isEmpty) { + _chatSpecificWallpapers.remove(chatId); + } else { + _chatSpecificWallpapers[chatId] = imagePath; + } + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + final key = 'chat_wallpaper_$chatId'; + if (imagePath == null || imagePath.isEmpty) { + await prefs.remove(key); + } else { + await prefs.setString(key, imagePath); + } + } + + String? getChatSpecificWallpaper(int chatId) { + return _chatSpecificWallpapers[chatId]; + } + + bool hasChatSpecificWallpaper(int chatId) { + return _chatSpecificWallpapers.containsKey(chatId) && + _chatSpecificWallpapers[chatId] != null && + _chatSpecificWallpapers[chatId]!.isNotEmpty; + } + + Future loadChatSpecificWallpapers() async { + final prefs = await SharedPreferences.getInstance(); + final keys = prefs.getKeys(); + _chatSpecificWallpapers.clear(); + + for (final key in keys) { + if (key.startsWith('chat_wallpaper_')) { + final chatIdStr = key.substring('chat_wallpaper_'.length); + final chatId = int.tryParse(chatIdStr); + if (chatId != null) { + final imagePath = prefs.getString(key); + if (imagePath != null && imagePath.isNotEmpty) { + _chatSpecificWallpapers[chatId] = imagePath; + } + } + } + } + notifyListeners(); + } + + Future setUIMode(UIMode value) async { + _activeTheme = _activeTheme.copyWith(uiMode: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setShowSeconds(bool value) async { + _activeTheme = _activeTheme.copyWith(showSeconds: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageBubbleOpacity(double value) async { + _activeTheme = _activeTheme.copyWith( + messageBubbleOpacity: value.clamp(0.0, 1.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageStyle(String value) async { + _activeTheme = _activeTheme.copyWith(messageStyle: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageBackgroundBlur(double value) async { + _activeTheme = _activeTheme.copyWith( + messageBackgroundBlur: value.clamp(0.0, 10.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageTextOpacity(double value) async { + _activeTheme = _activeTheme.copyWith( + messageTextOpacity: value.clamp(0.1, 1.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageShadowIntensity(double value) async { + _activeTheme = _activeTheme.copyWith( + messageShadowIntensity: value.clamp(0.0, 0.5), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageBorderRadius(double value) async { + _activeTheme = _activeTheme.copyWith( + messageBorderRadius: value.clamp(4.0, 50.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageMenuOpacity(double value) async { + _activeTheme = _activeTheme.copyWith(messageMenuOpacity: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageMenuBlur(double value) async { + _activeTheme = _activeTheme.copyWith(messageMenuBlur: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setDebugShowPerformanceOverlay(bool value) async { + _debugShowPerformanceOverlay = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_perf_overlay', value); + } + + Future setDebugShowChatsRefreshPanel(bool value) async { + _debugShowChatsRefreshPanel = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_show_chats_refresh_panel', value); + } + + Future setDebugShowMessageCount(bool value) async { + _debugShowMessageCount = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_show_message_count', value); + } + + Future setDebugReadOnEnter(bool value) async { + _debugReadOnEnter = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_read_on_enter', value); + } + + Future setDebugReadOnAction(bool value) async { + _debugReadOnAction = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_read_on_action', value); + } + + Future setDebugShowBurgerMenu(bool value) async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('debug_show_burger_menu', value); + } + + Future setChatTransition(TransitionOption value) async { + _activeTheme = _activeTheme.copyWith(chatTransition: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setTabTransition(TransitionOption value) async { + _activeTheme = _activeTheme.copyWith(tabTransition: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageTransition(TransitionOption value) async { + _activeTheme = _activeTheme.copyWith(messageTransition: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setExtraTransition(TransitionOption value) async { + _activeTheme = _activeTheme.copyWith(extraTransition: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setExtraAnimationStrength(double value) async { + _activeTheme = _activeTheme.copyWith( + extraAnimationStrength: value.clamp(1.0, 400.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setMessageSlideDistance(double value) async { + _activeTheme = _activeTheme.copyWith( + messageSlideDistance: value.clamp(1.0, 200.0), + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setAnimatePhotoMessages(bool value) async { + _activeTheme = _activeTheme.copyWith(animatePhotoMessages: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setOptimizeChats(bool value) async { + _activeTheme = _activeTheme.copyWith( + optimizeChats: value, + ultraOptimizeChats: value ? false : _activeTheme.ultraOptimizeChats, + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setUltraOptimizeChats(bool value) async { + _activeTheme = _activeTheme.copyWith( + ultraOptimizeChats: value, + optimizeChats: value ? false : _activeTheme.optimizeChats, + ); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setHighQualityPhotos(bool value) async { + _highQualityPhotos = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('high_quality_photos', _highQualityPhotos); + } + + Future setBlockBypass(bool value) async { + _blockBypass = value; + notifyListeners(); + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool('block_bypass', _blockBypass); + } + + Future setUseDesktopLayout(bool value) async { + _activeTheme = _activeTheme.copyWith(useDesktopLayout: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setUseAutoReplyColor(bool value) async { + _activeTheme = _activeTheme.copyWith(useAutoReplyColor: value); + notifyListeners(); + await _saveActiveTheme(); + } + + Future setCustomReplyColor(Color? color) async { + _activeTheme = _activeTheme.copyWith(customReplyColor: color); + notifyListeners(); + await _saveActiveTheme(); + } + + void toggleTheme() { + if (appTheme == AppTheme.light) { + setTheme(AppTheme.dark); + } else { + setTheme(AppTheme.light); + } + } + + Future resetAnimationsToDefault() async { + _activeTheme = _activeTheme.copyWith( + chatTransition: TransitionOption.systemDefault, + tabTransition: TransitionOption.systemDefault, + messageTransition: TransitionOption.systemDefault, + extraTransition: TransitionOption.systemDefault, + messageSlideDistance: 96.0, + extraAnimationStrength: 32.0, + ); + notifyListeners(); + await _saveActiveTheme(); + } +} diff --git a/lib/token_auth_screen.dart b/lib/token_auth_screen.dart new file mode 100644 index 0000000..6c6aa42 --- /dev/null +++ b/lib/token_auth_screen.dart @@ -0,0 +1,437 @@ + + +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; +import 'package:flutter/material.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + + +import 'package:gwid/api_service.dart'; +import 'package:gwid/home_screen.dart'; +import 'package:gwid/proxy_service.dart'; +import 'package:gwid/proxy_settings.dart'; +import 'package:gwid/screens/settings/qr_scanner_screen.dart'; +import 'package:gwid/screens/settings/session_spoofing_screen.dart'; + + +import 'package:encrypt/encrypt.dart' as encrypt; +import 'package:crypto/crypto.dart' as crypto; + +class TokenAuthScreen extends StatefulWidget { + const TokenAuthScreen({super.key}); + + @override + State createState() => _TokenAuthScreenState(); +} + +class _TokenAuthScreenState extends State { + final TextEditingController _tokenController = TextEditingController(); + bool _isLoading = false; + + @override + void dispose() { + _tokenController.dispose(); + super.dispose(); + } + + + Future _processLogin({ + required String token, + Map? spoofData, + ProxySettings? proxySettings, + }) async { + if (!mounted) return; + setState(() => _isLoading = true); + final messenger = ScaffoldMessenger.of(context); + + try { + if (spoofData != null && spoofData.isNotEmpty) { + + messenger.showSnackBar( + const SnackBar( + content: Text('Настройки анонимности из файла применены!'), + ), + ); + } + if (proxySettings != null) { + await ProxyService.instance.saveProxySettings(proxySettings); + messenger.showSnackBar( + const SnackBar( + content: Text('Настройки прокси из файла применены!'), + backgroundColor: Colors.blue, + ), + ); + } + + await ApiService.instance.saveToken(token); + + if (mounted) { + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute(builder: (context) => const HomeScreen()), + (Route route) => false, + ); + } + } catch (e) { + messenger.showSnackBar( + SnackBar( + content: Text('Ошибка входа: ${e.toString()}'), + backgroundColor: Colors.red, + ), + ); + } finally { + if (mounted) setState(() => _isLoading = false); + } + } + + + + void _loginWithToken() { + final token = _tokenController.text.trim(); + if (token.isEmpty) { + ScaffoldMessenger.of( + context, + ).showSnackBar(const SnackBar(content: Text('Введите токен для входа'))); + return; + } + _processLogin(token: token); + } + + Future _loadSessionFile() async { + + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['json'], + ); + if (result == null || result.files.single.path == null) return; + final filePath = result.files.single.path!; + setState(() => _isLoading = true); + try { + final fileContent = await File(filePath).readAsString(); + Map jsonData = json.decode(fileContent); + String finalJsonPayload; + if (jsonData['encrypted'] == true) { + final password = await _showPasswordDialog(); + if (password == null || password.isEmpty) { + setState(() => _isLoading = false); + return; + } + final iv = encrypt.IV.fromBase64(jsonData['iv_base64']); + final encryptedData = encrypt.Encrypted.fromBase64( + jsonData['data_base64'], + ); + final keyBytes = utf8.encode(password); + final keyHash = crypto.sha256.convert(keyBytes); + final key = encrypt.Key(Uint8List.fromList(keyHash.bytes)); + final encrypter = encrypt.Encrypter( + encrypt.AES(key, mode: encrypt.AESMode.cbc), + ); + finalJsonPayload = encrypter.decrypt(encryptedData, iv: iv); + } else { + finalJsonPayload = fileContent; + } + final Map sessionData = json.decode(finalJsonPayload); + final String? token = sessionData['token']; + if (token == null || token.isEmpty) + throw Exception('Файл сессии не содержит токена.'); + await _processLogin( + token: token, + spoofData: sessionData['spoof_data'] is Map + ? sessionData['spoof_data'] + : null, + proxySettings: sessionData['proxy_settings'] is Map + ? ProxySettings.fromJson(sessionData['proxy_settings']) + : null, + ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Ошибка: $e'), backgroundColor: Colors.red), + ); + setState(() => _isLoading = false); + } + } + + Future _processQrData(String qrData) async { + + if (!mounted) return; + setState(() => _isLoading = true); + final messenger = ScaffoldMessenger.of(context); + + try { + final decoded = jsonDecode(qrData) as Map; + + + if (decoded['type'] != 'komet_auth_v1' || + decoded['token'] == null || + decoded['timestamp'] == null) { + throw Exception("Неверный формат QR-кода."); + } + + + final int qrTimestamp = decoded['timestamp']; + final String token = decoded['token']; + + + final int now = DateTime.now().millisecondsSinceEpoch; + const int oneMinuteInMillis = 60 * 1000; // 60 секунд + + if ((now - qrTimestamp) > oneMinuteInMillis) { + + throw Exception("QR-код устарел. Пожалуйста, сгенерируйте новый."); + } + + + await _processLogin(token: token); + } catch (e) { + messenger.showSnackBar( + SnackBar( + content: Text('Ошибка: ${e.toString()}'), + backgroundColor: Colors.red, + ), + ); + } finally { + + if (mounted) setState(() => _isLoading = false); + } + } + + void _showQrSourceSelection() { + showModalBottomSheet( + context: context, + builder: (context) => SafeArea( + child: Wrap( + children: [ + ListTile( + leading: const Icon(Icons.camera_alt_outlined), + title: const Text('Камера'), + onTap: () { + Navigator.of(context).pop(); + _scanWithCamera(); + }, + ), + ListTile( + leading: const Icon(Icons.photo_library_outlined), + title: const Text('Галерея'), + onTap: () { + Navigator.of(context).pop(); + _scanFromGallery(); + }, + ), + ], + ), + ), + ); + } + + Future _scanWithCamera() async { + final result = await Navigator.of(context).push( + MaterialPageRoute(builder: (context) => const QrScannerScreen()), + ); + if (result != null) await _processQrData(result); + } + + Future _scanFromGallery() async { + final image = await ImagePicker().pickImage(source: ImageSource.gallery); + if (image == null) return; + final controller = MobileScannerController(); + final result = await controller.analyzeImage(image.path); + await controller.dispose(); + if (result != null && + result.barcodes.isNotEmpty && + result.barcodes.first.rawValue != null) { + await _processQrData(result.barcodes.first.rawValue!); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('QR-код на изображении не найден.'), + backgroundColor: Colors.orange, + ), + ); + } + } + + Future _showPasswordDialog() { + + final passwordController = TextEditingController(); + bool isPasswordVisible = false; + return showDialog( + context: context, + barrierDismissible: false, + builder: (context) => StatefulBuilder( + builder: (context, setStateDialog) => AlertDialog( + title: const Text('Введите пароль'), + content: TextField( + controller: passwordController, + obscureText: !isPasswordVisible, + autofocus: true, + decoration: InputDecoration( + labelText: 'Пароль от файла сессии', + prefixIcon: const Icon(Icons.lock_outline), + suffixIcon: IconButton( + icon: Icon( + isPasswordVisible ? Icons.visibility_off : Icons.visibility, + ), + onPressed: () => setStateDialog( + () => isPasswordVisible = !isPasswordVisible, + ), + ), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(null), + child: const Text('Отмена'), + ), + FilledButton( + onPressed: () => + Navigator.of(context).pop(passwordController.text), + child: const Text('OK'), + ), + ], + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Другие способы входа')), + body: Stack( + children: [ + ListView( + padding: const EdgeInsets.all(16), + children: [ + + _AuthCard( + icon: Icons.qr_code_scanner_rounded, + title: 'Вход по QR-коду', + subtitle: + 'Отсканируйте QR-код с другого устройства, чтобы быстро войти.', + buttonLabel: 'Сканировать QR-код', + onPressed: _showQrSourceSelection, + ), + + const SizedBox(height: 20), + + + _AuthCard( + icon: Icons.file_open_outlined, + title: 'Вход по файлу сессии', + subtitle: + 'Загрузите ранее экспортированный .json файл для восстановления сессии.', + buttonLabel: 'Загрузить файл', + onPressed: _loadSessionFile, + isOutlined: true, + ), + + const SizedBox(height: 20), + + + _AuthCard( + icon: Icons.vpn_key_outlined, + title: 'Вход по токену', + subtitle: 'Введите токен авторизации (AUTH_TOKEN) вручную.', + buttonLabel: 'Войти с токеном', + onPressed: _loginWithToken, + isOutlined: true, + child: Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: TextField( + controller: _tokenController, + decoration: const InputDecoration( + labelText: 'Токен', + border: OutlineInputBorder(), + ), + ), + ), + ), + ], + ), + if (_isLoading) + Container( + color: Colors.black.withOpacity(0.5), + child: const Center(child: CircularProgressIndicator()), + ), + ], + ), + ); + } +} + + +class _AuthCard extends StatelessWidget { + final IconData icon; + final String title; + final String subtitle; + final String buttonLabel; + final VoidCallback onPressed; + final bool isOutlined; + final Widget? child; + + const _AuthCard({ + required this.icon, + required this.title, + required this.subtitle, + required this.buttonLabel, + required this.onPressed, + this.isOutlined = false, + this.child, + }); + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + + return Card( + elevation: isOutlined ? 0 : 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: isOutlined + ? BorderSide( + color: Theme.of(context).colorScheme.outline.withOpacity(0.5), + ) + : BorderSide.none, + ), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + children: [ + Icon( + icon, + size: 28, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(width: 12), + Text( + title, + style: textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const SizedBox(height: 8), + Text( + subtitle, + style: textTheme.bodyMedium?.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + if (child != null) ...[const SizedBox(height: 20), child!], + const SizedBox(height: 20), + isOutlined + ? OutlinedButton(onPressed: onPressed, child: Text(buttonLabel)) + : FilledButton(onPressed: onPressed, child: Text(buttonLabel)), + ], + ), + ), + ); + } +} diff --git a/lib/tos_screen.dart b/lib/tos_screen.dart new file mode 100644 index 0000000..f6b36be --- /dev/null +++ b/lib/tos_screen.dart @@ -0,0 +1,176 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class TosScreen extends StatelessWidget { + const TosScreen({super.key}); + + + final String tosText = """ +### 1. Статус и отношения +1.1. «Komet» (далее — «Приложение») — неофициальное стороннее приложение, не имеющее отношения к ООО «Коммуникационная платформа» (правообладатель сервиса «MAX»). + +1.2. Разработчики Приложения не являются партнёрами, сотрудниками или аффилированными лицами ООО «Коммуникационная платформа». + +1.3. Все упоминания торговых марок «MAX» и связанных сервисов принадлежат их правообладателям. + +### 2. Условия использования +2.1. Используя Приложение «Komet», вы: +- Автоматически подтверждаете согласие с официальным Пользовательским соглашением «MAX» (https://legal.max.ru/ps) +- Осознаёте, что использование неофициального клиента может привести к блокировке аккаунта со стороны ООО «Коммуникационная платформа»; +- Принимаете на себя все риски, связанные с использованием Приложения. + +2.2. Строго запрещено: +- Использовать Приложение «Komet» для распространения запрещённого контента; +- Осуществлять массовые рассылки (спам); +- Нарушать законодательство РФ и международное право; +- Предпринимать попытки взлома или нарушения работы оригинального сервиса «MAX». + +2.3. Техническая реализация соответствует принципу добросовестного использования (fair use) и не нарушает исключительные права правообладателя в соответствии с статьёй 1273 ГК РФ. + +2.4. Особенности технического взаимодействия: +- Приложение «Komet» использует публично доступные методы взаимодействия с сервисом «MAX», аналогичные веб-версии (https://web.max.ru) +- Все запросы выполняются в рамках добросовестного использования для обеспечения совместимости; +- Разработчики не осуществляют обход технических средств защиты и не декомпилируют оригинальное ПО. + +### 3. Технические аспекты +3.1. Приложение «Komet» использует только публично доступные методы взаимодействия с сервисом «MAX» через официальные конечные точки. + +3.2. Все запросы выполняются в рамках добросовестного использования (fair use) для обеспечения совместимости. + +3.3. Разработчики не несут ответственности за: +- Изменения в API оригинального сервиса; +- Блокировку аккаунтов пользователей; +- Функциональные ограничения, вызванные действиями ООО «Коммуникационная платформа». + +### 4. Конфиденциальность +4.1. Приложение «Komet» не хранит и не обрабатывает персональные данные пользователей. + +4.2. Все данные авторизации передаются напрямую серверам ООО «Коммуникационная платформа». + +4.3. Разработчики не имеют доступа к логинам, паролям, переписке и другим персональным данным пользователей. + +### 5. Ответственность и ограничения +5.1. Приложение «Komet» предоставляется «как есть» (as is) без гарантий работоспособности. + +5.2. Разработчики вправе прекратить поддержку Приложения в любой момент без объяснения причин. + +5.3. Пользователь обязуется не использовать Приложение «Komet» в коммерческих целях. + +### 6. Правовые основания +6.1. Разработка и распространение Приложения «Komet» осуществляются в соответствии с: +- Статья 1280.1 ГК РФ — декомпилирование программы для обеспечения совместимости; +- Статья 1229 ГК РФ — ограничения исключительного права в информационных целях; +- Федеральный закон № 149-ФЗ «Об информации» — использование общедоступной информации; +- Право на межоперабельность (Directive (EU) 2019/790) — обеспечение взаимодействия программ. + +6.2. Взаимодействие с сервисом «MAX» осуществляется исключительно через: +- Публичные API-интерфейсы, доступные через веб-версию сервиса; +- Методы обратной разработки, разрешённые ст. 1280.1 ГК РФ для целей совместимости; +- Открытые протоколы взаимодействия, не защищённые техническими средствами охраны. + +6.3. Приложение «Komet» не обходит технические средства защиты и не нарушает нормальную работу оригинального сервиса, что соответствует требованиям статьи 1299 ГК РФ. + +### 7. Заключительные положения +7.1. Используя Приложение «Komet», вы соглашаетесь с тем, что: +- Единственным правомочным способом использования сервиса «MAX» является применение официальных клиентов; +- Все претензии по работе сервиса должны направляться в ООО «Коммуникационная платформа»; +- Разработчики Приложения не несут ответственности за любые косвенные или прямые убытки. + +7.2. Настоящее соглашение может быть изменено без предварительного уведомления пользователей. + +### 8. Функции безопасности и конфиденциальности +8.1. Приложение «Komet» включает инструменты защиты приватности: +- Подмена данных сессии — для предотвращения отслеживания пользователя; +- Система прокси-подключений — для обеспечения безопасности сетевого взаимодействия; +- Ограничение телеметрии — для минимизации передачи диагностических данных. + +8.2. Данные функции: +- Направлены исключительно на защиту конфиденциальности пользователей; +- Не используются для обхода систем безопасности оригинального сервиса; +- Реализованы в рамках статьи 152.1 ГК РФ о защите частной жизни. + +8.3. Разработчики не несут ответственности за: +- Блокировки, связанные с использованием инструментов конфиденциальности; +- Изменения в работе сервиса при активации данных функций. + +### 8.4. Функции экспорта и импорта сессии +8.4.1. Приложение «Komet» предоставляет возможность экспорта и импорта данных сессии для: +- Обеспечения переносимости данных между устройствами пользователя +- Резервного копирования учетных данных +- Восстановления доступа при утере устройства + +8.4.2. Особенности реализации: +- Экспорт сессии осуществляется без привязки к номеру телефона +- Данные сессии защищаются паролем и шифрованием по алгоритмам AES-256 +- Ключ шифрования известен только пользователю и не сохраняется в приложении + +8.4.3. Техническая реализация экспорта сессии: +- Экспорт сессии осуществляется через токен авторизации для идентификации в сервисе +- Используется подмена параметров сессии для сохранения контекста аутентификации +- Интеграция настроек прокси для обеспечения единой конфигурации подключения +- Импортированная сессия маскирует источник подключения через указанные прокси-настройки +- Серверы оригинального сервиса не получают данных о смене устройства пользователя +- Шифрование применяется ко всему пакету данных (сессия + прокси-конфиг) + +8.4.4. Правовые основания: +- Статья 6 ФЗ-152 «О персональных данных» — обработка данных с согласия субъекта +- Статья 434 ГК РФ — право на выбор формы сделки (электронная форма хранения учетных данных) +- Принцип минимизации данных — сбор только необходимой для работы информации +- Использование токена не является несанкционированным доступом (ст. 272 УК РФ не нарушается) +- Подмена сессии — легитимный метод сохранения аутентификации (аналог браузерных cookies) +- Маскировка IP-адреса — законный способ защиты персональных данных (ст. 6 ФЗ-152) + +8.4.5. Ограничения ответственности: +- Пользователь самостоятельно несет ответственность за сохранность пароля и резервных копий +- Разработчики не имеют доступа к зашифрованным данным сессии +- Восстановление утерянных паролей невозможно в целях безопасности +- Ключи шифрования не хранятся в приложении и известны только пользователю +"""; + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + final markdownStyleSheet = MarkdownStyleSheet.fromTheme(Theme.of(context)) + .copyWith( + h3: textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + fontFamily: GoogleFonts.manrope().fontFamily, + height: 2.2, + ), + p: textTheme.bodyMedium?.copyWith( + fontFamily: GoogleFonts.manrope().fontFamily, + height: 1.5, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + listBullet: textTheme.bodyMedium?.copyWith( + fontFamily: GoogleFonts.manrope().fontFamily, + height: 1.6, + ), + a: TextStyle( + color: Theme.of(context).colorScheme.primary, + decoration: TextDecoration.underline, + decorationColor: Theme.of(context).colorScheme.primary, + ), + ); + + return Scaffold( + appBar: AppBar(title: const Text('Пользовательское соглашение')), + body: Markdown( + data: tosText, + padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), + styleSheet: markdownStyleSheet, + selectable: true, + onTapLink: (text, href, title) async { + if (href != null) { + final uri = Uri.tryParse(href); + if (uri != null && await canLaunchUrl(uri)) { + await launchUrl(uri, mode: LaunchMode.externalApplication); + } + } + }, + ), + ); + } +} diff --git a/lib/universal_io.dart b/lib/universal_io.dart new file mode 100644 index 0000000..e23c124 --- /dev/null +++ b/lib/universal_io.dart @@ -0,0 +1,6 @@ +library; + +class Platform { + static bool get isAndroid => false; + static bool get isIOS => false; +} \ No newline at end of file diff --git a/lib/user_id_lookup_screen.dart b/lib/user_id_lookup_screen.dart new file mode 100644 index 0000000..e969278 --- /dev/null +++ b/lib/user_id_lookup_screen.dart @@ -0,0 +1,263 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/models/contact.dart'; + +class UserIdLookupScreen extends StatefulWidget { + const UserIdLookupScreen({super.key}); + + @override + State createState() => _UserIdLookupScreenState(); +} + +class _UserIdLookupScreenState extends State { + final TextEditingController _idController = TextEditingController(); + final FocusNode _idFocusNode = FocusNode(); + bool _isLoading = false; + Contact? _foundContact; + bool _searchAttempted = false; + + Future _searchById() async { + final String idText = _idController.text.trim(); + if (idText.isEmpty) { + return; + } + + final int? contactId = int.tryParse(idText); + if (contactId == null) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Пожалуйста, введите корректный ID (только цифры)'), + ), + ); + return; + } + + _idFocusNode.unfocus(); + + setState(() { + _isLoading = true; + _searchAttempted = true; + _foundContact = null; + }); + + try { + final List contacts = await ApiService.instance + .fetchContactsByIds([contactId]); + + if (mounted) { + setState(() { + _foundContact = contacts.isNotEmpty ? contacts.first : null; + _isLoading = false; + }); + } + } catch (e) { + if (mounted) { + setState(() { + _isLoading = false; + }); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Ошибка при поиске: $e'))); + } + } + } + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + _idFocusNode.requestFocus(); + }); + } + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Scaffold( + appBar: AppBar(title: const Text('Поиск по ID')), + body: SingleChildScrollView( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + TextField( + controller: _idController, + focusNode: _idFocusNode, + decoration: InputDecoration( + labelText: 'Введите ID пользователя', + filled: true, + fillColor: colors.surfaceContainerHighest, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(16), + borderSide: BorderSide.none, + ), + prefixIcon: const Icon(Icons.person_search_outlined), + suffixIcon: _isLoading + ? const Padding( + padding: EdgeInsets.all(12.0), + child: CircularProgressIndicator(strokeWidth: 2), + ) + : IconButton( + icon: const Icon(Icons.search), + onPressed: _searchById, + ), + ), + keyboardType: TextInputType.number, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], + onSubmitted: (_) => _searchById(), + ), + const SizedBox(height: 32), + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + child: _isLoading + ? const Center( + key: ValueKey('loading'), + child: CircularProgressIndicator(), + ) + : _searchAttempted + ? _foundContact != null + ? _buildContactCard(_foundContact!, colors) + : _buildEmptyState( + key: const ValueKey('not_found'), + colors: colors, + icon: Icons.search_off_rounded, + title: 'Пользователь не найден', + subtitle: + 'Аккаунт с ID "${_idController.text}" не существует или скрыт.', + ) + : _buildEmptyState( + key: const ValueKey('initial'), + colors: colors, + icon: Icons.person_search_rounded, + title: 'Введите ID для поиска', + subtitle: 'Найдем пользователя в системе по его ID', + ), + ), + ], + ), + ), + ); + } + + Widget _buildContactCard(Contact contact, ColorScheme colors) { + return Column( + key: const ValueKey('contact_card'), + children: [ + CircleAvatar( + radius: 56, + backgroundColor: colors.primaryContainer, + backgroundImage: contact.photoBaseUrl != null + ? NetworkImage(contact.photoBaseUrl!) + : null, + child: contact.photoBaseUrl == null + ? Text( + contact.name.isNotEmpty ? contact.name[0].toUpperCase() : '?', + style: Theme.of(context).textTheme.headlineLarge?.copyWith( + color: colors.onPrimaryContainer, + ), + ) + : null, + ), + const SizedBox(height: 16), + Text( + contact.name, + style: Theme.of(context).textTheme.headlineSmall, + textAlign: TextAlign.center, + ), + const SizedBox(height: 4), + Text( + 'ID: ${contact.id}', + style: Theme.of( + context, + ).textTheme.bodyMedium?.copyWith(color: colors.onSurfaceVariant), + ), + const SizedBox(height: 24), + Container( + decoration: BoxDecoration( + color: colors.surfaceContainer, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + children: [ + _buildInfoTile( + colors: colors, + icon: Icons.person_outlined, + title: 'Имя', + subtitle: contact.firstName, + ), + const Divider(height: 1, indent: 16, endIndent: 16), + _buildInfoTile( + colors: colors, + icon: Icons.badge_outlined, + title: 'Фамилия', + subtitle: contact.lastName, + ), + const Divider(height: 1, indent: 16, endIndent: 16), + _buildInfoTile( + colors: colors, + icon: Icons.notes_rounded, + title: 'Описание', + subtitle: contact.description, + ), + ], + ), + ), + ], + ); + } + + Widget _buildInfoTile({ + required ColorScheme colors, + required IconData icon, + required String title, + String? subtitle, + }) { + final bool hasData = subtitle != null && subtitle.isNotEmpty; + + return ListTile( + leading: Icon(icon, color: colors.primary), + title: Text(title), + subtitle: Text( + hasData ? subtitle : '(не указано)', + style: TextStyle( + color: hasData + ? colors.onSurfaceVariant + : colors.onSurfaceVariant.withOpacity(0.7), + fontStyle: hasData ? FontStyle.normal : FontStyle.italic, + ), + ), + ); + } + + Widget _buildEmptyState({ + required Key key, + required ColorScheme colors, + required IconData icon, + required String title, + required String subtitle, + }) { + return Column( + key: key, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon, size: 64, color: colors.onSurfaceVariant.withOpacity(0.5)), + const SizedBox(height: 16), + Text( + title, + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(color: colors.onSurfaceVariant), + ), + const SizedBox(height: 8), + Text( + subtitle, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: colors.onSurfaceVariant.withOpacity(0.7), + ), + textAlign: TextAlign.center, + ), + ], + ); + } +} diff --git a/lib/widgets/chat_message_bubble.dart b/lib/widgets/chat_message_bubble.dart new file mode 100644 index 0000000..46e19e2 --- /dev/null +++ b/lib/widgets/chat_message_bubble.dart @@ -0,0 +1,4048 @@ +import 'dart:core'; +import 'package:flutter/material.dart'; +import 'dart:io' show File; +import 'dart:convert' show base64Decode; +import 'package:http/http.dart' as http; +import 'package:flutter/foundation.dart'; +import 'package:path_provider/path_provider.dart'; +import 'dart:io' as io; +import 'package:crypto/crypto.dart' as crypto; +import 'package:intl/intl.dart'; +import 'package:gwid/models/message.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/theme_provider.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter/services.dart'; +import 'dart:ui'; +import 'package:flutter_linkify/flutter_linkify.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:gwid/chat_screen.dart'; +import 'package:gwid/services/avatar_cache_service.dart'; +import 'package:gwid/api_service.dart'; +import 'dart:async'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:open_file/open_file.dart'; +import 'package:gwid/full_screen_video_player.dart'; + + +final _userColorCache = {}; +bool _currentIsDark = false; + +enum MessageReadStatus { + sending, // Отправляется (часы) + sent, // Отправлено (1 галочка) + read, // Прочитано (2 галочки) +} + + +class FileDownloadProgressService { + static final FileDownloadProgressService _instance = + FileDownloadProgressService._internal(); + factory FileDownloadProgressService() => _instance; + FileDownloadProgressService._internal(); + + final Map> _progressNotifiers = {}; + bool _initialized = false; + + + Future _ensureInitialized() async { + if (_initialized) return; + + try { + final prefs = await SharedPreferences.getInstance(); + + + final fileIdMap = prefs.getStringList('file_id_to_path_map') ?? []; + + + for (final mapping in fileIdMap) { + final parts = mapping.split(':'); + if (parts.length >= 2) { + final fileId = parts[0]; + final filePath = parts.skip(1).join(':'); // In case path contains ':' + + final file = io.File(filePath); + if (await file.exists()) { + if (!_progressNotifiers.containsKey(fileId)) { + _progressNotifiers[fileId] = ValueNotifier(1.0); + } else { + _progressNotifiers[fileId]!.value = 1.0; + } + } + } + } + + _initialized = true; + } catch (e) { + print('Error initializing download status: $e'); + _initialized = true; // Mark as initialized to avoid retrying indefinitely + } + } + + ValueNotifier getProgress(String fileId) { + _ensureInitialized(); // Ensure initialization + if (!_progressNotifiers.containsKey(fileId)) { + _progressNotifiers[fileId] = ValueNotifier(-1); + } + return _progressNotifiers[fileId]!; + } + + void updateProgress(String fileId, double progress) { + if (!_progressNotifiers.containsKey(fileId)) { + _progressNotifiers[fileId] = ValueNotifier(progress); + } else { + _progressNotifiers[fileId]!.value = progress; + } + } + + void clearProgress(String fileId) { + _progressNotifiers.remove(fileId); + } +} + +Color _getUserColor(int userId, BuildContext context) { + final bool isDark = Theme.of(context).brightness == Brightness.dark; + + + if (isDark != _currentIsDark) { + _userColorCache.clear(); + _currentIsDark = isDark; + } + + + if (_userColorCache.containsKey(userId)) { + return _userColorCache[userId]!; + } + + final List materialYouColors = isDark + ? [ + + const Color(0xFFEF5350), // Красный + const Color(0xFFEC407A), // Розовый + const Color(0xFFAB47BC), // Фиолетовый + const Color(0xFF7E57C2), // Глубокий фиолетовый + const Color(0xFF5C6BC0), // Индиго + const Color(0xFF42A5F5), // Синий + const Color(0xFF29B6F6), // Голубой + const Color(0xFF26C6DA), // Бирюзовый + const Color(0xFF26A69A), // Теal + const Color(0xFF66BB6A), // Зеленый + const Color(0xFF9CCC65), // Светло-зеленый + const Color(0xFFD4E157), // Лаймовый + const Color(0xFFFFEB3B), // Желтый + const Color(0xFFFFCA28), // Янтарный + const Color(0xFFFFA726), // Оранжевый + const Color(0xFFFF7043), // Глубокий оранжевый + const Color(0xFF8D6E63), // Коричневый + const Color(0xFF78909C), // Сине-серый + const Color(0xFFB39DDB), // Лавандовый + const Color(0xFF80CBC4), // Аквамариновый + const Color(0xFFC5E1A5), // Светло-зеленый пастельный + ] + : [ + + const Color(0xFFF44336), // Красный + const Color(0xFFE91E63), // Розовый + const Color(0xFF9C27B0), // Фиолетовый + const Color(0xFF673AB7), // Глубокий фиолетовый + const Color(0xFF3F51B5), // Индиго + const Color(0xFF2196F3), // Синий + const Color(0xFF03A9F4), // Голубой + const Color(0xFF00BCD4), // Бирюзовый + const Color(0xFF009688), // Теal + const Color(0xFF4CAF50), // Зеленый + const Color(0xFF8BC34A), // Светло-зеленый + const Color(0xFFCDDC39), // Лаймовый + const Color(0xFFFFEE58), // Желтый + const Color(0xFFFFC107), // Янтарный + const Color(0xFFFF9800), // Оранжевый + const Color(0xFFFF5722), // Глубокий оранжевый + const Color(0xFF795548), // Коричневый + const Color(0xFF607D8B), // Сине-серый + const Color(0xFF9575CD), // Лавандовый + const Color(0xFF4DB6AC), // Бирюзовый светлый + const Color(0xFFAED581), // Зеленый пастельный + ]; + + final colorIndex = userId % materialYouColors.length; + final color = materialYouColors[colorIndex]; + + + _userColorCache[userId] = color; + + return color; +} + +class ChatMessageBubble extends StatelessWidget { + final Message message; + final bool isMe; + final MessageReadStatus? readStatus; + final bool deferImageLoading; + final VoidCallback? onEdit; + final VoidCallback? onDelete; + final VoidCallback? onDeleteForMe; + final VoidCallback? onDeleteForAll; + final Function(String)? onReaction; + final VoidCallback? onRemoveReaction; + final VoidCallback? onReply; + final int? myUserId; + final bool? canEditMessage; + final bool isGroupChat; + final bool isChannel; + final String? senderName; + final String? forwardedFrom; + final Map? contactDetailsCache; + final Function(String)? onReplyTap; + final bool useAutoReplyColor; + final Color? customReplyColor; + final bool isFirstInGroup; + final bool isLastInGroup; + final bool isGrouped; + final double avatarVerticalOffset; + final int? chatId; + + const ChatMessageBubble({ + super.key, + required this.message, + required this.isMe, + this.readStatus, + this.deferImageLoading = false, + this.onEdit, + this.onDelete, + this.onDeleteForMe, + this.onDeleteForAll, + this.onReaction, + this.onRemoveReaction, + this.onReply, + this.myUserId, + this.canEditMessage, + this.isGroupChat = false, + this.isChannel = false, + this.senderName, + this.forwardedFrom, + this.contactDetailsCache, + this.onReplyTap, + this.useAutoReplyColor = true, + this.customReplyColor, + this.isFirstInGroup = false, + this.isLastInGroup = false, + this.isGrouped = false, + this.avatarVerticalOffset = + -35.0, // выше ниже аватарку бля как хотите я жрать хочу + this.chatId, + }); + + String _formatMessageTime(BuildContext context, int timestamp) { + final dt = DateTime.fromMillisecondsSinceEpoch(timestamp); + final showSeconds = Provider.of( + context, + listen: false, + ).showSeconds; + return DateFormat(showSeconds ? 'HH:mm:ss' : 'HH:mm').format(dt); + } + + EdgeInsets _getMessageMargin(BuildContext context) { + if (isLastInGroup) { + return const EdgeInsets.only(bottom: 12); + } + if (isFirstInGroup) { + return const EdgeInsets.only(bottom: 3); + } + return const EdgeInsets.only(bottom: 3); + } + + Widget _buildForwardedMessage( + BuildContext context, + Map link, + Color textColor, + double messageTextOpacity, + bool isUltraOptimized, + ) { + final forwardedMessage = link['message'] as Map?; + if (forwardedMessage == null) return const SizedBox.shrink(); + + final text = forwardedMessage['text'] as String? ?? ''; + final attaches = + (forwardedMessage['attaches'] as List?) + ?.map((e) => (e as Map).cast()) + .toList() ?? + []; + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), + decoration: BoxDecoration( + color: textColor.withOpacity(0.08 * messageTextOpacity), + border: Border( + left: BorderSide( + color: textColor.withOpacity(0.3 * messageTextOpacity), + width: 3, // Делаем рамку жирнее для отличия от ответа + ), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Icons.forward, + size: 14, + color: textColor.withOpacity(0.6 * messageTextOpacity), + ), + const SizedBox(width: 6), + Flexible( + child: Text( + + forwardedFrom ?? 'Неизвестный', + style: TextStyle( + fontSize: 13, + fontWeight: FontWeight.bold, + color: textColor.withOpacity(0.9 * messageTextOpacity), + ), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + const SizedBox(height: 6), + + + if (attaches.isNotEmpty) ...[ + ..._buildPhotosWithCaption( + context, + attaches, // Передаем вложения из вложенного сообщения + textColor, + isUltraOptimized, + messageTextOpacity, + ), + const SizedBox(height: 6), + ], + if (text.isNotEmpty) + Text( + text, + style: TextStyle( + color: textColor.withOpacity(0.9 * messageTextOpacity), + fontSize: 14, + ), + ), + ], + ), + ); + } + + Widget _buildVideoPreview({ + required BuildContext context, + required int videoId, + required String messageId, + String? highQualityUrl, + Uint8List? lowQualityBytes, + }) { + final borderRadius = BorderRadius.circular(12); + + + void openFullScreenVideo() async { + + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => const Center(child: CircularProgressIndicator()), + ); + + try { + final videoUrl = await ApiService.instance.getVideoUrl( + videoId, + chatId!, // chatId из `build` + messageId, + ); + + if (!context.mounted) return; // [!code ++] Проверка правильным способом + Navigator.pop(context); // Убираем индикатор + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FullScreenVideoPlayer(videoUrl: videoUrl), + ), + ); + } catch (e) { + if (!context.mounted) return; // [!code ++] Проверка правильным способом + Navigator.pop(context); // Убираем индикатор + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Не удалось загрузить видео: $e'), + backgroundColor: Colors.red, + ), + ); + } + } + + + return GestureDetector( + onTap: openFullScreenVideo, + child: AspectRatio( + aspectRatio: 16 / 9, + child: ClipRRect( + borderRadius: borderRadius, + child: Stack( + alignment: Alignment.center, + fit: StackFit.expand, + children: [ + + + (highQualityUrl != null && highQualityUrl.isNotEmpty) || + (lowQualityBytes != null) + ? _ProgressiveNetworkImage( + url: + highQualityUrl ?? + '', // _ProgressiveNetworkImage теперь это выдержит + previewBytes: lowQualityBytes, + width: 220, + height: 160, + fit: BoxFit.cover, + keepAlive: false, + ) + + : Container( + color: Colors.black26, + child: const Center( + child: Icon( + Icons.video_library_outlined, + color: Colors.white, + size: 40, + ), + ), + ), + + + + Container( + decoration: BoxDecoration( + + color: Colors.black.withOpacity(0.15), + ), + child: Icon( + Icons.play_circle_filled_outlined, + color: Colors.white.withOpacity(0.95), + size: 50, + shadows: const [ + Shadow( + color: Colors.black38, + blurRadius: 4, + offset: Offset(0, 2), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + Widget _buildReplyPreview( + BuildContext context, + Map link, + Color textColor, + double messageTextOpacity, + bool isUltraOptimized, + double messageBorderRadius, + ) { + final replyMessage = link['message'] as Map?; + if (replyMessage == null) return const SizedBox.shrink(); + + final replyText = replyMessage['text'] as String? ?? ''; + final replySenderId = replyMessage['sender'] as int?; + final replyMessageId = replyMessage['id'] as String?; + + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + Color replyAccentColor; + if (useAutoReplyColor) { + replyAccentColor = _getUserColor(replySenderId ?? 0, context); + } else { + replyAccentColor = + customReplyColor ?? + (isDarkMode ? const Color(0xFF90CAF9) : const Color(0xFF1976D2)); + } + + + final textLength = replyText.length; + final minWidth = 120.0; // Минимальная ширина для коротких сообщений + + + double adaptiveWidth = minWidth; + if (textLength > 0) { + + adaptiveWidth = (textLength * 8.0 + 32).clamp(minWidth, double.infinity); + } + + return GestureDetector( + onTap: () { + + if (replyMessageId != null && onReplyTap != null) { + onReplyTap!(replyMessageId); + } + }, + child: Container( + constraints: BoxConstraints(minWidth: minWidth, minHeight: 40), + width: adaptiveWidth, // Используем адаптивную ширину + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), + decoration: BoxDecoration( + color: isDarkMode + ? replyAccentColor.withOpacity( + 0.15, + ) // Полупрозрачный фон для темной темы + : replyAccentColor.withOpacity( + 0.08, + ), // Более прозрачный для светлой + borderRadius: BorderRadius.circular( + (isUltraOptimized ? 4 : messageBorderRadius) * 0.3, + ), + border: Border( + left: BorderSide( + color: replyAccentColor, // Цвет левой границы + width: 2, + ), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.reply, size: 12, color: replyAccentColor), + const SizedBox(width: 4), + Expanded( + child: Text( + replySenderId != null + ? (contactDetailsCache?[replySenderId]?.name ?? + 'Участник $replySenderId') + : 'Неизвестный', + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.w600, + color: replyAccentColor, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + const SizedBox(height: 2), + + Align( + alignment: Alignment.centerLeft, + child: Text( + replyText.isNotEmpty ? replyText : 'Фото', + style: const TextStyle(fontSize: 11, color: Colors.white), + maxLines: 2, + overflow: TextOverflow.ellipsis, + softWrap: true, + textAlign: TextAlign.left, + ), + ), + ], + ), + ), + ); + } + /* + void _showMessageContextMenu(BuildContext context) { + + const reactions = [ + '👍', + '❤️', + '😂', + '🔥', + '👏', + '👌', + '🎉', + '🥰', + '😍', + '🙏', + '🤔', + '🤯', + '💯', + '⚡️', + '🤟', + '🌚', + '🌝', + '🥱', + '🤣', + '🫠', + '🫡', + '🐱', + '💋', + '😘', + '🐶', + '🤝', + '⭐️', + '🍷', + '🍑', + '😁', + '🤷‍♀️', + '🤷‍♂️', + '👩‍❤️‍👨', + '🦄', + '👻', + '🗿', + '❤️‍🩹', + '🛑', + '⛄️', + '❓', + '🙄', + '❗️', + '😉', + '😳', + '🥳', + '😎', + '💪', + '👀', + '🤞', + '🤤', + '🤪', + '🤩', + '😴', + '😐', + '😇', + '🖤', + '👑', + '👋', + '👁️', + ]; + + + final hasUserReaction = + message.reactionInfo != null && + message.reactionInfo!['yourReaction'] != null; + + showModalBottomSheet( + context: context, + backgroundColor: Colors + .transparent, // Фон делаем прозрачным, чтобы скругление было видно + builder: (context) => Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + ), + child: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + + if (onReaction != null) ...[ + + SizedBox( + height: 80, // Задаем высоту для ряда с реакциями + child: SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 12.0, + ), + child: Row( + children: [ + ...reactions.map( + (emoji) => Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4.0, + ), + child: GestureDetector( + onTap: () { + Navigator.pop(context); + onReaction!(emoji); + }, + child: Text( + emoji, + style: const TextStyle(fontSize: 32), + ), + ), + ), + ), + ], + ), + ), + ), + + if (hasUserReaction && onRemoveReaction != null) ...[ + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: () { + Navigator.pop(context); + onRemoveReaction!(); + }, + icon: const Icon(Icons.remove_circle_outline), + label: const Text('Убрать реакцию'), + style: ElevatedButton.styleFrom( + backgroundColor: Theme.of( + context, + ).colorScheme.errorContainer, + foregroundColor: Theme.of( + context, + ).colorScheme.onErrorContainer, + ), + ), + ), + ), + ], + const Divider(height: 1), + ], + + if (onReply != null) + ListTile( + leading: const Icon(Icons.reply), + title: const Text('Ответить'), + onTap: () { + Navigator.pop(context); + onReply!(); + }, + ), + if (onEdit != null) + ListTile( + leading: Icon( + canEditMessage == false ? Icons.edit_off : Icons.edit, + color: canEditMessage == false ? Colors.grey : null, + ), + title: Text( + canEditMessage == false + ? 'Редактировать (недоступно)' + : 'Редактировать', + style: TextStyle( + color: canEditMessage == false ? Colors.grey : null, + ), + ), + onTap: canEditMessage == false + ? null + : () { + Navigator.pop(context); + onEdit!(); + }, + ), + if (onDeleteForMe != null || + onDeleteForAll != null || + onDelete != null) ...[ + if (onEdit != null) const Divider(height: 1), + if (onDeleteForMe != null) + ListTile( + leading: const Icon( + Icons.person_remove, + color: Colors.redAccent, + ), + title: const Text( + 'Удалить у меня', + style: TextStyle(color: Colors.redAccent), + ), + onTap: () { + Navigator.pop(context); + onDeleteForMe?.call(); + }, + ), + if (onDeleteForAll != null) + ListTile( + leading: const Icon( + Icons.delete_forever, + color: Colors.red, + ), + title: const Text( + 'Удалить у всех', + style: TextStyle(color: Colors.red), + ), + onTap: () { + Navigator.pop(context); + onDeleteForAll?.call(); + }, + ), + if (onDelete != null && + onDeleteForMe == null && + onDeleteForAll == null) + ListTile( + leading: const Icon(Icons.delete, color: Colors.red), + title: const Text( + 'Удалить', + style: TextStyle(color: Colors.red), + ), + onTap: () { + Navigator.pop(context); + onDelete!.call(); + }, + ), + ], + ], + ), + ), + ), + ); + } + */ + + void _showMessageContextMenu(BuildContext context, Offset tapPosition) { + final hasUserReaction = message.reactionInfo?['yourReaction'] != null; + + showDialog( + context: context, + barrierColor: Colors.transparent, // Делаем фон прозрачным + builder: (context) { + return _MessageContextMenu( + message: message, + position: tapPosition, + onReply: onReply, + onEdit: onEdit, + onDeleteForMe: onDeleteForMe, + onDeleteForAll: onDeleteForAll, + onReaction: onReaction, + onRemoveReaction: onRemoveReaction, + canEditMessage: canEditMessage ?? false, + hasUserReaction: hasUserReaction, + ); + }, + ); + } + + Widget _buildReactionsWidget(BuildContext context, Color textColor) { + if (message.reactionInfo == null || + message.reactionInfo!['counters'] == null) { + return const SizedBox.shrink(); + } + + final counters = message.reactionInfo!['counters'] as List; + if (counters.isEmpty) { + return const SizedBox.shrink(); + } + + return Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Wrap( + spacing: 4.0, + runSpacing: 4.0, + alignment: isMe ? WrapAlignment.end : WrapAlignment.start, + children: counters.map((counter) { + final emoji = counter['reaction'] as String; + final count = counter['count'] as int; + final isUserReaction = message.reactionInfo!['yourReaction'] == emoji; + + return GestureDetector( + onTap: () { + if (isUserReaction) { + + onRemoveReaction?.call(); + } else { + + onReaction?.call(emoji); + } + }, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: isUserReaction + ? Theme.of(context).colorScheme.primary.withOpacity(0.3) + : textColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(16), + ), + child: Text( + '$emoji $count', + style: TextStyle( + fontSize: 12, + fontWeight: isUserReaction + ? FontWeight.w600 + : FontWeight.w500, + color: isUserReaction + ? Theme.of(context).colorScheme.primary + : textColor.withOpacity(0.9), + ), + ), + ), + ); + }).toList(), + ), + ); + } + + Widget build(BuildContext context) { + final themeProvider = Provider.of(context); + final isUltraOptimized = themeProvider.ultraOptimizeChats; + + final isStickerOnly = + message.attaches.length == 1 && + message.attaches.any((a) => a['_type'] == 'STICKER') && + message.text.isEmpty; + if (isStickerOnly) { + return _buildStickerOnlyMessage(context); + } + + final hasUnsupportedContent = _hasUnsupportedMessageTypes(); + + final messageOpacity = themeProvider.messageBubbleOpacity; + final messageTextOpacity = themeProvider.messageTextOpacity; + final messageShadowIntensity = themeProvider.messageShadowIntensity; + final messageBorderRadius = themeProvider.messageBorderRadius; + + final bubbleColor = _getBubbleColor(isMe, themeProvider, messageOpacity); + final textColor = _getTextColor( + isMe, + bubbleColor, + messageTextOpacity, + context, + ); + final bubbleDecoration = _createBubbleDecoration( + bubbleColor, + messageBorderRadius, + messageShadowIntensity, + ); + + if (hasUnsupportedContent) { + return _buildUnsupportedMessage( + context, + bubbleColor, + textColor, + bubbleDecoration, + ); + } + + final baseTextStyle = + Theme.of(context).textTheme.bodyMedium ?? const TextStyle(); + final defaultTextStyle = baseTextStyle.copyWith(color: textColor); + final linkColor = _getLinkColor(bubbleColor, isMe); + final linkStyle = baseTextStyle.copyWith( + color: linkColor, + decoration: TextDecoration.underline, + decorationColor: linkColor, + ); + + Future _onOpenLink(LinkableElement link) async { + final uri = Uri.parse(link.url); + if (await canLaunchUrl(uri)) { + await launchUrl(uri, mode: LaunchMode.externalApplication); + } else { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Не удалось открыть ссылку: ${link.url}')), + ); + } + } + } + + void _onSenderNameTap() { + openUserProfileById(context, message.senderId); + } + + final messageContentChildren = _buildMessageContentChildren( + context, + textColor, + messageTextOpacity, + isUltraOptimized, + linkStyle, + defaultTextStyle, + messageBorderRadius, + _onOpenLink, + _onSenderNameTap, + ); + + Widget messageContent = _buildMessageContentInner( + context, + bubbleDecoration, + messageContentChildren, + ); + + if (onReaction != null || (isMe && (onEdit != null || onDelete != null))) { + messageContent = GestureDetector( + onTapDown: (TapDownDetails details) { + _showMessageContextMenu(context, details.globalPosition); + }, + child: messageContent, + ); + } + + return Column( + crossAxisAlignment: isMe + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: isMe + ? MainAxisAlignment.end + : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (!isMe && isGroupChat && !isChannel) ...[ + SizedBox( + width: 40, + child: isLastInGroup + ? Transform.translate( + offset: Offset(0, avatarVerticalOffset), + child: _buildSenderAvatar(), + ) + : null, + ), + ], + Flexible(child: messageContent), + ], + ), + ], + ); + } + + List _buildInlineKeyboard( + BuildContext context, + List> attaches, + Color textColor, + ) { + + final keyboardAttach = attaches.firstWhere( + (a) => a['_type'] == 'INLINE_KEYBOARD', + orElse: () => + {}, // Возвращаем пустую карту, если не найдено + ); + + if (keyboardAttach.isEmpty) { + return []; // Нет клавиатуры + } + + + final keyboardData = keyboardAttach['keyboard'] as Map?; + final buttonRows = keyboardData?['buttons'] as List?; + + if (buttonRows == null || buttonRows.isEmpty) { + return []; // Нет кнопок + } + + final List rows = []; + + + for (final row in buttonRows) { + if (row is List && row.isNotEmpty) { + final List buttonsInRow = []; + + + for (final buttonData in row) { + if (buttonData is Map) { + final String? text = buttonData['text'] as String?; + final String? type = buttonData['type'] as String?; + final String? url = buttonData['url'] as String?; + + + if (text != null && type == 'LINK' && url != null) { + buttonsInRow.add( + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 2.0), + child: FilledButton( + onPressed: () => + _launchURL(context, url), // Открываем ссылку + style: FilledButton.styleFrom( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 12, + ), + + backgroundColor: textColor.withOpacity(0.1), + foregroundColor: textColor.withOpacity(0.9), + ), + child: Text( + text, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ), + ); + } + } + } + + + if (buttonsInRow.isNotEmpty) { + rows.add( + Padding( + padding: const EdgeInsets.only(top: 4.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: buttonsInRow, + ), + ), + ); + } + } + } + + + if (rows.isNotEmpty) { + return [ + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Column(children: rows), + ), + ]; + } + + return []; + } + + + Future _launchURL(BuildContext context, String url) async { + final uri = Uri.parse(url); + if (await canLaunchUrl(uri)) { + await launchUrl(uri, mode: LaunchMode.externalApplication); + } else { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Не удалось открыть ссылку: $url'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + bool _hasUnsupportedMessageTypes() { + final hasUnsupportedAttachments = message.attaches.any((attach) { + final type = attach['_type']?.toString().toUpperCase(); + return type == 'AUDIO' || + type == 'VOICE' || + type == 'GIF' || + type == 'LOCATION' || + type == 'CONTACT'; + }); + + return hasUnsupportedAttachments; + } + + Widget _buildUnsupportedMessage( + BuildContext context, + Color bubbleColor, + Color textColor, + BoxDecoration bubbleDecoration, + ) { + return Column( + crossAxisAlignment: isMe + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: isMe + ? MainAxisAlignment.end + : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (!isMe && isGroupChat && !isChannel) ...[ + + SizedBox( + width: 40, + child: + isLastInGroup //Если это соо в группе, и оно последнее в группе соо + ? Transform.translate( + offset: Offset(0, avatarVerticalOffset), + child: _buildSenderAvatar(), + ) + : null, + ), + ], + Flexible( + child: Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.65, + ), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 8, + ), + margin: _getMessageMargin(context), + decoration: bubbleDecoration, + child: Column( + crossAxisAlignment: isMe + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + + if (isGroupChat && !isMe && senderName != null) + Padding( + padding: const EdgeInsets.only(left: 2.0, bottom: 2.0), + child: Text( + senderName ?? 'Неизвестный', + style: TextStyle( + fontWeight: FontWeight.bold, + color: _getUserColor( + message.senderId, + context, + ).withOpacity(0.8), + fontSize: 12, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + if (isGroupChat && !isMe && senderName != null) + const SizedBox(height: 4), + + Text( + 'Это сообщение не поддерживается в Вашей версии Komet. ' + 'Пожалуйста, обновитесь до последней версии. ' + 'Если Вы уже используете свежую версию приложения, ' + 'возможно, в сообщении используется нововведение, ' + 'которое пока не поддерживается.', + style: TextStyle( + color: textColor, + fontStyle: FontStyle.italic, + fontSize: 14, + ), + textAlign: TextAlign.left, + ), + + const SizedBox(height: 8.0), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isMe) ...[ + if (message.isEdited) ...[ + Text( + '(изменено)', + style: TextStyle( + fontSize: 10, + color: textColor.withOpacity(0.5), + fontStyle: FontStyle.italic, + ), + ), + const SizedBox(width: 6), + ], + Text( + _formatMessageTime(context, message.time), + style: TextStyle( + fontSize: 12, + color: + Theme.of(context).brightness == + Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280), + ), + ), + ], + if (!isMe) ...[ + Text( + _formatMessageTime(context, message.time), + style: TextStyle( + fontSize: 12, + color: + Theme.of(context).brightness == + Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280), + ), + ), + if (message.isEdited) ...[ + const SizedBox(width: 6), + Text( + '(изменено)', + style: TextStyle( + fontSize: 10, + color: textColor.withOpacity(0.5), + fontStyle: FontStyle.italic, + ), + ), + ], + ], + ], + ), + ], + ), + ), + ), + ], + ), + ], + ); + } + + Widget _buildStickerOnlyMessage(BuildContext context) { + final sticker = message.attaches.firstWhere((a) => a['_type'] == 'STICKER'); + final stickerSize = 250.0; + + final timeColor = Theme.of(context).brightness == Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280); + + return Column( + crossAxisAlignment: isMe + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: isMe + ? MainAxisAlignment.end + : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (!isMe && isGroupChat && !isChannel) ...[ + SizedBox( + width: 40, + child: isLastInGroup + ? Transform.translate( + offset: Offset(0, avatarVerticalOffset), + child: _buildSenderAvatar(), + ) + : null, + ), + ], + Column( + crossAxisAlignment: isMe + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + GestureDetector( + onTap: () => _openPhotoViewer(context, sticker), + child: ConstrainedBox( + constraints: BoxConstraints( + maxWidth: stickerSize, + maxHeight: stickerSize, + ), + child: _buildStickerImage(context, sticker), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 4, right: 6), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _formatMessageTime(context, message.time), + style: TextStyle(fontSize: 12, color: timeColor), + ), + ], + ), + ), + ], + ), + ], + ), + ], + ); + } + + Widget _buildStickerImage( + BuildContext context, + Map sticker, + ) { + final url = sticker['url'] ?? sticker['baseUrl']; + + if (url is String && url.isNotEmpty) { + if (url.startsWith('file://')) { + final path = url.replaceFirst('file://', ''); + return Image.file( + File(path), + fit: BoxFit.contain, + filterQuality: FilterQuality.high, + ); + } else { + return Image.network( + url, + fit: BoxFit.contain, + filterQuality: FilterQuality.high, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) { + return child; + } + return const Center(child: CircularProgressIndicator()); + }, + errorBuilder: (context, error, stackTrace) { + return _imagePlaceholder(); + }, + ); + } + } + + return _imagePlaceholder(); + } + + String? _extractFirstPhotoUrl(List> attaches) { + for (final a in attaches) { + if (a['_type'] == 'PHOTO') { + final dynamic maybe = a['url'] ?? a['baseUrl']; + if (maybe is String && maybe.isNotEmpty) return maybe; + } + } + return null; + } + + List _buildPhotosWithCaption( + BuildContext context, + List> attaches, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + ) { + final photos = attaches.where((a) => a['_type'] == 'PHOTO').toList(); + final List widgets = []; + + if (photos.isEmpty) return widgets; + + + widgets.add( + _buildSmartPhotoGroup(context, photos, textColor, isUltraOptimized), + ); + + widgets.add(const SizedBox(height: 6)); + + return widgets; + } + + List _buildVideosWithCaption( + BuildContext context, + List> attaches, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + ) { + final videos = attaches.where((a) => a['_type'] == 'VIDEO').toList(); + final List widgets = []; + + if (videos.isEmpty) return widgets; + + for (final video in videos) { + + final videoId = video['videoId'] as int?; + final previewData = video['previewData'] as String?; // Блюр-превью + final thumbnailUrl = + video['url'] ?? video['baseUrl'] as String?; // HQ-превью URL + + + Uint8List? previewBytes; + if (previewData != null && previewData.startsWith('data:')) { + final idx = previewData.indexOf('base64,'); + if (idx != -1) { + final b64 = previewData.substring(idx + 7); + try { + previewBytes = base64Decode(b64); + } catch (_) {} + } + } + + + String? highQualityThumbnailUrl; + if (thumbnailUrl != null && thumbnailUrl.isNotEmpty) { + highQualityThumbnailUrl = thumbnailUrl; + if (!thumbnailUrl.contains('?')) { + highQualityThumbnailUrl = + '$thumbnailUrl?size=medium&quality=high&format=jpeg'; + } else { + highQualityThumbnailUrl = + '$thumbnailUrl&size=medium&quality=high&format=jpeg'; + } + } + + + if (videoId != null && chatId != null) { + widgets.add( + Padding( + padding: const EdgeInsets.only(bottom: 4.0), + child: _buildVideoPreview( + context: context, + videoId: videoId, + messageId: message.id, + highQualityUrl: highQualityThumbnailUrl, + lowQualityBytes: previewBytes, + ), + ), + ); + } else { + + widgets.add( + Container( + padding: const EdgeInsets.all(16), + color: Colors.black12, + child: Row( + children: [ + Icon(Icons.videocam_off, color: textColor), + const SizedBox(width: 8), + Text( + 'Видео повреждено (нет ID)', + style: TextStyle(color: textColor), + ), + ], + ), + ), + ); + } + } + + widgets.add(const SizedBox(height: 6)); + return widgets; + } + + List _buildStickersWithCaption( + BuildContext context, + List> attaches, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + ) { + final stickers = attaches.where((a) => a['_type'] == 'STICKER').toList(); + final List widgets = []; + + if (stickers.isEmpty) return widgets; + + for (final sticker in stickers) { + widgets.add( + _buildStickerWidget(context, sticker, textColor, isUltraOptimized), + ); + widgets.add(const SizedBox(height: 6)); + } + + return widgets; + } + + Widget _buildStickerWidget( + BuildContext context, + Map sticker, + Color textColor, + bool isUltraOptimized, + ) { + + final stickerSize = 250.0; + + return ConstrainedBox( + constraints: BoxConstraints( + maxWidth: stickerSize, + maxHeight: stickerSize, + ), + child: GestureDetector( + onTap: () => _openPhotoViewer(context, sticker), + child: ClipRRect( + borderRadius: BorderRadius.circular(isUltraOptimized ? 8 : 12), + child: _buildPhotoWidget(context, sticker), + ), + ), + ); + } + + List _buildCallsWithCaption( + BuildContext context, + List> attaches, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + ) { + final calls = attaches.where((a) { + final type = a['_type']; + return type == 'CALL' || type == 'call'; + }).toList(); + final List widgets = []; + + if (calls.isEmpty) return widgets; + + for (final call in calls) { + widgets.add( + _buildCallWidget( + context, + call, + textColor, + isUltraOptimized, + messageTextOpacity, + ), + ); + widgets.add(const SizedBox(height: 6)); + } + + return widgets; + } + + Widget _buildCallWidget( + BuildContext context, + Map callData, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + ) { + final hangupType = callData['hangupType'] as String? ?? ''; + final callType = callData['callType'] as String? ?? 'AUDIO'; + final duration = callData['duration'] as int? ?? 0; + final borderRadius = BorderRadius.circular(isUltraOptimized ? 8 : 12); + + String callText; + IconData callIcon; + Color callColor; + + + switch (hangupType) { + case 'HUNGUP': + + final minutes = duration ~/ 60000; + final seconds = (duration % 60000) ~/ 1000; + final durationText = minutes > 0 + ? '$minutes:${seconds.toString().padLeft(2, '0')}' + : '$seconds сек'; + + final callTypeText = callType == 'VIDEO' ? 'Видеозвонок' : 'Звонок'; + callText = '$callTypeText, $durationText'; + callIcon = callType == 'VIDEO' ? Icons.videocam : Icons.call; + callColor = Theme.of(context).colorScheme.primary; + break; + + case 'MISSED': + + final callTypeText = callType == 'VIDEO' + ? 'Пропущенный видеозвонок' + : 'Пропущенный звонок'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_missed; + callColor = Theme.of(context).colorScheme.error; + break; + + case 'CANCELED': + + final callTypeText = callType == 'VIDEO' + ? 'Видеозвонок отменен' + : 'Звонок отменен'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_end; + callColor = textColor.withOpacity(0.6); + break; + + case 'REJECTED': + + final callTypeText = callType == 'VIDEO' + ? 'Видеозвонок отклонен' + : 'Звонок отклонен'; + callText = callTypeText; + callIcon = callType == 'VIDEO' ? Icons.videocam_off : Icons.call_end; + callColor = textColor.withOpacity(0.6); + break; + + default: + + callText = callType == 'VIDEO' ? 'Видеозвонок' : 'Звонок'; + callIcon = callType == 'VIDEO' ? Icons.videocam : Icons.call; + callColor = textColor.withOpacity(0.6); + break; + } + + return Container( + decoration: BoxDecoration( + color: callColor.withOpacity(0.1), + borderRadius: borderRadius, + border: Border.all(color: callColor.withOpacity(0.3), width: 1), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Row( + children: [ + + Container( + width: 48, + height: 48, + decoration: BoxDecoration( + color: callColor.withOpacity(0.2), + borderRadius: BorderRadius.circular(8), + ), + child: Icon(callIcon, color: callColor, size: 24), + ), + const SizedBox(width: 12), + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + callText, + style: TextStyle( + color: callColor, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ), + ], + ), + ), + ); + } + + List _buildFilesWithCaption( + BuildContext context, + List> attaches, + Color textColor, + bool isUltraOptimized, + double messageTextOpacity, + int? chatId, + ) { + final files = attaches.where((a) => a['_type'] == 'FILE').toList(); + final List widgets = []; + + if (files.isEmpty) return widgets; + + for (final file in files) { + final fileName = file['name'] ?? 'Файл'; + final fileSize = file['size'] as int? ?? 0; + + widgets.add( + _buildFileWidget( + context, + fileName, + fileSize, + file, + textColor, + isUltraOptimized, + chatId, + ), + ); + widgets.add(const SizedBox(height: 6)); + } + + return widgets; + } + + Widget _buildFileWidget( + BuildContext context, + String fileName, + int fileSize, + Map fileData, + Color textColor, + bool isUltraOptimized, + int? chatId, + ) { + final borderRadius = BorderRadius.circular(isUltraOptimized ? 8 : 12); + + + final extension = _getFileExtension(fileName); + final iconData = _getFileIcon(extension); + + + final sizeStr = _formatFileSize(fileSize); + + + final fileId = fileData['fileId'] as int?; + final token = fileData['token'] as String?; + + return GestureDetector( + onTap: () => + _handleFileDownload(context, fileId, token, fileName, chatId), + child: Container( + decoration: BoxDecoration( + color: textColor.withOpacity(0.05), + borderRadius: borderRadius, + border: Border.all(color: textColor.withOpacity(0.1), width: 1), + ), + child: Padding( + padding: const EdgeInsets.all(12), + child: Row( + children: [ + + Container( + width: 48, + height: 48, + decoration: BoxDecoration( + color: textColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + ), + child: Icon( + iconData, + color: textColor.withOpacity(0.8), + size: 24, + ), + ), + const SizedBox(width: 12), + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + fileName, + style: TextStyle( + color: textColor, + fontSize: 14, + fontWeight: FontWeight.w500, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 4), + if (fileId != null) + ValueListenableBuilder( + valueListenable: FileDownloadProgressService() + .getProgress(fileId.toString()), + builder: (context, progress, child) { + if (progress < 0) { + + return Text( + sizeStr, + style: TextStyle( + color: textColor.withOpacity(0.6), + fontSize: 12, + ), + ); + } else if (progress < 1.0) { + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LinearProgressIndicator( + value: progress, + minHeight: 3, + backgroundColor: textColor.withOpacity(0.1), + ), + const SizedBox(height: 4), + Text( + '${(progress * 100).toStringAsFixed(0)}%', + style: TextStyle( + color: textColor.withOpacity(0.6), + fontSize: 11, + ), + ), + ], + ); + } else { + + return Row( + children: [ + Icon( + Icons.check_circle, + size: 12, + color: Colors.green.withOpacity(0.8), + ), + const SizedBox(width: 4), + Text( + 'Загружено', + style: TextStyle( + color: Colors.green.withOpacity(0.8), + fontSize: 11, + ), + ), + ], + ); + } + }, + ) + else + Text( + sizeStr, + style: TextStyle( + color: textColor.withOpacity(0.6), + fontSize: 12, + ), + ), + ], + ), + ), + + if (fileId != null) + ValueListenableBuilder( + valueListenable: FileDownloadProgressService().getProgress( + fileId.toString(), + ), + builder: (context, progress, child) { + if (progress >= 0 && progress < 1.0) { + return const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator(strokeWidth: 2), + ); + } + return Icon( + Icons.download_outlined, + color: textColor.withOpacity(0.6), + size: 20, + ); + }, + ) + else + Icon( + Icons.download_outlined, + color: textColor.withOpacity(0.6), + size: 20, + ), + ], + ), + ), + ), + ); + } + + String _getFileExtension(String fileName) { + final parts = fileName.split('.'); + if (parts.length > 1) { + return parts.last.toLowerCase(); + } + return ''; + } + + IconData _getFileIcon(String extension) { + switch (extension) { + case 'pdf': + return Icons.picture_as_pdf; + case 'doc': + case 'docx': + return Icons.description; + case 'xls': + case 'xlsx': + return Icons.table_chart; + case 'txt': + return Icons.text_snippet; + case 'zip': + case 'rar': + case '7z': + return Icons.archive; + case 'mp3': + case 'wav': + case 'flac': + return Icons.audiotrack; + case 'mp4': + case 'avi': + case 'mov': + return Icons.video_file; + case 'jpg': + case 'jpeg': + case 'png': + case 'gif': + return Icons.image; + default: + return Icons.insert_drive_file; + } + } + + String _formatFileSize(int bytes) { + if (bytes < 1024) { + return '$bytes B'; + } else if (bytes < 1024 * 1024) { + return '${(bytes / 1024).toStringAsFixed(1)} KB'; + } else if (bytes < 1024 * 1024 * 1024) { + return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; + } else { + return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; + } + } + + Future _handleFileDownload( + BuildContext context, + int? fileId, + String? token, + String fileName, + int? chatId, + ) async { + + if (fileId == null) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Не удалось загрузить информацию о файле (нет fileId)', + ), + backgroundColor: Colors.red, + ), + ); + } + return; + } + + try { + final prefs = await SharedPreferences.getInstance(); + final fileIdMap = prefs.getStringList('file_id_to_path_map') ?? []; + final fileIdString = fileId.toString(); + + + final mapping = fileIdMap.firstWhere( + (m) => m.startsWith('$fileIdString:'), + orElse: () => '', // Возвращаем пустую строку, если не найдено + ); + + if (mapping.isNotEmpty) { + + final filePath = mapping.substring(fileIdString.length + 1); + final file = io.File(filePath); + + + if (await file.exists()) { + print( + 'Файл $fileName (ID: $fileId) найден локально: $filePath. Открываем...', + ); + + final result = await OpenFile.open(filePath); + + if (result.type != ResultType.done && context.mounted) { + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Не удалось открыть файл: ${result.message}'), + backgroundColor: Colors.red, + ), + ); + } + return; // Важно: выходим из функции, чтобы не скачивать заново + } else { + + print( + 'Файл $fileName (ID: $fileId) был в SharedPreferences, но удален. Начинаем загрузку.', + ); + fileIdMap.remove(mapping); + await prefs.setStringList('file_id_to_path_map', fileIdMap); + } + } + } catch (e) { + print('Ошибка при проверке локального файла: $e. Продолжаем загрузку...'); + + } + + + print( + 'Файл $fileName (ID: $fileId) не найден. Запрашиваем URL у сервера...', + ); + + if (token == null) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text( + 'Не удалось загрузить информацию о файле (нет token)', + ), + backgroundColor: Colors.red, + ), + ); + } + return; + } + + if (chatId == null) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Не удалось определить чат'), + backgroundColor: Colors.red, + ), + ); + } + return; + } + + try { + + final messageId = message.id; + + + final seq = ApiService.instance.sendRawRequest(88, { + "fileId": fileId, + "chatId": chatId, + "messageId": messageId, + }); + + if (seq == -1) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Не удалось отправить запрос на получение файла'), + backgroundColor: Colors.red, + ), + ); + } + return; + } + + + final response = await ApiService.instance.messages + .firstWhere( + (msg) => msg['seq'] == seq && msg['opcode'] == 88, + orElse: () => {}, + ) + .timeout( + const Duration(seconds: 10), + onTimeout: () => throw TimeoutException( + 'Превышено время ожидания ответа от сервера', + ), + ); + + if (response.isEmpty || response['payload'] == null) { + throw Exception('Не получен ответ от сервера'); + } + + final downloadUrl = response['payload']['url'] as String?; + if (downloadUrl == null || downloadUrl.isEmpty) { + throw Exception('Не получена ссылка на файл'); + } + + + await _downloadFile(downloadUrl, fileName, fileId.toString(), context); + } catch (e) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при скачивании файла: ${e.toString()}'), + backgroundColor: Colors.red, + ), + ); + } + } + } + + Future _downloadFile( + String url, + String fileName, + String fileId, + BuildContext context, + ) async { + + _startBackgroundDownload(url, fileName, fileId, context); + + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Начато скачивание файла...'), + duration: Duration(seconds: 2), + ), + ); + } + } + + void _startBackgroundDownload( + String url, + String fileName, + String fileId, + BuildContext context, + ) async { + + FileDownloadProgressService().updateProgress(fileId, 0.0); + + try { + + io.Directory? downloadDir; + + if (io.Platform.isAndroid) { + downloadDir = await getExternalStorageDirectory(); + } else if (io.Platform.isIOS) { + final directory = await getApplicationDocumentsDirectory(); + downloadDir = directory; + } else if (io.Platform.isWindows || io.Platform.isLinux) { + + final homeDir = + io.Platform.environment['HOME'] ?? + io.Platform.environment['USERPROFILE'] ?? + ''; + downloadDir = io.Directory('$homeDir/Downloads'); + } else { + downloadDir = await getApplicationDocumentsDirectory(); + } + + if (downloadDir == null || !await downloadDir.exists()) { + throw Exception('Downloads directory not found'); + } + + + final filePath = '${downloadDir.path}/$fileName'; + final file = io.File(filePath); + + + final request = http.Request('GET', Uri.parse(url)); + final streamedResponse = await request.send(); + + if (streamedResponse.statusCode != 200) { + throw Exception( + 'Failed to download file: ${streamedResponse.statusCode}', + ); + } + + final contentLength = streamedResponse.contentLength ?? 0; + final bytes = []; + int received = 0; + + await for (final chunk in streamedResponse.stream) { + bytes.addAll(chunk); + received += chunk.length; + + + if (contentLength > 0) { + final progress = received / contentLength; + FileDownloadProgressService().updateProgress(fileId, progress); + } + } + + + final data = Uint8List.fromList(bytes); + await file.writeAsBytes(data); + + + FileDownloadProgressService().updateProgress(fileId, 1.0); + + + final prefs = await SharedPreferences.getInstance(); + final List downloadedFiles = + prefs.getStringList('downloaded_files') ?? []; + if (!downloadedFiles.contains(file.path)) { + downloadedFiles.add(file.path); + await prefs.setStringList('downloaded_files', downloadedFiles); + } + + + final fileIdMap = prefs.getStringList('file_id_to_path_map') ?? []; + final mappingKey = '$fileId:${file.path}'; + if (!fileIdMap.contains(mappingKey)) { + fileIdMap.add(mappingKey); + await prefs.setStringList('file_id_to_path_map', fileIdMap); + } + + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Файл сохранен: $fileName'), + duration: const Duration(seconds: 3), + action: SnackBarAction(label: 'OK', onPressed: () {}), + ), + ); + } + } catch (e) { + + FileDownloadProgressService().clearProgress(fileId); + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при скачивании: ${e.toString()}'), + backgroundColor: Colors.red, + duration: const Duration(seconds: 3), + ), + ); + } + } + } + + Widget _buildSmartPhotoGroup( + BuildContext context, + List> photos, + Color textColor, + bool isUltraOptimized, + ) { + final borderRadius = BorderRadius.circular(isUltraOptimized ? 4 : 12); + + switch (photos.length) { + case 1: + return _buildSinglePhoto(context, photos[0], borderRadius); + case 2: + return _buildTwoPhotos(context, photos, borderRadius); + case 3: + return _buildThreePhotos(context, photos, borderRadius); + case 4: + return _buildFourPhotos(context, photos, borderRadius); + default: + return _buildManyPhotos(context, photos, borderRadius); + } + } + + Widget _buildSinglePhoto( + BuildContext context, + Map photo, + BorderRadius borderRadius, + ) { + return RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photo), + child: ClipRRect( + borderRadius: borderRadius, + child: ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 180, maxWidth: 250), + child: _buildPhotoWidget(context, photo), + ), + ), + ), + ); + } + + Widget _buildTwoPhotos( + BuildContext context, + List> photos, + BorderRadius borderRadius, + ) { + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 180), + child: Row( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[0]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[0]), + ), + ), + ), + ), + const SizedBox(width: 2), + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[1]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[1]), + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildThreePhotos( + BuildContext context, + List> photos, + BorderRadius borderRadius, + ) { + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 180), + child: Row( + children: [ + + Expanded( + flex: 2, + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[0]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[0]), + ), + ), + ), + ), + const SizedBox(width: 2), + + Expanded( + flex: 1, + child: Column( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[1]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[1]), + ), + ), + ), + ), + const SizedBox(height: 2), + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[2]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[2]), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildFourPhotos( + BuildContext context, + List> photos, + BorderRadius borderRadius, + ) { + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 180), + child: Column( + children: [ + + Expanded( + child: Row( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[0]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[0]), + ), + ), + ), + ), + const SizedBox(width: 2), + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[1]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[1]), + ), + ), + ), + ), + ], + ), + ), + const SizedBox(height: 2), + + Expanded( + child: Row( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[2]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[2]), + ), + ), + ), + ), + const SizedBox(width: 2), + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[3]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[3]), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildManyPhotos( + BuildContext context, + List> photos, + BorderRadius borderRadius, + ) { + + return ConstrainedBox( + constraints: const BoxConstraints(maxHeight: 180), + child: Column( + children: [ + Expanded( + child: Row( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[0]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[0]), + ), + ), + ), + ), + const SizedBox(width: 2), + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[1]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[1]), + ), + ), + ), + ), + ], + ), + ), + const SizedBox(height: 2), + Expanded( + child: Row( + children: [ + Expanded( + child: RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[2]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[2]), + ), + ), + ), + ), + const SizedBox(width: 2), + Expanded( + child: Stack( + children: [ + RepaintBoundary( + child: GestureDetector( + onTap: () => _openPhotoViewer(context, photos[3]), + child: ClipRRect( + borderRadius: borderRadius, + child: _buildPhotoWidget(context, photos[3]), + ), + ), + ), + if (photos.length > 4) + Positioned.fill( + child: Container( + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.6), + borderRadius: borderRadius, + ), + child: Center( + child: Text( + '+${photos.length - 3}', + style: const TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ); + } + + void _openPhotoViewer(BuildContext context, Map attach) { + final url = attach['url'] ?? attach['baseUrl']; + final preview = attach['previewData']; + + Widget child; + if (url is String && url.isNotEmpty) { + if (url.startsWith('file://')) { + final path = url.replaceFirst('file://', ''); + child = Image.file( + File(path), + fit: BoxFit.contain, + filterQuality: FilterQuality.high, + ); + } else { + String fullQualityUrl = url; + if (!url.contains('?')) { + fullQualityUrl = '$url?size=original&quality=high&format=original'; + } else { + fullQualityUrl = '$url&size=original&quality=high&format=original'; + } + child = _ProgressiveNetworkImage( + url: fullQualityUrl, + previewBytes: null, + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + fit: BoxFit.contain, + ); + } + } else if (preview is String && preview.startsWith('data:')) { + final idx = preview.indexOf('base64,'); + if (idx != -1) { + final b64 = preview.substring(idx + 7); + try { + final bytes = base64Decode(b64); + child = Image.memory(bytes, fit: BoxFit.contain); + } catch (_) { + child = _imagePlaceholder(); + } + } else { + child = _imagePlaceholder(); + } + } else { + child = _imagePlaceholder(); + } + + + Navigator.of(context).push( + PageRouteBuilder( + opaque: false, // Делаем страницу прозрачной для красивого перехода + barrierColor: Colors.black, + pageBuilder: (BuildContext context, _, __) { + + return FullScreenPhotoViewer(imageChild: child, attach: attach); + }, + + transitionsBuilder: (_, animation, __, page) { + return FadeTransition(opacity: animation, child: page); + }, + ), + ); + } + + Widget _buildPhotoWidget(BuildContext context, Map attach) { + + + Uint8List? previewBytes; + final preview = attach['previewData']; + if (preview is String && preview.startsWith('data:')) { + final idx = preview.indexOf('base64,'); + if (idx != -1) { + final b64 = preview.substring(idx + 7); + try { + previewBytes = base64Decode(b64); + } catch (_) { + + } + } + } + + final url = attach['url'] ?? attach['baseUrl']; + if (url is String && url.isNotEmpty) { + + if (url.startsWith('file://')) { + final path = url.replaceFirst('file://', ''); + return Image.file( + File(path), + fit: BoxFit.cover, + width: 220, + filterQuality: + FilterQuality.medium, // Используем среднее качество для превью + gaplessPlayback: true, + errorBuilder: (context, _, __) => _imagePlaceholder(), + ); + } + + + + String previewQualityUrl = url; + if (!url.contains('?')) { + previewQualityUrl = '$url?size=medium&quality=high&format=jpeg'; + } else { + previewQualityUrl = '$url&size=medium&quality=high&format=jpeg'; + } + + final themeProvider = Provider.of(context, listen: false); + final optimize = + themeProvider.optimizeChats || themeProvider.ultraOptimizeChats; + + + return _ProgressiveNetworkImage( + key: ValueKey(previewQualityUrl), // Ключ по новому URL + url: previewQualityUrl, // Передаем новый URL + previewBytes: + previewBytes, // Передаем размытую заглушку для мгновенного отображения + width: 220, + height: 160, + fit: BoxFit.cover, + keepAlive: !optimize, + startDownloadNextFrame: deferImageLoading, + ); + } + + + if (previewBytes != null) { + return Image.memory(previewBytes, fit: BoxFit.cover, width: 180); + } + + + return _imagePlaceholder(); + } + + Widget _imagePlaceholder() { + return Container( + width: 220, + height: 160, + color: Colors.black12, + alignment: Alignment.center, + child: const Icon(Icons.image_outlined, color: Colors.black38), + ); + } + + + + Color _getBubbleColor( + bool isMe, + ThemeProvider themeProvider, + double messageOpacity, + ) { + final baseColor = isMe + ? (themeProvider.myBubbleColor ?? const Color(0xFF2b5278)) + : (themeProvider.theirBubbleColor ?? const Color(0xFF182533)); + return baseColor.withOpacity(1.0 - messageOpacity); + } + + Color _getTextColor( + bool isMe, + Color bubbleColor, + double messageTextOpacity, + BuildContext context, + ) { + final isDarkMode = Theme.of(context).brightness == Brightness.dark; + + if (isDarkMode) { + return Colors.white; + } else { + return Colors.black; + } + } + + List _buildMessageContentChildren( + BuildContext context, + Color textColor, + double messageTextOpacity, + bool isUltraOptimized, + TextStyle linkStyle, + TextStyle defaultTextStyle, + double messageBorderRadius, + Future Function(LinkableElement) onOpenLink, + VoidCallback onSenderNameTap, + ) { + return [ + if (isGroupChat && !isMe && senderName != null) + MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: onSenderNameTap, + child: Padding( + padding: const EdgeInsets.only(left: 2.0, bottom: 2.0), + child: Text( + senderName ?? 'Неизвестный', + style: TextStyle( + fontWeight: FontWeight.bold, + color: _getUserColor( + message.senderId, + context, + ).withOpacity(0.8), + fontSize: 12, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ), + if (isGroupChat && !isMe && senderName != null) const SizedBox(height: 4), + if (message.isForwarded && message.link != null) ...[ + if (message.link is Map) + _buildForwardedMessage( + context, + message.link as Map, + textColor, + messageTextOpacity, + isUltraOptimized, + ), + ] else ...[ + if (message.isReply && message.link != null) ...[ + if (message.link is Map) + _buildReplyPreview( + context, + message.link as Map, + textColor, + messageTextOpacity, + isUltraOptimized, + messageBorderRadius, + ), + const SizedBox(height: 8), + ], + if (message.attaches.isNotEmpty) ...[ + ..._buildCallsWithCaption( + context, + message.attaches, + textColor, + isUltraOptimized, + messageTextOpacity, + ), + ..._buildPhotosWithCaption( + context, + message.attaches, + textColor, + isUltraOptimized, + messageTextOpacity, + ), + ..._buildVideosWithCaption( + context, + message.attaches, + textColor, + isUltraOptimized, + messageTextOpacity, + ), + ..._buildStickersWithCaption( + context, + message.attaches, + textColor, + isUltraOptimized, + messageTextOpacity, + ), + ..._buildFilesWithCaption( + context, + message.attaches, + textColor, + isUltraOptimized, + messageTextOpacity, + chatId, + ), + const SizedBox(height: 6), + ], + if (message.text.isNotEmpty) ...[ + if (message.text.contains("welcome.saved.dialog.message")) + Container( + alignment: Alignment.center, + child: Text( + 'Привет! Это твои избранные. Все написанное сюда попадёт прямиком к дяде Майору.', + style: TextStyle(color: textColor, fontStyle: FontStyle.italic), + textAlign: TextAlign.center, + ), + ) + else + Linkify( + text: message.text, + style: defaultTextStyle, + linkStyle: linkStyle, + onOpen: onOpenLink, + options: const LinkifyOptions(humanize: false), + textAlign: TextAlign.left, + ), + if (message.reactionInfo != null) const SizedBox(height: 4), + ], + ], + ..._buildInlineKeyboard(context, message.attaches, textColor), + _buildReactionsWidget(context, textColor), + const SizedBox(height: 8.0), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (isMe) ...[ + if (message.attaches.any((a) => a['_type'] == 'PHOTO')) ...[ + Builder( + builder: (context) { + final url = _extractFirstPhotoUrl(message.attaches); + if (url == null || url.startsWith('file://')) { + return const SizedBox.shrink(); + } + final notifier = GlobalImageStore.progressFor(url); + return ValueListenableBuilder( + valueListenable: notifier, + builder: (context, value, _) { + if (value == null || value <= 0 || value >= 1) { + return const SizedBox.shrink(); + } + return SizedBox( + width: 24, + height: 12, + child: LinearProgressIndicator( + value: value, + backgroundColor: Colors.transparent, + color: textColor.withOpacity( + 0.7 * messageTextOpacity, + ), + minHeight: 3, + ), + ); + }, + ); + }, + ), + const SizedBox(width: 8), + ], + if (message.isEdited) ...[ + Text( + '(изменено)', + style: TextStyle( + fontSize: 10, + color: textColor.withOpacity(0.5 * messageTextOpacity), + fontStyle: FontStyle.italic, + ), + ), + const SizedBox(width: 6), + ], + Text( + _formatMessageTime(context, message.time), + style: TextStyle( + fontSize: 12, + color: Theme.of(context).brightness == Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280), + ), + ), + if (readStatus != null) ...[ + const SizedBox(width: 4), + Builder( + builder: (context) { + final bool isRead = readStatus == MessageReadStatus.read; + final Color iconColor = isRead + ? (Theme.of(context).brightness == Brightness.dark + ? Colors.lightBlueAccent[100]! + : Colors.blue[600]!) + : (Theme.of(context).brightness == Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280)); + if (readStatus == MessageReadStatus.sending) { + return _RotatingIcon( + icon: Icons.watch_later_outlined, + size: 16, + color: iconColor, + ); + } else { + return Icon( + isRead ? Icons.done_all : Icons.done, + size: 16, + color: iconColor, + ); + } + }, + ), + ], + ], + if (!isMe) ...[ + Text( + _formatMessageTime(context, message.time), + style: TextStyle( + fontSize: 12, + color: Theme.of(context).brightness == Brightness.dark + ? const Color(0xFF9bb5c7) + : const Color(0xFF6b7280), + ), + ), + if (message.isEdited) ...[ + const SizedBox(width: 6), + Text( + '(изменено)', + style: TextStyle( + fontSize: 10, + color: textColor.withOpacity(0.5 * messageTextOpacity), + fontStyle: FontStyle.italic, + ), + ), + ], + ], + ], + ), + ]; + } + + BoxDecoration _createBubbleDecoration( + Color bubbleColor, + double messageBorderRadius, + double messageShadowIntensity, + ) { + return BoxDecoration( + color: bubbleColor, + borderRadius: BorderRadius.circular(messageBorderRadius), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(messageShadowIntensity), + blurRadius: 8, + spreadRadius: 0, + offset: const Offset(0, 2), + ), + ], + ); + } + + Widget _buildMessageContentInner( + BuildContext context, + BoxDecoration? decoration, + List children, + ) { + return Container( + constraints: BoxConstraints( + maxWidth: MediaQuery.of(context).size.width * 0.65, + ), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + margin: _getMessageMargin(context), + decoration: decoration, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: children, + ), + ); + } + + Color _getLinkColor(Color bubbleColor, bool isMe) { + final isDark = BrightnessExtension( + ThemeData.estimateBrightnessForColor(bubbleColor), + ).isDark; + if (isMe) { + return isDark ? Colors.white : Colors.blue[700]!; + } + return Colors.blue[700]!; + } + + Widget _buildSenderAvatar() { + final senderContact = contactDetailsCache?[message.senderId]; + final avatarUrl = senderContact?.photoBaseUrl; + final contactName = senderContact?.name ?? 'Участник ${message.senderId}'; + + return Builder( + builder: (context) => MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () => openUserProfileById(context, message.senderId), + child: AvatarCacheService().getAvatarWidget( + avatarUrl, + userId: message.senderId, + size: 32, + fallbackText: contactName, + backgroundColor: _getUserColor(message.senderId, context), + textColor: Colors.white, + ), + ), + ), + ); + } +} + +class GlobalImageStore { + static final Map _memory = {}; + static final Map> _progress = {}; + + static Uint8List? getData(String url) => _memory[url]; + static void setData(String url, Uint8List bytes) { + _memory[url] = bytes; + progressFor(url).value = null; + } + + static ValueNotifier progressFor(String url) { + return _progress.putIfAbsent(url, () => ValueNotifier(null)); + } + + static void setProgress(String url, double? value) { + progressFor(url).value = value; + } +} + +class _ProgressiveNetworkImage extends StatefulWidget { + final String url; + final Uint8List? previewBytes; + final double width; + final double height; + final BoxFit fit; + final bool startDownloadNextFrame; + final bool keepAlive; + const _ProgressiveNetworkImage({ + super.key, + required this.url, + required this.previewBytes, + required this.width, + required this.height, + required this.fit, + this.startDownloadNextFrame = false, + this.keepAlive = true, + }); + + @override + State<_ProgressiveNetworkImage> createState() => + _ProgressiveNetworkImageState(); +} + +class _ProgressiveNetworkImageState extends State<_ProgressiveNetworkImage> + with AutomaticKeepAliveClientMixin { + static final Map _memoryCache = {}; + Uint8List? _fullBytes; + double _progress = 0.0; + bool _error = false; + String? _diskPath; + + @override + void initState() { + super.initState(); + + + + + if (widget.url.isEmpty) { + return; + } + + + + final cached = GlobalImageStore.getData(widget.url); + if (cached != null) { + _fullBytes = cached; + + } + + if (_memoryCache.containsKey(widget.url)) { + _fullBytes = _memoryCache[widget.url]; + } + if (widget.startDownloadNextFrame) { + + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) _tryLoadFromDiskThenDownload(); + }); + } else { + _tryLoadFromDiskThenDownload(); + } + } + + Future _tryLoadFromDiskThenDownload() async { + + + if (widget.url.isEmpty) { + return; + } + + + + try { + final dir = await getTemporaryDirectory(); + final name = crypto.md5.convert(widget.url.codeUnits).toString(); + final filePath = '${dir.path}/imgcache_$name'; + _diskPath = filePath; + final f = io.File(filePath); + if (await f.exists()) { + final data = await f.readAsBytes(); + _memoryCache[widget.url] = data; + GlobalImageStore.setData(widget.url, data); + if (mounted) setState(() => _fullBytes = data); + return; // нашли на диске, скачивать не надо + } + } catch (_) {} + await _download(); + } + + Future _download() async { + try { + final req = http.Request('GET', Uri.parse(widget.url)); + req.headers['User-Agent'] = + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; + + final resp = await req.send(); + if (resp.statusCode != 200) { + setState(() => _error = true); + return; + } + final contentLength = resp.contentLength ?? 0; + final bytes = []; + int received = 0; + await for (final chunk in resp.stream) { + bytes.addAll(chunk); + received += chunk.length; + if (contentLength > 0) { + final p = received / contentLength; + _progress = + p; // не дергаем setState, чтобы не создавать лишние перерисовки при slide + GlobalImageStore.setProgress(widget.url, _progress); + } + } + final data = Uint8List.fromList(bytes); + _memoryCache[widget.url] = data; + GlobalImageStore.setData(widget.url, data); + + try { + final path = _diskPath; + if (path != null) { + final f = io.File(path); + await f.writeAsBytes(data, flush: true); + } + } catch (_) {} + if (mounted) setState(() => _fullBytes = data); + } catch (_) { + if (mounted) setState(() => _error = true); + } + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + super.build(context); + final width = widget.width; + final height = widget.height; + if (_error) { + return Container( + width: width, + height: height, + color: Colors.black12, + alignment: Alignment.center, + child: const Icon(Icons.broken_image_outlined, color: Colors.black38), + ); + } + + return RepaintBoundary( + child: SizedBox( + width: width, + height: height, + child: ClipRRect( + borderRadius: BorderRadius.circular( + 0, + ), // Упрощено для производительности + child: Stack( + fit: StackFit.expand, + children: [ + + if (widget.previewBytes != null) + Image.memory( + widget.previewBytes!, + fit: widget.fit, + filterQuality: FilterQuality.none, + ) + else + Container(color: Colors.black12), + + if (_fullBytes != null) + Image.memory( + _fullBytes!, + fit: widget.fit, + filterQuality: FilterQuality.high, + ), + + + ], + ), + ), + ), + ); + } + + @override + bool get wantKeepAlive => true; + @override + void didUpdateWidget(covariant _ProgressiveNetworkImage oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.keepAlive != widget.keepAlive) { + + updateKeepAlive(); + } + } +} + +extension BrightnessExtension on Brightness { + bool get isDark => this == Brightness.dark; +} + +class _CustomEmojiButton extends StatefulWidget { + final Function(String) onCustomEmoji; + + const _CustomEmojiButton({required this.onCustomEmoji}); + + @override + State<_CustomEmojiButton> createState() => _CustomEmojiButtonState(); +} + +class _CustomEmojiButtonState extends State<_CustomEmojiButton> + with TickerProviderStateMixin { + late AnimationController _scaleController; + late Animation _scaleAnimation; + + @override + void initState() { + super.initState(); + _scaleController = AnimationController( + duration: const Duration(milliseconds: 200), + vsync: this, + ); + + _scaleAnimation = Tween(begin: 1.0, end: 1.15).animate( + CurvedAnimation(parent: _scaleController, curve: Curves.elasticOut), + ); + } + + @override + void dispose() { + _scaleController.dispose(); + super.dispose(); + } + + + void _handleTap() { + + _scaleController.forward().then((_) { + _scaleController.reverse(); + }); + + _showCustomEmojiDialog(); + } + + void _showCustomEmojiDialog() { + showDialog( + context: context, + builder: (context) => _CustomEmojiDialog( + onEmojiSelected: (emoji) { + widget.onCustomEmoji(emoji); + }, + ), + ); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: _handleTap, + child: AnimatedBuilder( + animation: _scaleController, + builder: (context, child) { + return Transform.scale( + scale: _scaleAnimation.value, + child: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainerHighest, + borderRadius: BorderRadius.circular(20), + ), + + child: Icon( + Icons.add_reaction_outlined, + size: 24, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ); + }, + ), + ); + } +} + +class _CustomEmojiDialog extends StatefulWidget { + final Function(String) onEmojiSelected; + + const _CustomEmojiDialog({required this.onEmojiSelected}); + + @override + State<_CustomEmojiDialog> createState() => _CustomEmojiDialogState(); +} + +class _CustomEmojiDialogState extends State<_CustomEmojiDialog> { + final TextEditingController _controller = TextEditingController(); + String _selectedEmoji = ''; + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + title: Row( + children: [ + Icon( + Icons.emoji_emotions, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(width: 8), + const Text('Введите эмодзи'), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: Theme.of(context).colorScheme.outline.withOpacity(0.3), + ), + ), + child: TextField( + controller: _controller, + maxLength: 1, // Только один символ + decoration: InputDecoration( + hintText: 'Введите эмодзи...', + border: InputBorder.none, + contentPadding: const EdgeInsets.all(16), + counterText: '', + hintStyle: TextStyle( + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.6), + ), + ), + onChanged: (value) { + setState(() { + _selectedEmoji = value; + }); + }, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 24), + ), + ), + const SizedBox(height: 20), + if (_selectedEmoji.isNotEmpty) ...[ + Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + Theme.of(context).colorScheme.primaryContainer, + Theme.of( + context, + ).colorScheme.primaryContainer.withOpacity(0.7), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: Theme.of(context).colorScheme.primary.withOpacity(0.3), + width: 2, + ), + boxShadow: [ + BoxShadow( + color: Theme.of( + context, + ).colorScheme.primary.withOpacity(0.2), + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Text(_selectedEmoji, style: const TextStyle(fontSize: 48)), + ), + const SizedBox(height: 20), + ], + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + FilledButton.icon( + onPressed: _selectedEmoji.isNotEmpty + ? () { + widget.onEmojiSelected(_selectedEmoji); + Navigator.of(context).pop(); + } + : null, + icon: const Icon(Icons.add), + label: const Text('Добавить'), + style: FilledButton.styleFrom( + backgroundColor: Theme.of(context).colorScheme.primary, + foregroundColor: Theme.of(context).colorScheme.onPrimary, + ), + ), + ], + ); + } +} + +class _MessageContextMenu extends StatefulWidget { + final Message message; + final Offset position; + final VoidCallback? onReply; + final VoidCallback? onEdit; + final VoidCallback? onDeleteForMe; + final VoidCallback? onDeleteForAll; + final Function(String)? onReaction; + final VoidCallback? onRemoveReaction; + final bool canEditMessage; + final bool hasUserReaction; + + const _MessageContextMenu({ + required this.message, + required this.position, + this.onReply, + this.onEdit, + this.onDeleteForMe, + this.onDeleteForAll, + this.onReaction, + this.onRemoveReaction, + required this.canEditMessage, + required this.hasUserReaction, + }); + + @override + _MessageContextMenuState createState() => _MessageContextMenuState(); +} + +class _MessageContextMenuState extends State<_MessageContextMenu> + with SingleTickerProviderStateMixin { + bool _isEmojiListExpanded = false; + + late AnimationController _animationController; + late Animation _scaleAnimation; + + + static const List _quickReactions = [ + '👍', + '❤️', + '😂', + '🔥', + '👏', + '🤔', + ]; + + + static const List _allReactions = [ + '👍', + '❤️', + '😂', + '🔥', + '👏', + '👌', + '🎉', + '🥰', + '😍', + '🙏', + '🤔', + '🤯', + '💯', + '⚡️', + '🤟', + '🌚', + '🌝', + '🥱', + '🤣', + '🫠', + '🫡', + '🐱', + '💋', + '😘', + '🐶', + '🤝', + '⭐️', + '🍷', + '🍑', + '😁', + '🤷‍♀️', + '🤷‍♂️', + '👩‍❤️‍👨', + '🦄', + '👻', + '🗿', + '❤️‍🩹', + '🛑', + '⛄️', + '❓', + '🙄', + '❗️', + '😉', + '😳', + '🥳', + '😎', + '💪', + '👀', + '🤞', + '🤤', + '🤪', + '🤩', + '😴', + '😐', + '😇', + '🖤', + '👑', + '👋', + '👁️', + ]; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 150), + ); + + _scaleAnimation = CurvedAnimation( + parent: _animationController, + curve: Curves.easeOutCubic, + ); + + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + void _onCopy() { + Clipboard.setData(ClipboardData(text: widget.message.text)); + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Сообщение скопировано'), + behavior: SnackBarBehavior.floating, + duration: Duration(seconds: 2), + ), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final themeProvider = Provider.of(context); + final screenSize = MediaQuery.of(context).size; + + const menuWidth = 250.0; + final double estimatedMenuHeight = _isEmojiListExpanded ? 320.0 : 250.0; + + double left = widget.position.dx - (menuWidth / 4); + if (left + menuWidth > screenSize.width) { + left = screenSize.width - menuWidth - 16; + } + if (left < 16) { + left = 16; + } + + double top = widget.position.dy; + if (top + estimatedMenuHeight > screenSize.height) { + top = widget.position.dy - estimatedMenuHeight - 10; + } + + return Scaffold( + backgroundColor: Colors.black.withOpacity(0.1), + body: Stack( + children: [ + Positioned.fill( + child: GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container(color: Colors.transparent), + ), + ), + Positioned( + top: top, + left: left, + child: ScaleTransition( + scale: _scaleAnimation, + alignment: Alignment.topCenter, + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: BackdropFilter( + filter: ImageFilter.blur( + sigmaX: themeProvider.messageMenuBlur, + sigmaY: themeProvider.messageMenuBlur, + ), + child: Card( + elevation: 8, + color: theme.colorScheme.surface.withOpacity( + themeProvider.messageMenuOpacity, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: Container( + width: menuWidth, + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + AnimatedSize( + duration: const Duration(milliseconds: 250), + curve: Curves.easeInOut, + child: _buildEmojiSection(), + ), + const Divider(height: 12), + _buildActionsSection(theme), + ], + ), + ), + ), + ), + ), + ), + ), + ], + ), + ); + } + + Widget _buildEmojiSection() { + if (_isEmojiListExpanded) { + return SizedBox( + height: 150, + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 5, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + ), + itemCount: _allReactions.length, + itemBuilder: (context, index) { + final emoji = _allReactions[index]; + return GestureDetector( + onTap: () { + Navigator.pop(context); + widget.onReaction?.call(emoji); + }, + child: Center( + child: Text(emoji, style: const TextStyle(fontSize: 28)), + ), + ); + }, + ), + ); + } else { + return Wrap( + spacing: 8, + runSpacing: 4, + alignment: WrapAlignment.center, + children: [ + ..._quickReactions.map( + (emoji) => GestureDetector( + onTap: () { + Navigator.pop(context); + widget.onReaction?.call(emoji); + }, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Text(emoji, style: const TextStyle(fontSize: 28)), + ), + ), + ), + IconButton( + icon: const Icon(Icons.add_circle_outline, size: 28), + onPressed: () => setState(() => _isEmojiListExpanded = true), + tooltip: 'Больше реакций', + ), + ], + ); + } + } + + Widget _buildActionsSection(ThemeData theme) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.message.text.isNotEmpty) + _buildActionButton( + icon: Icons.copy_rounded, + text: 'Копировать', + onTap: _onCopy, + ), + if (widget.onReply != null) + _buildActionButton( + icon: Icons.reply_rounded, + text: 'Ответить', + onTap: () { + Navigator.pop(context); + widget.onReply!(); + }, + ), + if (widget.onEdit != null) + _buildActionButton( + icon: widget.canEditMessage + ? Icons.edit_rounded + : Icons.edit_off_rounded, + text: 'Редактировать', + onTap: widget.canEditMessage + ? () { + Navigator.pop(context); + widget.onEdit!(); + } + : null, + color: widget.canEditMessage ? null : Colors.grey, + ), + if (widget.hasUserReaction && widget.onRemoveReaction != null) + _buildActionButton( + icon: Icons.remove_circle_outline_rounded, + text: 'Убрать реакцию', + color: theme.colorScheme.error, + onTap: () { + Navigator.pop(context); + widget.onRemoveReaction!(); + }, + ), + if (widget.onDeleteForMe != null) + _buildActionButton( + icon: Icons.person_remove_rounded, + text: 'Удалить у меня', + color: theme.colorScheme.error, + onTap: () { + Navigator.pop(context); + widget.onDeleteForMe!(); + }, + ), + if (widget.onDeleteForAll != null) + _buildActionButton( + icon: Icons.delete_forever_rounded, + text: 'Удалить у всех', + color: theme.colorScheme.error, + onTap: () { + Navigator.pop(context); + widget.onDeleteForAll!(); + }, + ), + ], + ); + } + + Widget _buildActionButton({ + required IconData icon, + required String text, + required VoidCallback? onTap, + Color? color, + }) { + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 10.0), + child: Row( + children: [ + Icon( + icon, + size: 20, + color: color ?? Theme.of(context).iconTheme.color, + ), + const SizedBox(width: 12), + Text( + text, + style: TextStyle( + color: color, + fontSize: 15, + fontWeight: onTap == null ? FontWeight.normal : FontWeight.w500, + ), + ), + ], + ), + ), + ); + } +} + +class FullScreenPhotoViewer extends StatefulWidget { + final Widget imageChild; + final Map? attach; + + const FullScreenPhotoViewer({ + super.key, + required this.imageChild, + this.attach, + }); + + @override + State createState() => _FullScreenPhotoViewerState(); +} + +class _FullScreenPhotoViewerState extends State { + late final TransformationController _transformationController; + + bool _isPanEnabled = false; + + @override + void initState() { + super.initState(); + _transformationController = TransformationController(); + + _transformationController.addListener(_onTransformChanged); + } + + @override + void dispose() { + _transformationController.removeListener(_onTransformChanged); + _transformationController.dispose(); + super.dispose(); + } + + void _onTransformChanged() { + + final currentScale = _transformationController.value.getMaxScaleOnAxis(); + + final shouldPan = currentScale > 1.0; + + + if (shouldPan != _isPanEnabled) { + setState(() { + _isPanEnabled = shouldPan; + }); + } + } + + Future _downloadPhoto() async { + if (widget.attach == null) return; + + try { + + io.Directory? downloadDir; + + if (io.Platform.isAndroid) { + final directory = await getExternalStorageDirectory(); + if (directory != null) { + downloadDir = io.Directory( + '${directory.path.split('Android')[0]}Download', + ); + if (!await downloadDir.exists()) { + downloadDir = io.Directory( + '${directory.path.split('Android')[0]}Downloads', + ); + } + } + } else if (io.Platform.isIOS) { + final directory = await getApplicationDocumentsDirectory(); + downloadDir = directory; + } else if (io.Platform.isWindows || io.Platform.isLinux) { + final homeDir = + io.Platform.environment['HOME'] ?? + io.Platform.environment['USERPROFILE'] ?? + ''; + downloadDir = io.Directory('$homeDir/Downloads'); + } else { + downloadDir = await getApplicationDocumentsDirectory(); + } + + if (downloadDir == null || !await downloadDir.exists()) { + throw Exception('Downloads directory not found'); + } + + + final url = widget.attach!['url'] ?? widget.attach!['baseUrl']; + if (url == null || url.isEmpty) { + throw Exception('Photo URL not found'); + } + + + String extension = 'jpg'; + final uri = Uri.tryParse(url); + if (uri != null && uri.pathSegments.isNotEmpty) { + final lastSegment = uri.pathSegments.last; + final extMatch = RegExp(r'\.([a-zA-Z0-9]+)$').firstMatch(lastSegment); + if (extMatch != null) { + extension = extMatch.group(1)!; + } + } + + + final timestamp = DateTime.now().millisecondsSinceEpoch; + final fileName = 'photo_$timestamp.$extension'; + final filePath = '${downloadDir.path}/$fileName'; + final file = io.File(filePath); + + + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + await file.writeAsBytes(response.bodyBytes); + + + final prefs = await SharedPreferences.getInstance(); + final List downloadedFiles = + prefs.getStringList('downloaded_files') ?? []; + if (!downloadedFiles.contains(filePath)) { + downloadedFiles.add(filePath); + await prefs.setStringList('downloaded_files', downloadedFiles); + } + + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Фото сохранено: $fileName'), + duration: const Duration(seconds: 3), + ), + ); + } + } else { + throw Exception('Failed to download photo: ${response.statusCode}'); + } + } catch (e) { + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Ошибка при скачивании фото: ${e.toString()}'), + backgroundColor: Colors.red, + duration: const Duration(seconds: 3), + ), + ); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Stack( + children: [ + GestureDetector( + onTap: () { + Navigator.of(context).pop(); + }, + child: InteractiveViewer( + transformationController: _transformationController, + panEnabled: _isPanEnabled, + boundaryMargin: EdgeInsets.zero, + minScale: 1.0, + maxScale: 5.0, + child: Center(child: widget.imageChild), + ), + ), + + SafeArea( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton( + icon: const Icon(Icons.close, color: Colors.white), + onPressed: () => Navigator.of(context).pop(), + ), + if (widget.attach != null) + IconButton( + icon: const Icon(Icons.download, color: Colors.white), + onPressed: _downloadPhoto, + tooltip: 'Скачать фото', + ), + ], + ), + ), + ), + ], + ), + ); + } +} + +class _RotatingIcon extends StatefulWidget { + final IconData icon; + final double size; + final Color color; + + const _RotatingIcon({ + required this.icon, + required this.size, + required this.color, + }); + + @override + State<_RotatingIcon> createState() => _RotatingIconState(); +} + +class _RotatingIconState extends State<_RotatingIcon> + with SingleTickerProviderStateMixin { + + late final AnimationController _controller; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + + duration: const Duration(seconds: 2), + vsync: this, + )..repeat(); // Запускаем анимацию на бесконечное повторение + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + + return RotationTransition( + turns: _controller, // Анимация вращения + child: Icon(widget.icon, size: widget.size, color: widget.color), + ); + } +} diff --git a/lib/widgets/connection_debug_panel.dart b/lib/widgets/connection_debug_panel.dart new file mode 100644 index 0000000..a2ba1b8 --- /dev/null +++ b/lib/widgets/connection_debug_panel.dart @@ -0,0 +1,676 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; + +import '../connection/connection_logger.dart'; +import '../connection/connection_state.dart' as conn_state; +import '../connection/health_monitor.dart'; +import '../api_service_v2.dart'; + + +class ConnectionDebugPanel extends StatefulWidget { + final bool isVisible; + final VoidCallback? onClose; + + const ConnectionDebugPanel({super.key, this.isVisible = false, this.onClose}); + + @override + State createState() => _ConnectionDebugPanelState(); +} + +class _ConnectionDebugPanelState extends State + with TickerProviderStateMixin { + late TabController _tabController; + + List _logs = []; + final List _stateHistory = []; + final List _healthMetrics = []; + + late StreamSubscription> _logsSubscription; + late StreamSubscription _stateSubscription; + late StreamSubscription _healthSubscription; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 4, vsync: this); + _setupSubscriptions(); + } + + void _setupSubscriptions() { + + _logsSubscription = Stream.periodic(const Duration(seconds: 1)) + .asyncMap((_) async => ApiServiceV2.instance.logs.take(100).toList()) + .listen((logs) { + if (mounted) { + setState(() { + _logs = logs; + }); + } + }); + + + _stateSubscription = ApiServiceV2.instance.connectionState.listen((state) { + if (mounted) { + setState(() { + _stateHistory.add(state); + if (_stateHistory.length > 50) { + _stateHistory.removeAt(0); + } + }); + } + }); + + + _healthSubscription = ApiServiceV2.instance.healthMetrics.listen((health) { + if (mounted) { + setState(() { + _healthMetrics.add(health); + if (_healthMetrics.length > 50) { + _healthMetrics.removeAt(0); + } + }); + } + }); + } + + @override + void dispose() { + _logsSubscription.cancel(); + _stateSubscription.cancel(); + _healthSubscription.cancel(); + _tabController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (!widget.isVisible) return const SizedBox.shrink(); + + return Container( + height: 400, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, -5), + ), + ], + ), + child: Column( + children: [ + _buildHeader(), + _buildTabBar(), + Expanded(child: _buildTabContent()), + ], + ), + ); + } + + Widget _buildHeader() { + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primary.withOpacity(0.1), + borderRadius: const BorderRadius.vertical(top: Radius.circular(16)), + ), + child: Row( + children: [ + Icon(Icons.bug_report, color: Theme.of(context).colorScheme.primary), + const SizedBox(width: 8), + Text( + 'Отладка подключения', + style: Theme.of(context).textTheme.titleMedium?.copyWith( + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold, + ), + ), + const Spacer(), + IconButton( + onPressed: widget.onClose, + icon: const Icon(Icons.close), + iconSize: 20, + ), + ], + ), + ); + } + + Widget _buildTabBar() { + return TabBar( + controller: _tabController, + isScrollable: true, + tabs: const [ + Tab(text: 'Логи'), + Tab(text: 'Состояния'), + Tab(text: 'Здоровье'), + Tab(text: 'Статистика'), + ], + ); + } + + Widget _buildTabContent() { + return TabBarView( + controller: _tabController, + children: [ + _buildLogsTab(), + _buildStatesTab(), + _buildHealthTab(), + _buildStatsTab(), + ], + ); + } + + Widget _buildLogsTab() { + return Column( + children: [ + _buildLogsControls(), + Expanded(child: _buildLogsList()), + ], + ); + } + + Widget _buildLogsControls() { + return Container( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + ElevatedButton.icon( + onPressed: _clearLogs, + icon: const Icon(Icons.clear, size: 16), + label: const Text('Очистить'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + ), + ), + const SizedBox(width: 8), + ElevatedButton.icon( + onPressed: _exportLogs, + icon: const Icon(Icons.download, size: 16), + label: const Text('Экспорт'), + style: ElevatedButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + ), + ), + const Spacer(), + Text( + 'Логов: ${_logs.length}', + style: Theme.of(context).textTheme.bodySmall, + ), + ], + ), + ); + } + + Widget _buildLogsList() { + if (_logs.isEmpty) { + return const Center(child: Text('Нет логов')); + } + + return ListView.builder( + itemCount: _logs.length, + itemBuilder: (context, index) { + final log = _logs[index]; + return _buildLogItem(log); + }, + ); + } + + Widget _buildLogItem(LogEntry log) { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: _getLogColor(log.level).withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: _getLogColor(log.level).withOpacity(0.3), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + _getLogIcon(log.level), + size: 16, + color: _getLogColor(log.level), + ), + const SizedBox(width: 8), + Text( + log.category, + style: TextStyle( + color: _getLogColor(log.level), + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + const Spacer(), + Text( + _formatTime(log.timestamp), + style: Theme.of(context).textTheme.bodySmall, + ), + ], + ), + const SizedBox(height: 4), + Text(log.message, style: Theme.of(context).textTheme.bodyMedium), + if (log.data != null) ...[ + const SizedBox(height: 4), + Text( + 'Data: ${log.data}', + style: Theme.of( + context, + ).textTheme.bodySmall?.copyWith(fontFamily: 'monospace'), + ), + ], + if (log.error != null) ...[ + const SizedBox(height: 4), + Text( + 'Error: ${log.error}', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Colors.red, + fontFamily: 'monospace', + ), + ), + ], + ], + ), + ); + } + + Widget _buildStatesTab() { + return ListView.builder( + itemCount: _stateHistory.length, + itemBuilder: (context, index) { + final state = _stateHistory[index]; + return _buildStateItem(state); + }, + ); + } + + Widget _buildStateItem(conn_state.ConnectionInfo state) { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: _getStateColor(state.state).withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: _getStateColor(state.state).withOpacity(0.3), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + _getStateIcon(state.state), + size: 16, + color: _getStateColor(state.state), + ), + const SizedBox(width: 8), + Text( + _getStateText(state.state), + style: TextStyle( + color: _getStateColor(state.state), + fontWeight: FontWeight.bold, + ), + ), + const Spacer(), + Text( + _formatTime(state.timestamp), + style: Theme.of(context).textTheme.bodySmall, + ), + ], + ), + if (state.message != null) ...[ + const SizedBox(height: 4), + Text(state.message!, style: Theme.of(context).textTheme.bodyMedium), + ], + if (state.serverUrl != null) ...[ + const SizedBox(height: 4), + Text( + 'Сервер: ${state.serverUrl}', + style: Theme.of(context).textTheme.bodySmall, + ), + ], + if (state.latency != null) ...[ + const SizedBox(height: 4), + Text( + 'Задержка: ${state.latency}ms', + style: Theme.of(context).textTheme.bodySmall, + ), + ], + ], + ), + ); + } + + Widget _buildHealthTab() { + if (_healthMetrics.isEmpty) { + return const Center(child: Text('Нет данных о здоровье')); + } + + final latestHealth = _healthMetrics.last; + + return Column( + children: [ + _buildHealthSummary(latestHealth), + Expanded(child: _buildHealthChart()), + ], + ); + } + + Widget _buildHealthSummary(HealthMetrics health) { + return Container( + margin: const EdgeInsets.all(8), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: _getHealthColor(health.quality).withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: _getHealthColor(health.quality).withOpacity(0.3), + width: 1, + ), + ), + child: Column( + children: [ + Row( + children: [ + Icon( + _getHealthIcon(health.quality), + size: 24, + color: _getHealthColor(health.quality), + ), + const SizedBox(width: 12), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Здоровье соединения', + style: Theme.of(context).textTheme.titleMedium, + ), + Text( + '${health.healthScore}/100 - ${_getHealthText(health.quality)}', + style: TextStyle( + color: _getHealthColor(health.quality), + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ], + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _buildHealthMetric('Задержка', '${health.latency}ms'), + _buildHealthMetric('Потери', '${health.packetLoss}%'), + _buildHealthMetric('Переподключения', '${health.reconnects}'), + _buildHealthMetric('Ошибки', '${health.errors}'), + ], + ), + ], + ), + ); + } + + Widget _buildHealthMetric(String label, String value) { + return Column( + children: [ + Text( + value, + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), + ), + Text(label, style: Theme.of(context).textTheme.bodySmall), + ], + ); + } + + Widget _buildHealthChart() { + return Container( + margin: const EdgeInsets.all(8), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of(context).colorScheme.outline.withOpacity(0.2), + ), + ), + child: const Center( + child: Text('График здоровья соединения\n(в разработке)'), + ), + ); + } + + Widget _buildStatsTab() { + return FutureBuilder>( + future: ApiServiceV2.instance + .getStatistics(), // Указываем Future, который нужно ожидать + builder: (context, snapshot) { + + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + + + if (snapshot.hasError) { + return Center( + child: Text('Ошибка загрузки статистики: ${snapshot.error}'), + ); + } + + + if (!snapshot.hasData || snapshot.data == null) { + return const Center(child: Text('Нет данных для отображения')); + } + + + final stats = snapshot.data!; // Теперь это точно Map + return ListView( + padding: const EdgeInsets.all(16), + children: [ + + _buildStatsSection('API Service', stats['api_service']), + const SizedBox(height: 16), + _buildStatsSection('Connection', stats['connection']), + ], + ); + }, + ); + } + + Widget _buildStatsSection(String title, Map? data) { + if (data == null) return const SizedBox.shrink(); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: Theme.of( + context, + ).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + ...data.entries.map((entry) => _buildStatsRow(entry.key, entry.value)), + ], + ); + } + + Widget _buildStatsRow(String key, dynamic value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 2), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text(key, style: Theme.of(context).textTheme.bodyMedium), + ), + Expanded( + flex: 1, + child: Text( + value.toString(), + style: Theme.of( + context, + ).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w500), + ), + ), + ], + ), + ); + } + + + Color _getLogColor(LogLevel level) { + switch (level) { + case LogLevel.debug: + return Colors.blue; + case LogLevel.info: + return Colors.green; + case LogLevel.warning: + return Colors.orange; + case LogLevel.error: + return Colors.red; + case LogLevel.critical: + return Colors.red.shade800; + } + } + + IconData _getLogIcon(LogLevel level) { + switch (level) { + case LogLevel.debug: + return Icons.bug_report; + case LogLevel.info: + return Icons.info; + case LogLevel.warning: + return Icons.warning; + case LogLevel.error: + return Icons.error; + case LogLevel.critical: + return Icons.dangerous; + } + } + + Color _getStateColor(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.ready: + return Colors.green; + case conn_state.ConnectionState.connected: + return Colors.blue; + case conn_state.ConnectionState.connecting: + case conn_state.ConnectionState.reconnecting: + return Colors.orange; + case conn_state.ConnectionState.error: + return Colors.red; + case conn_state.ConnectionState.disconnected: + case conn_state.ConnectionState.disabled: + return Colors.grey; + } + } + + IconData _getStateIcon(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.ready: + return Icons.check_circle; + case conn_state.ConnectionState.connected: + return Icons.link; + case conn_state.ConnectionState.connecting: + case conn_state.ConnectionState.reconnecting: + return Icons.sync; + case conn_state.ConnectionState.error: + return Icons.error; + case conn_state.ConnectionState.disconnected: + case conn_state.ConnectionState.disabled: + return Icons.link_off; + } + } + + String _getStateText(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.ready: + return 'Готов'; + case conn_state.ConnectionState.connected: + return 'Подключен'; + case conn_state.ConnectionState.connecting: + return 'Подключение'; + case conn_state.ConnectionState.reconnecting: + return 'Переподключение'; + case conn_state.ConnectionState.error: + return 'Ошибка'; + case conn_state.ConnectionState.disconnected: + return 'Отключен'; + case conn_state.ConnectionState.disabled: + return 'Отключен'; + } + } + + Color _getHealthColor(ConnectionQuality quality) { + switch (quality) { + case ConnectionQuality.excellent: + return Colors.green; + case ConnectionQuality.good: + return Colors.lightGreen; + case ConnectionQuality.fair: + return Colors.orange; + case ConnectionQuality.poor: + return Colors.red; + case ConnectionQuality.critical: + return Colors.red.shade800; + } + } + + IconData _getHealthIcon(ConnectionQuality quality) { + switch (quality) { + case ConnectionQuality.excellent: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.good: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.fair: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.poor: + return Icons.signal_cellular_0_bar; + case ConnectionQuality.critical: + return Icons.signal_cellular_0_bar; + } + } + + String _getHealthText(ConnectionQuality quality) { + switch (quality) { + case ConnectionQuality.excellent: + return 'Отлично'; + case ConnectionQuality.good: + return 'Хорошо'; + case ConnectionQuality.fair: + return 'Удовлетворительно'; + case ConnectionQuality.poor: + return 'Плохо'; + case ConnectionQuality.critical: + return 'Критично'; + } + } + + String _formatTime(DateTime time) { + return '${time.hour.toString().padLeft(2, '0')}:' + '${time.minute.toString().padLeft(2, '0')}:' + '${time.second.toString().padLeft(2, '0')}'; + } + + void _clearLogs() { + + } + + void _exportLogs() { + + } +} diff --git a/lib/widgets/connection_status_widget.dart b/lib/widgets/connection_status_widget.dart new file mode 100644 index 0000000..4a9e5f2 --- /dev/null +++ b/lib/widgets/connection_status_widget.dart @@ -0,0 +1,440 @@ +import 'package:flutter/material.dart'; +import 'dart:async'; + +import '../connection/connection_state.dart' as conn_state; +import '../connection/health_monitor.dart'; +import '../api_service_v2.dart'; + + +class ConnectionStatusWidget extends StatefulWidget { + final bool showDetails; + final bool showHealthMetrics; + final VoidCallback? onTap; + + const ConnectionStatusWidget({ + super.key, + this.showDetails = false, + this.showHealthMetrics = false, + this.onTap, + }); + + @override + State createState() => _ConnectionStatusWidgetState(); +} + +class _ConnectionStatusWidgetState extends State { + late StreamSubscription _stateSubscription; + late StreamSubscription _healthSubscription; + + conn_state.ConnectionInfo? _currentState; + HealthMetrics? _currentHealth; + bool _isExpanded = false; + + @override + void initState() { + super.initState(); + _setupSubscriptions(); + } + + void _setupSubscriptions() { + _stateSubscription = ApiServiceV2.instance.connectionState.listen((state) { + if (mounted) { + setState(() { + _currentState = state; + }); + } + }); + + if (widget.showHealthMetrics) { + _healthSubscription = ApiServiceV2.instance.healthMetrics.listen(( + health, + ) { + if (mounted) { + setState(() { + _currentHealth = health; + }); + } + }); + } + } + + @override + void dispose() { + _stateSubscription.cancel(); + _healthSubscription.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (_currentState == null) { + return const SizedBox.shrink(); + } + + return GestureDetector( + onTap: widget.onTap ?? _toggleExpanded, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + decoration: BoxDecoration( + color: _getStatusColor().withOpacity(0.1), + borderRadius: BorderRadius.circular(20), + border: Border.all( + color: _getStatusColor().withOpacity(0.3), + width: 1, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisSize: MainAxisSize.min, + children: [ + _buildStatusIcon(), + const SizedBox(width: 8), + _buildStatusText(), + if (widget.showDetails) ...[ + const SizedBox(width: 8), + Icon( + _isExpanded + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + size: 16, + color: _getStatusColor(), + ), + ], + ], + ), + if (_isExpanded && widget.showDetails) ...[ + const SizedBox(height: 8), + _buildDetails(), + ], + ], + ), + ), + ); + } + + Widget _buildStatusIcon() { + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + width: 8, + height: 8, + decoration: BoxDecoration( + color: _getStatusColor(), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: _getStatusColor().withOpacity(0.5), + blurRadius: 4, + spreadRadius: 1, + ), + ], + ), + ); + } + + Widget _buildStatusText() { + return Text( + _getStatusText(), + style: TextStyle( + color: _getStatusColor(), + fontSize: 12, + fontWeight: FontWeight.w500, + ), + ); + } + + Widget _buildDetails() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (_currentState?.serverUrl != null) + _buildDetailRow('Сервер', _currentState!.serverUrl!), + if (_currentState?.latency != null) + _buildDetailRow('Задержка', '${_currentState!.latency}ms'), + if (_currentState?.attemptNumber != null) + _buildDetailRow('Попытка', '${_currentState!.attemptNumber}'), + if (_currentState?.reconnectDelay != null) + _buildDetailRow( + 'Переподключение', + 'через ${_currentState!.reconnectDelay!.inSeconds}с', + ), + if (_currentHealth != null) ...[ + const SizedBox(height: 4), + _buildHealthMetrics(), + ], + ], + ); + } + + Widget _buildDetailRow(String label, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 1), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '$label: ', + style: TextStyle( + color: _getStatusColor().withOpacity(0.7), + fontSize: 10, + ), + ), + Text( + value, + style: TextStyle( + color: _getStatusColor(), + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + ); + } + + Widget _buildHealthMetrics() { + if (_currentHealth == null) return const SizedBox.shrink(); + + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: _getHealthColor().withOpacity(0.1), + borderRadius: BorderRadius.circular(8), + border: Border.all(color: _getHealthColor().withOpacity(0.3), width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(_getHealthIcon(), size: 12, color: _getHealthColor()), + const SizedBox(width: 4), + Text( + 'Здоровье: ${_currentHealth!.healthScore}/100', + style: TextStyle( + color: _getHealthColor(), + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + const SizedBox(height: 4), + _buildHealthBar(), + ], + ), + ); + } + + Widget _buildHealthBar() { + final score = _currentHealth!.healthScore; + return Container( + height: 4, + decoration: BoxDecoration( + color: Colors.grey.withOpacity(0.2), + borderRadius: BorderRadius.circular(2), + ), + child: FractionallySizedBox( + alignment: Alignment.centerLeft, + widthFactor: score / 100, + child: Container( + decoration: BoxDecoration( + color: _getHealthColor(), + borderRadius: BorderRadius.circular(2), + ), + ), + ), + ); + } + + Color _getStatusColor() { + switch (_currentState?.state) { + case conn_state.ConnectionState.ready: + return Colors.green; + case conn_state.ConnectionState.connected: + return Colors.blue; + case conn_state.ConnectionState.connecting: + case conn_state.ConnectionState.reconnecting: + return Colors.orange; + case conn_state.ConnectionState.error: + return Colors.red; + case conn_state.ConnectionState.disconnected: + case conn_state.ConnectionState.disabled: + default: + return Colors.grey; + } + } + + String _getStatusText() { + switch (_currentState?.state) { + case conn_state.ConnectionState.ready: + return 'Готов'; + case conn_state.ConnectionState.connected: + return 'Подключен'; + case conn_state.ConnectionState.connecting: + return 'Подключение...'; + case conn_state.ConnectionState.reconnecting: + return 'Переподключение...'; + case conn_state.ConnectionState.error: + return 'Ошибка'; + case conn_state.ConnectionState.disconnected: + return 'Отключен'; + case conn_state.ConnectionState.disabled: + return 'Отключен'; + default: + return 'Неизвестно'; + } + } + + Color _getHealthColor() { + if (_currentHealth == null) return Colors.grey; + + switch (_currentHealth!.quality) { + case ConnectionQuality.excellent: + return Colors.green; + case ConnectionQuality.good: + return Colors.lightGreen; + case ConnectionQuality.fair: + return Colors.orange; + case ConnectionQuality.poor: + return Colors.red; + case ConnectionQuality.critical: + return Colors.red.shade800; + } + } + + IconData _getHealthIcon() { + if (_currentHealth == null) return Icons.help_outline; + + switch (_currentHealth!.quality) { + case ConnectionQuality.excellent: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.good: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.fair: + return Icons.signal_cellular_4_bar; + case ConnectionQuality.poor: + return Icons.signal_cellular_0_bar; + case ConnectionQuality.critical: + return Icons.signal_cellular_0_bar; + } + } + + void _toggleExpanded() { + setState(() { + _isExpanded = !_isExpanded; + }); + } +} + + +class ConnectionIndicator extends StatefulWidget { + final double size; + final bool showPulse; + + const ConnectionIndicator({ + super.key, + this.size = 12.0, + this.showPulse = true, + }); + + @override + State createState() => _ConnectionIndicatorState(); +} + +class _ConnectionIndicatorState extends State { + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: ApiServiceV2.instance.connectionState, + builder: (context, snapshot) { + if (!snapshot.hasData) { + return SizedBox( + width: widget.size, + height: widget.size, + child: const CircularProgressIndicator(strokeWidth: 2), + ); + } + + final state = snapshot.data!; + final color = _getStatusColor(state.state); + final isActive = + state.state == conn_state.ConnectionState.ready || + state.state == conn_state.ConnectionState.connected; + + if (widget.showPulse && isActive) { + return _buildPulsingIndicator(color); + } else { + return _buildStaticIndicator(color); + } + }, + ); + } + + Widget _buildPulsingIndicator(Color color) { + return TweenAnimationBuilder( + duration: const Duration(seconds: 2), + tween: Tween(begin: 0.0, end: 1.0), + builder: (context, value, child) { + return Container( + width: widget.size, + height: widget.size, + decoration: BoxDecoration( + color: color.withOpacity(0.3 + (0.7 * value)), + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: color.withOpacity(0.5 * value), + blurRadius: 8 * value, + spreadRadius: 2 * value, + ), + ], + ), + ); + }, + onEnd: () { + + if (mounted) { + setState(() {}); + } + }, + ); + } + + Widget _buildStaticIndicator(Color color) { + return Container( + width: widget.size, + height: widget.size, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: color.withOpacity(0.5), + blurRadius: 4, + spreadRadius: 1, + ), + ], + ), + ); + } + + Color _getStatusColor(conn_state.ConnectionState state) { + switch (state) { + case conn_state.ConnectionState.ready: + return Colors.green; + case conn_state.ConnectionState.connected: + return Colors.blue; + case conn_state.ConnectionState.connecting: + case conn_state.ConnectionState.reconnecting: + return Colors.orange; + case conn_state.ConnectionState.error: + return Colors.red; + case conn_state.ConnectionState.disconnected: + case conn_state.ConnectionState.disabled: + return Colors.grey; + } + } +} diff --git a/lib/widgets/group_avatars.dart b/lib/widgets/group_avatars.dart new file mode 100644 index 0000000..ecefb6f --- /dev/null +++ b/lib/widgets/group_avatars.dart @@ -0,0 +1,189 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:gwid/models/chat.dart'; +import 'package:gwid/models/contact.dart'; + +class GroupAvatars extends StatelessWidget { + final Chat chat; + final Map contacts; + final int maxAvatars; + final double avatarSize; + final double overlap; + + const GroupAvatars({ + super.key, + required this.chat, + required this.contacts, + this.maxAvatars = 3, + this.avatarSize = 16.0, + this.overlap = 8.0, + }); + + @override + Widget build(BuildContext context) { + if (!chat.isGroup) { + return const SizedBox.shrink(); + } + + final participantIds = chat.groupParticipantIds; + + if (participantIds.isEmpty) { + return const SizedBox.shrink(); + } + + final visibleParticipants = participantIds.take(maxAvatars).toList(); + final remainingCount = participantIds.length - maxAvatars; + + + final totalParticipants = participantIds.length; + double adaptiveAvatarSize; + if (totalParticipants <= 2) { + adaptiveAvatarSize = + avatarSize * 1.5; // Большие аватары для 1-2 участников + } else if (totalParticipants <= 4) { + adaptiveAvatarSize = + avatarSize * 1.2; // Средние аватары для 3-4 участников + } else { + adaptiveAvatarSize = + avatarSize * 0.8; // Маленькие аватары для 5+ участников + } + + return SizedBox( + height: adaptiveAvatarSize * 2.5, + width: adaptiveAvatarSize * 2.5, + child: Stack( + children: [ + + ...visibleParticipants.asMap().entries.map((entry) { + final index = entry.key; + final participantId = entry.value; + final contact = contacts[participantId]; + + + double x, y; + if (visibleParticipants.length == 1) { + + x = adaptiveAvatarSize * 1.25; + y = adaptiveAvatarSize * 1.25; + } else if (visibleParticipants.length == 2) { + + x = adaptiveAvatarSize * (0.5 + index * 1.5); + y = adaptiveAvatarSize * 1.25; + } else { + + final angle = (index * 2 * pi) / visibleParticipants.length; + final radius = adaptiveAvatarSize * 0.6; + final center = adaptiveAvatarSize * 1.25; + x = center + radius * cos(angle); + y = center + radius * sin(angle); + } + + return Positioned( + left: x - adaptiveAvatarSize / 2, + top: y - adaptiveAvatarSize / 2, + child: _buildAvatar( + context, + contact, + participantId, + adaptiveAvatarSize, + ), + ); + }), + + + if (remainingCount > 0) + Positioned( + left: adaptiveAvatarSize * 0.75, + top: adaptiveAvatarSize * 0.75, + child: _buildMoreIndicator( + context, + remainingCount, + adaptiveAvatarSize, + ), + ), + ], + ), + ); + } + + Widget _buildAvatar( + BuildContext context, + Contact? contact, + int participantId, + double size, + ) { + final colors = Theme.of(context).colorScheme; + + return Container( + width: size, + height: size, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all(color: colors.surface, width: 2), + boxShadow: [ + BoxShadow( + color: colors.shadow.withOpacity(0.3), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: CircleAvatar( + radius: size / 2, + backgroundColor: contact != null + ? colors.primaryContainer + : colors.secondaryContainer, + backgroundImage: contact?.photoBaseUrl != null + ? NetworkImage(contact!.photoBaseUrl!) + : null, + child: contact?.photoBaseUrl == null + ? Text( + contact?.name.isNotEmpty == true + ? contact!.name[0].toUpperCase() + : participantId.toString().substring( + participantId.toString().length - 1, + ), // Последняя цифра ID + style: TextStyle( + color: contact != null + ? colors.onPrimaryContainer + : colors.onSecondaryContainer, + fontSize: size * 0.5, + fontWeight: FontWeight.w600, + ), + ) + : null, + ), + ); + } + + Widget _buildMoreIndicator(BuildContext context, int count, double size) { + final colors = Theme.of(context).colorScheme; + + return Container( + width: size, + height: size, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: colors.secondaryContainer, + border: Border.all(color: colors.surface, width: 2), + boxShadow: [ + BoxShadow( + color: colors.shadow.withOpacity(0.3), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: Center( + child: Text( + '+$count', + style: TextStyle( + color: colors.onSecondaryContainer, + fontSize: size * 0.4, + fontWeight: FontWeight.w600, + ), + ), + ), + ); + } +} diff --git a/lib/widgets/group_header.dart b/lib/widgets/group_header.dart new file mode 100644 index 0000000..2c34cd8 --- /dev/null +++ b/lib/widgets/group_header.dart @@ -0,0 +1,124 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/models/chat.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/widgets/group_avatars.dart'; +import 'package:gwid/widgets/group_management_panel.dart'; + +class GroupHeader extends StatelessWidget { + final Chat chat; + final Map contacts; + final int myId; + final VoidCallback? onParticipantsChanged; + + const GroupHeader({ + super.key, + required this.chat, + required this.contacts, + required this.myId, + this.onParticipantsChanged, + }); + + @override + Widget build(BuildContext context) { + if (!chat.isGroup) { + return const SizedBox.shrink(); + } + + final colors = Theme.of(context).colorScheme; + final onlineCount = chat.onlineParticipantsCount; + final totalCount = chat.participantsCount; + + return GestureDetector( + onTap: () => _showGroupManagementPanel(context), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: colors.surfaceContainerHighest.withOpacity(0.3), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + children: [ + + GroupAvatars( + chat: chat, + contacts: contacts, + maxAvatars: 4, + avatarSize: 20.0, + overlap: 6.0, + ), + + const SizedBox(width: 12), + + + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + chat.displayTitle, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w600, + color: colors.onSurface, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 2), + Row( + children: [ + + if (onlineCount > 0) ...[ + Container( + width: 8, + height: 8, + decoration: BoxDecoration( + color: colors.primary, + shape: BoxShape.circle, + ), + ), + const SizedBox(width: 6), + Text( + '$onlineCount онлайн', + style: TextStyle( + fontSize: 12, + color: colors.primary, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(width: 8), + ], + + + Text( + '$totalCount участников', + style: TextStyle( + fontSize: 12, + color: colors.onSurfaceVariant, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ); + } + + void _showGroupManagementPanel(BuildContext context) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => GroupManagementPanel( + chat: chat, + contacts: contacts, + myId: myId, + onParticipantsChanged: onParticipantsChanged, + ), + ); + } +} diff --git a/lib/widgets/group_management_panel.dart b/lib/widgets/group_management_panel.dart new file mode 100644 index 0000000..12b8156 --- /dev/null +++ b/lib/widgets/group_management_panel.dart @@ -0,0 +1,358 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/models/chat.dart'; +import 'package:gwid/models/contact.dart'; +import 'package:gwid/api_service.dart'; +import 'package:gwid/screens/group_settings_screen.dart'; + +class GroupManagementPanel extends StatefulWidget { + final Chat chat; + final Map contacts; + final int myId; + final VoidCallback? onParticipantsChanged; + + const GroupManagementPanel({ + super.key, + required this.chat, + required this.contacts, + required this.myId, + this.onParticipantsChanged, + }); + + @override + State createState() => _GroupManagementPanelState(); +} + +class _GroupManagementPanelState extends State { + final ApiService _apiService = ApiService.instance; + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.7, + minChildSize: 0.3, + maxChildSize: 1.0, + builder: (context, scrollController) { + return _buildContent(context, scrollController); + }, + ); + } + + Widget _buildContent( + BuildContext context, + ScrollController scrollController, + ) { + final colors = Theme.of(context).colorScheme; + final participantIds = widget.chat.groupParticipantIds; + final participants = participantIds + .map((id) => widget.contacts[id]) + .where((contact) => contact != null) + .cast() + .toList(); + + return Container( + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + ), + child: Column( + children: [ + + Container( + margin: const EdgeInsets.only(top: 8), + width: 40, + height: 4, + decoration: BoxDecoration( + color: colors.onSurfaceVariant.withOpacity(0.3), + borderRadius: BorderRadius.circular(2), + ), + ), + + + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: colors.outline.withOpacity(0.2)), + ), + ), + child: Row( + children: [ + Icon(Icons.group, color: colors.primary), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.chat.displayTitle, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: colors.onSurface, + ), + ), + Text( + '${participants.length} участников', + style: TextStyle( + fontSize: 14, + color: colors.onSurfaceVariant, + ), + ), + ], + ), + ), + IconButton( + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => GroupSettingsScreen( + chatId: widget.chat.id, + initialContact: + widget.contacts[widget.chat.ownerId] ?? + Contact( + id: 0, + name: widget.chat.displayTitle, + firstName: '', + lastName: '', + ), + myId: widget.myId, + ), + ), + ); + }, + icon: Icon(Icons.settings, color: colors.primary), + tooltip: 'Настройки группы', + ), + IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: Icon(Icons.close, color: colors.onSurfaceVariant), + ), + ], + ), + ), + + + Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: SizedBox( + width: double.infinity, + child: ElevatedButton.icon( + onPressed: _isLoading ? null : _showAddParticipantDialog, + icon: const Icon(Icons.person_add), + label: const Text('Добавить участника'), + style: ElevatedButton.styleFrom( + backgroundColor: colors.primary, + foregroundColor: colors.onPrimary, + padding: const EdgeInsets.symmetric(vertical: 12), + ), + ), + ), + ), + + + Expanded( + child: ListView.builder( + controller: scrollController, + padding: const EdgeInsets.symmetric(horizontal: 16), + itemCount: participants.length, + itemBuilder: (context, index) { + final participant = participants[index]; + final isOwner = participant.id == widget.chat.ownerId; + final isMe = participant.id == widget.myId; + + return ListTile( + leading: CircleAvatar( + backgroundImage: participant.photoBaseUrl != null + ? NetworkImage(participant.photoBaseUrl!) + : null, + child: participant.photoBaseUrl == null + ? Text( + participant.name.isNotEmpty + ? participant.name[0].toUpperCase() + : '?', + style: TextStyle(color: colors.onPrimaryContainer), + ) + : null, + ), + title: Row( + children: [ + Text( + participant.name, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + if (isOwner) ...[ + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.primary, + borderRadius: BorderRadius.circular(10), + ), + child: Text( + 'Создатель', + style: TextStyle( + color: colors.onPrimary, + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + if (isMe) ...[ + const SizedBox(width: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + decoration: BoxDecoration( + color: colors.secondary, + borderRadius: BorderRadius.circular(10), + ), + child: Text( + 'Вы', + style: TextStyle( + color: colors.onSecondary, + fontSize: 10, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ], + ), + subtitle: Text( + 'ID: ${participant.id}', + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 12, + ), + ), + trailing: isOwner || isMe + ? null + : PopupMenuButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + onSelected: (value) => + _handleParticipantAction(participant, value), + itemBuilder: (context) => [ + const PopupMenuItem( + value: 'remove', + child: Row( + children: [ + Icon(Icons.person_remove, color: Colors.red), + SizedBox(width: 8), + Text('Удалить из группы'), + ], + ), + ), + const PopupMenuItem( + value: 'remove_with_messages', + child: Row( + children: [ + Icon(Icons.delete_forever, color: Colors.red), + SizedBox(width: 8), + Text('Удалить с сообщениями'), + ], + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ); + } + + void _showAddParticipantDialog() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Добавить участника'), + content: const Text('Введите ID пользователя для добавления в группу'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('Отмена'), + ), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Функция добавления участника в разработке'), + ), + ); + }, + child: const Text('Добавить'), + ), + ], + ), + ); + } + + Future _handleParticipantAction( + Contact participant, + String action, + ) async { + if (_isLoading) return; + + setState(() { + _isLoading = true; + }); + + try { + if (action == 'remove') { + await _removeParticipant(participant.id, cleanMessages: false); + } else if (action == 'remove_with_messages') { + await _removeParticipant(participant.id, cleanMessages: true); + } + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + action == 'remove' + ? '${participant.name} удален из группы' + : '${participant.name} удален с сообщениями', + ), + ), + ); + widget.onParticipantsChanged?.call(); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Ошибка: $e'), backgroundColor: Colors.red), + ); + } + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } + } + + Future _removeParticipant( + int userId, { + required bool cleanMessages, + }) async { + + print('Удаляем участника $userId, очистка сообщений: $cleanMessages'); + + + _apiService.sendMessage(widget.chat.id, '', replyToMessageId: null); + } +} diff --git a/lib/widgets/reconnection_overlay.dart b/lib/widgets/reconnection_overlay.dart new file mode 100644 index 0000000..32f5025 --- /dev/null +++ b/lib/widgets/reconnection_overlay.dart @@ -0,0 +1,116 @@ + + +import 'package:flutter/material.dart'; + +class ReconnectionOverlay extends StatelessWidget { + final bool isReconnecting; + final String? message; + + const ReconnectionOverlay({ + super.key, + required this.isReconnecting, + this.message, + }); + + @override + Widget build(BuildContext context) { + if (!isReconnecting) { + return const SizedBox.shrink(); + } + + return Directionality( + textDirection: TextDirection.ltr, + child: Material( + color: Colors.black.withOpacity(0.7), + child: Center( + child: Container( + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + + SizedBox( + width: 48, + height: 48, + child: CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation( + Theme.of(context).colorScheme.primary, + ), + ), + ), + const SizedBox(height: 16), + + + Text( + message ?? 'Переподключение...', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface, + ), + textAlign: TextAlign.center, + ), + + const SizedBox(height: 8), + + + Text( + 'Пожалуйста, подождите', + style: TextStyle( + fontSize: 14, + color: Theme.of( + context, + ).colorScheme.onSurface.withOpacity(0.7), + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ), + ); + } +} + +class ReconnectionOverlayController { + static final ReconnectionOverlayController _instance = + ReconnectionOverlayController._internal(); + factory ReconnectionOverlayController() => _instance; + ReconnectionOverlayController._internal(); + + bool _isReconnecting = false; + String? _message; + VoidCallback? _onStateChanged; + + bool get isReconnecting => _isReconnecting; + String? get message => _message; + + void setOnStateChanged(VoidCallback? callback) { + _onStateChanged = callback; + } + + void showReconnecting({String? message}) { + _isReconnecting = true; + _message = message; + _onStateChanged?.call(); + } + + void hideReconnecting() { + _isReconnecting = false; + _message = null; + _onStateChanged?.call(); + } +} diff --git a/lib/widgets/user_profile_panel.dart b/lib/widgets/user_profile_panel.dart new file mode 100644 index 0000000..c6b3a88 --- /dev/null +++ b/lib/widgets/user_profile_panel.dart @@ -0,0 +1,396 @@ +import 'package:flutter/material.dart'; +import 'package:gwid/services/avatar_cache_service.dart'; + + + + +class UserProfilePanel extends StatefulWidget { + final int userId; + final String? name; + final String? firstName; + final String? lastName; + final String? avatarUrl; + final String? description; + final int myId; + final int? currentChatId; + final Map? contactData; + final int? dialogChatId; + + const UserProfilePanel({ + super.key, + required this.userId, + this.name, + this.firstName, + this.lastName, + this.avatarUrl, + this.description, + required this.myId, + this.currentChatId, + this.contactData, + this.dialogChatId, + }); + + @override + State createState() => _UserProfilePanelState(); +} + +class _UserProfilePanelState extends State { + final ScrollController _nameScrollController = ScrollController(); + + + + String get _displayName { + if (widget.firstName != null || widget.lastName != null) { + final firstName = widget.firstName ?? ''; + final lastName = widget.lastName ?? ''; + final fullName = '$firstName $lastName'.trim(); + return fullName.isNotEmpty ? fullName : (widget.name ?? 'Неизвестный'); + } + return widget.name ?? 'Неизвестный'; + } + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + _checkNameLength(); + }); + } + + void _checkNameLength() { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (_nameScrollController.hasClients) { + final maxScroll = _nameScrollController.position.maxScrollExtent; + if (maxScroll > 0) { + _startNameScroll(); + } + } + }); + } + + void _startNameScroll() { + if (!_nameScrollController.hasClients) return; + + Future.delayed(const Duration(seconds: 2), () { + if (!mounted || !_nameScrollController.hasClients) return; + + _nameScrollController + .animateTo( + _nameScrollController.position.maxScrollExtent, + duration: const Duration(seconds: 3), + curve: Curves.easeInOut, + ) + .then((_) { + if (!mounted) return; + Future.delayed(const Duration(seconds: 1), () { + if (!mounted || !_nameScrollController.hasClients) return; + _nameScrollController + .animateTo( + 0, + duration: const Duration(seconds: 3), + curve: Curves.easeInOut, + ) + .then((_) { + if (mounted) { + Future.delayed(const Duration(seconds: 2), () { + if (mounted) _startNameScroll(); + }); + } + }); + }); + }); + }); + } + + @override + void dispose() { + _nameScrollController.dispose(); + super.dispose(); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @override + Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + + return Container( + decoration: BoxDecoration( + color: colors.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + margin: const EdgeInsets.only(top: 12, bottom: 8), + width: 40, + height: 4, + decoration: BoxDecoration( + color: colors.onSurfaceVariant.withOpacity(0.4), + borderRadius: BorderRadius.circular(2), + ), + ), + Padding( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + AvatarCacheService().getAvatarWidget( + widget.avatarUrl, + userId: widget.userId, + size: 80, + fallbackText: _displayName, + backgroundColor: colors.primaryContainer, + textColor: colors.onPrimaryContainer, + ), + const SizedBox(height: 16), + LayoutBuilder( + builder: (context, constraints) { + final textPainter = TextPainter( + text: TextSpan( + text: _displayName, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + maxLines: 1, + textDirection: TextDirection.ltr, + ); + textPainter.layout(); + final textWidth = textPainter.size.width; + final needsScroll = textWidth > constraints.maxWidth; + + if (needsScroll) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _checkNameLength(); + }); + return SizedBox( + height: 28, + child: SingleChildScrollView( + controller: _nameScrollController, + scrollDirection: Axis.horizontal, + physics: const NeverScrollableScrollPhysics(), + child: Text( + _displayName, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + ), + ), + ); + } else { + return Text( + _displayName, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ); + } + }, + ), + const SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _buildActionButton( + icon: Icons.phone, + label: 'Позвонить', + onPressed: null, + colors: colors, + ), + _buildActionButton( + icon: Icons.person_add, + label: 'В контакты', + onPressed: null, + colors: colors, + ), + _buildActionButton( + icon: Icons.message, + label: 'Написать', + onPressed: null, + colors: colors, + ), + ], + ), + if (widget.description != null && + widget.description!.isNotEmpty) ...[ + const SizedBox(height: 24), + Text( + widget.description!, + style: TextStyle( + color: colors.onSurfaceVariant, + fontSize: 14, + ), + textAlign: TextAlign.center, + ), + ], + SizedBox(height: MediaQuery.of(context).padding.bottom), + ], + ), + ), + ], + ), + ); + } + + Widget _buildActionButton({ + required IconData icon, + required String label, + required VoidCallback? onPressed, + required ColorScheme colors, + bool isLoading = false, + }) { + return Column( + children: [ + Container( + width: 56, + height: 56, + decoration: BoxDecoration( + color: colors.primaryContainer, + shape: BoxShape.circle, + ), + child: isLoading + ? Center( + child: SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation(colors.primary), + ), + ), + ) + : IconButton( + icon: Icon(icon, color: colors.primary), + onPressed: onPressed, + ), + ), + const SizedBox(height: 8), + Text( + label, + style: TextStyle(fontSize: 12, color: colors.onSurfaceVariant), + ), + ], + ); + } +} diff --git a/linux/.gitignore b/linux/.gitignore new file mode 100644 index 0000000..d3896c9 --- /dev/null +++ b/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt new file mode 100644 index 0000000..a91e348 --- /dev/null +++ b/linux/CMakeLists.txt @@ -0,0 +1,141 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "Komet") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.github.TeamKomet-Developer-s.app") + + + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +# Check for Wayland support in GTK +#pkg_check_modules(GTK_WAYLAND REQUIRED IMPORTED_TARGET gtk+-3.0) + +#pkg_check_modules(FLUTTER_INAPPWEBVIEW_PLUGIN REQUIRED IMPORTED_TARGET +# webkit2gtk-4.0 +# gtk+-3.0 +#) + + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +## Install the AOT library on non-Debug builds only. +#if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") +# install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" +# COMPONENT Runtime) +#endif() + + diff --git a/linux/flutter/CMakeLists.txt b/linux/flutter/CMakeLists.txt new file mode 100644 index 0000000..d5bd016 --- /dev/null +++ b/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..988d667 --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,47 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) dynamic_color_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); + dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); + g_autoptr(FlPluginRegistrar) file_saver_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin"); + file_saver_plugin_register_with_registrar(file_saver_registrar); + g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); + file_selector_plugin_register_with_registrar(file_selector_linux_registrar); + g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin"); + flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar); + g_autoptr(FlPluginRegistrar) flutter_timezone_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterTimezonePlugin"); + flutter_timezone_plugin_register_with_registrar(flutter_timezone_registrar); + g_autoptr(FlPluginRegistrar) gtk_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); + gtk_plugin_register_with_registrar(gtk_registrar); + g_autoptr(FlPluginRegistrar) open_file_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "OpenFileLinuxPlugin"); + open_file_linux_plugin_register_with_registrar(open_file_linux_registrar); + g_autoptr(FlPluginRegistrar) smart_auth_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SmartAuthPlugin"); + smart_auth_plugin_register_with_registrar(smart_auth_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); +} diff --git a/linux/flutter/generated_plugin_registrant.h b/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..e0f0a47 --- /dev/null +++ b/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake new file mode 100644 index 0000000..25b57ba --- /dev/null +++ b/linux/flutter/generated_plugins.cmake @@ -0,0 +1,32 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + dynamic_color + file_saver + file_selector_linux + flutter_secure_storage_linux + flutter_timezone + gtk + open_file_linux + smart_auth + url_launcher_linux +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/linux/readme.md b/linux/readme.md new file mode 100644 index 0000000..25ecdbe --- /dev/null +++ b/linux/readme.md @@ -0,0 +1,3 @@ +# Linux Build +Maintenied by: ivan2282 +No modifications to this folder without permission \ No newline at end of file diff --git a/linux/runner/CMakeLists.txt b/linux/runner/CMakeLists.txt new file mode 100644 index 0000000..53bea08 --- /dev/null +++ b/linux/runner/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.13) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the application ID. +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + diff --git a/linux/runner/main.cc b/linux/runner/main.cc new file mode 100644 index 0000000..7243ee1 --- /dev/null +++ b/linux/runner/main.cc @@ -0,0 +1,8 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + + gdk_set_allowed_backends("x11"); + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/linux/runner/my_application.cc b/linux/runner/my_application.cc new file mode 100644 index 0000000..62a6c8b --- /dev/null +++ b/linux/runner/my_application.cc @@ -0,0 +1,143 @@ + +#include "my_application.h" + +#include + + + + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + + +static void first_frame_cb(MyApplication* self, FlView *view) +{ + gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view))); +} + + +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + + + GError* error = NULL; + GdkPixbuf* icon_pixbuf = gdk_pixbuf_new_from_file("assets/icon/komet_512.png", &error); + if (icon_pixbuf != NULL) { + gtk_window_set_icon(window, icon_pixbuf); + g_object_unref(icon_pixbuf); + } else { + g_warning("Failed to load icon: %s", error->message); + g_clear_error(&error); + + + icon_pixbuf = gdk_pixbuf_new_from_file("data/flutter_assets/assets/icon/komet_512.png", &error); + if (icon_pixbuf != NULL) { + gtk_window_set_icon(window, icon_pixbuf); + g_object_unref(icon_pixbuf); + } else { + g_warning("Failed to load icon: %s", error->message); + g_clear_error(&error); + } + } + + gtk_window_set_title(window, "Komet"); + + gtk_window_set_default_size(window, 1280, 720); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + GdkRGBA background_color; + + gdk_rgba_parse(&background_color, "#000000"); + fl_view_set_background_color(view, &background_color); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + + + g_signal_connect_swapped(view, "first-frame", G_CALLBACK(first_frame_cb), self); + gtk_widget_realize(GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + + +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + + +static void my_application_startup(GApplication* application) { + + + + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + + +static void my_application_shutdown(GApplication* application) { + + + + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + + +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + + + + + g_set_prgname(APPLICATION_ID); + + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/linux/runner/my_application.h b/linux/runner/my_application.h new file mode 100644 index 0000000..0118b8a --- /dev/null +++ b/linux/runner/my_application.h @@ -0,0 +1,10 @@ +#ifndef MY_APPLICATION_H +#define MY_APPLICATION_H + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, GtkApplication) + +MyApplication *my_application_new(); + +#endif \ No newline at end of file diff --git a/macos/.gitignore b/macos/.gitignore new file mode 100644 index 0000000..746adbb --- /dev/null +++ b/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..c2efd0b --- /dev/null +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..65ea0b3 --- /dev/null +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,50 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import app_links +import device_info_plus +import dynamic_color +import file_picker +import file_saver +import file_selector_macos +import flutter_inappwebview_macos +import flutter_secure_storage_macos +import flutter_timezone +import mobile_scanner +import open_file_mac +import package_info_plus +import path_provider_foundation +import share_plus +import shared_preferences_foundation +import smart_auth +import sqflite_darwin +import url_launcher_macos +import video_player_avfoundation +import wakelock_plus + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) + FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) + FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin")) + FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) + FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) + FlutterTimezonePlugin.register(with: registry.registrar(forPlugin: "FlutterTimezonePlugin")) + MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) + OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SmartAuthPlugin.register(with: registry.registrar(forPlugin: "SmartAuthPlugin")) + SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) +} diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..325ea1b --- /dev/null +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* gwid.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "gwid.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* gwid.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* gwid.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gwid.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gwid"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gwid.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gwid"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gwid.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gwid"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..f359c81 --- /dev/null +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..b3c1761 --- /dev/null +++ b/macos/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..82b6f9d9a33e198f5747104729e1fcef999772a5 GIT binary patch literal 102994 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..13b35eba55c6dabc3aac36f33d859266c18fa0d0 GIT binary patch literal 5680 zcmaiYXH?Tqu=Xz`p-L#B_gI#0we$cm_HcmYFP$?wjD#BaCN4mzC5#`>w9y6=ThxrYZc0WPXprg zYjB`UsV}0=eUtY$(P6YW}npdd;%9pi?zS3k-nqCob zSX_AQEf|=wYT3r?f!*Yt)ar^;l3Sro{z(7deUBPd2~(SzZ-s@0r&~Km2S?8r##9-< z)2UOSVaHqq6}%sA9Ww;V2LG=PnNAh6mA2iWOuV7T_lRDR z&N8-eN=U)-T|;wo^Wv=34wtV0g}sAAe}`Ph@~!|<;z7*K8(qkX0}o=!(+N*UWrkEja*$_H6mhK1u{P!AC39} z|3+Z(mAOq#XRYS)TLoHv<)d%$$I@+x+2)V{@o~~J-!YUI-Q9%!Ldi4Op&Lw&B>jj* zwAgC#Y>gbIqv!d|J5f!$dbCXoq(l3GR(S>(rtZ~Z*agXMMKN!@mWT_vmCbSd3dUUm z4M&+gz?@^#RRGal%G3dDvj7C5QTb@9+!MG+>0dcjtZEB45c+qx*c?)d<%htn1o!#1 zpIGonh>P1LHu3s)fGFF-qS}AXjW|M*2Xjkh7(~r(lN=o#mBD9?jt74=Rz85I4Nfx_ z7Z)q?!};>IUjMNM6ee2Thq7))a>My?iWFxQ&}WvsFP5LP+iGz+QiYek+K1`bZiTV- zHHYng?ct@Uw5!gquJ(tEv1wTrRR7cemI>aSzLI^$PxW`wL_zt@RSfZ1M3c2sbebM* ze0=;sy^!90gL~YKISz*x;*^~hcCoO&CRD)zjT(A2b_uRue=QXFe5|!cf0z1m!iwv5GUnLw9Dr*Ux z)3Lc!J@Ei;&&yxGpf2kn@2wJ2?t6~obUg;?tBiD#uo$SkFIasu+^~h33W~`r82rSa ztyE;ehFjC2hjpJ-e__EH&z?!~>UBb=&%DS>NT)1O3Isn-!SElBV2!~m6v0$vx^a<@ISutdTk1@?;i z<8w#b-%|a#?e5(n@7>M|v<<0Kpg?BiHYMRe!3Z{wYc2hN{2`6(;q`9BtXIhVq6t~KMH~J0~XtUuT06hL8c1BYZWhN zk4F2I;|za*R{ToHH2L?MfRAm5(i1Ijw;f+0&J}pZ=A0;A4M`|10ZskA!a4VibFKn^ zdVH4OlsFV{R}vFlD~aA4xxSCTTMW@Gws4bFWI@xume%smAnuJ0b91QIF?ZV!%VSRJ zO7FmG!swKO{xuH{DYZ^##gGrXsUwYfD0dxXX3>QmD&`mSi;k)YvEQX?UyfIjQeIm! z0ME3gmQ`qRZ;{qYOWt}$-mW*>D~SPZKOgP)T-Sg%d;cw^#$>3A9I(%#vsTRQe%moT zU`geRJ16l>FV^HKX1GG7fR9AT((jaVb~E|0(c-WYQscVl(z?W!rJp`etF$dBXP|EG z=WXbcZ8mI)WBN>3<@%4eD597FD5nlZajwh8(c$lum>yP)F}=(D5g1-WVZRc)(!E3} z-6jy(x$OZOwE=~{EQS(Tp`yV2&t;KBpG*XWX!yG+>tc4aoxbXi7u@O*8WWFOxUjcq z^uV_|*818$+@_{|d~VOP{NcNi+FpJ9)aA2So<7sB%j`$Prje&auIiTBb{oD7q~3g0 z>QNIwcz(V-y{Ona?L&=JaV5`o71nIsWUMA~HOdCs10H+Irew#Kr(2cn>orG2J!jvP zqcVX0OiF}c<)+5&p}a>_Uuv)L_j}nqnJ5a?RPBNi8k$R~zpZ33AA4=xJ@Z($s3pG9 zkURJY5ZI=cZGRt_;`hs$kE@B0FrRx(6K{`i1^*TY;Vn?|IAv9|NrN*KnJqO|8$e1& zb?OgMV&q5|w7PNlHLHF) zB+AK#?EtCgCvwvZ6*u|TDhJcCO+%I^@Td8CR}+nz;OZ*4Dn?mSi97m*CXXc=};!P`B?}X`F-B5v-%ACa8fo0W++j&ztmqK z;&A)cT4ob9&MxpQU41agyMU8jFq~RzXOAsy>}hBQdFVL%aTn~M>5t9go2j$i9=(rZ zADmVj;Qntcr3NIPPTggpUxL_z#5~C!Gk2Rk^3jSiDqsbpOXf^f&|h^jT4|l2ehPat zb$<*B+x^qO8Po2+DAmrQ$Zqc`1%?gp*mDk>ERf6I|42^tjR6>}4`F_Mo^N(~Spjcg z_uY$}zui*PuDJjrpP0Pd+x^5ds3TG#f?57dFL{auS_W8|G*o}gcnsKYjS6*t8VI<) zcjqTzW(Hk*t-Qhq`Xe+x%}sxXRerScbPGv8hlJ;CnU-!Nl=# zR=iTFf9`EItr9iAlAGi}i&~nJ-&+)Y| zMZigh{LXe)uR+4D_Yb+1?I93mHQ5{pId2Fq%DBr7`?ipi;CT!Q&|EO3gH~7g?8>~l zT@%*5BbetH)~%TrAF1!-!=)`FIS{^EVA4WlXYtEy^|@y@yr!C~gX+cp2;|O4x1_Ol z4fPOE^nj(}KPQasY#U{m)}TZt1C5O}vz`A|1J!-D)bR%^+=J-yJsQXDzFiqb+PT0! zIaDWWU(AfOKlSBMS};3xBN*1F2j1-_=%o($ETm8@oR_NvtMDVIv_k zlnNBiHU&h8425{MCa=`vb2YP5KM7**!{1O>5Khzu+5OVGY;V=Vl+24fOE;tMfujoF z0M``}MNnTg3f%Uy6hZi$#g%PUA_-W>uVCYpE*1j>U8cYP6m(>KAVCmbsDf39Lqv0^ zt}V6FWjOU@AbruB7MH2XqtnwiXS2scgjVMH&aF~AIduh#^aT1>*V>-st8%=Kk*{bL zzbQcK(l2~)*A8gvfX=RPsNnjfkRZ@3DZ*ff5rmx{@iYJV+a@&++}ZW+za2fU>&(4y`6wgMpQGG5Ah(9oGcJ^P(H< zvYn5JE$2B`Z7F6ihy>_49!6}(-)oZ(zryIXt=*a$bpIw^k?>RJ2 zQYr>-D#T`2ZWDU$pM89Cl+C<;J!EzHwn(NNnWpYFqDDZ_*FZ{9KQRcSrl5T>dj+eA zi|okW;6)6LR5zebZJtZ%6Gx8^=2d9>_670!8Qm$wd+?zc4RAfV!ZZ$jV0qrv(D`db zm_T*KGCh3CJGb(*X6nXzh!h9@BZ-NO8py|wG8Qv^N*g?kouH4%QkPU~Vizh-D3<@% zGomx%q42B7B}?MVdv1DFb!axQ73AUxqr!yTyFlp%Z1IAgG49usqaEbI_RnbweR;Xs zpJq7GKL_iqi8Md?f>cR?^0CA+Uk(#mTlGdZbuC*$PrdB$+EGiW**=$A3X&^lM^K2s zzwc3LtEs5|ho z2>U(-GL`}eNgL-nv3h7E<*<>C%O^=mmmX0`jQb6$mP7jUKaY4je&dCG{x$`0=_s$+ zSpgn!8f~ya&U@c%{HyrmiW2&Wzc#Sw@+14sCpTWReYpF9EQ|7vF*g|sqG3hx67g}9 zwUj5QP2Q-(KxovRtL|-62_QsHLD4Mu&qS|iDp%!rs(~ah8FcrGb?Uv^Qub5ZT_kn%I^U2rxo1DDpmN@8uejxik`DK2~IDi1d?%~pR7i#KTS zA78XRx<(RYO0_uKnw~vBKi9zX8VnjZEi?vD?YAw}y+)wIjIVg&5(=%rjx3xQ_vGCy z*&$A+bT#9%ZjI;0w(k$|*x{I1c!ECMus|TEA#QE%#&LxfGvijl7Ih!B2 z6((F_gwkV;+oSKrtr&pX&fKo3s3`TG@ye+k3Ov)<#J|p8?vKh@<$YE@YIU1~@7{f+ zydTna#zv?)6&s=1gqH<-piG>E6XW8ZI7&b@-+Yk0Oan_CW!~Q2R{QvMm8_W1IV8<+ zQTyy=(Wf*qcQubRK)$B;QF}Y>V6d_NM#=-ydM?%EPo$Q+jkf}*UrzR?Nsf?~pzIj$ z<$wN;7c!WDZ(G_7N@YgZ``l;_eAd3+;omNjlpfn;0(B7L)^;;1SsI6Le+c^ULe;O@ zl+Z@OOAr4$a;=I~R0w4jO`*PKBp?3K+uJ+Tu8^%i<_~bU!p%so z^sjol^slR`W@jiqn!M~eClIIl+`A5%lGT{z^mRbpv}~AyO%R*jmG_Wrng{B9TwIuS z0!@fsM~!57K1l0%{yy(#no}roy#r!?0wm~HT!vLDfEBs9x#`9yCKgufm0MjVRfZ=f z4*ZRc2Lgr(P+j2zQE_JzYmP0*;trl7{*N341Cq}%^M^VC3gKG-hY zmPT>ECyrhIoFhnMB^qpdbiuI}pk{qPbK^}0?Rf7^{98+95zNq6!RuV_zAe&nDk0;f zez~oXlE5%ve^TmBEt*x_X#fs(-En$jXr-R4sb$b~`nS=iOy|OVrph(U&cVS!IhmZ~ zKIRA9X%Wp1J=vTvHZ~SDe_JXOe9*fa zgEPf;gD^|qE=dl>Qkx3(80#SE7oxXQ(n4qQ#by{uppSKoDbaq`U+fRqk0BwI>IXV3 zD#K%ASkzd7u>@|pA=)Z>rQr@dLH}*r7r0ng zxa^eME+l*s7{5TNu!+bD{Pp@2)v%g6^>yj{XP&mShhg9GszNu4ITW=XCIUp2Xro&1 zg_D=J3r)6hp$8+94?D$Yn2@Kp-3LDsci)<-H!wCeQt$e9Jk)K86hvV^*Nj-Ea*o;G zsuhRw$H{$o>8qByz1V!(yV{p_0X?Kmy%g#1oSmlHsw;FQ%j9S#}ha zm0Nx09@jmOtP8Q+onN^BAgd8QI^(y!n;-APUpo5WVdmp8!`yKTlF>cqn>ag`4;o>i zl!M0G-(S*fm6VjYy}J}0nX7nJ$h`|b&KuW4d&W5IhbR;-)*9Y0(Jj|@j`$xoPQ=Cl literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3f5fa40fb3d1e0710331a48de5d256da3f275d GIT binary patch literal 520 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 literal 0 HcmV?d00001 diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1632cfddf3d9dade342351e627a0a75609fb46 GIT binary patch literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..d8d0b39 --- /dev/null +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = gwid + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2025 com.gwid.app. All rights reserved. diff --git a/macos/Runner/Configs/Debug.xcconfig b/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Release.xcconfig b/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/macos/Runner/Configs/Warnings.xcconfig b/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/macos/Runner/DebugProfile.entitlements b/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..3cc05eb --- /dev/null +++ b/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/macos/Runner/Release.entitlements b/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..e573b40 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,1543 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + app_links_linux: + dependency: transitive + description: + name: app_links_linux + sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + app_links_platform_interface: + dependency: transitive + description: + name: app_links_platform_interface + sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + app_links_web: + dependency: transitive + description: + name: app_links_web + sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" + url: "https://pub.dev" + source: hosted + version: "1.6.5" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + cached_network_image: + dependency: "direct main" + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + chewie: + dependency: "direct main" + description: + name: chewie + sha256: "44bcfc5f0dfd1de290c87c9d86a61308b3282a70b63435d5557cfd60f54a69ca" + url: "https://pub.dev" + source: hosted + version: "1.13.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + url: "https://pub.dev" + source: hosted + version: "0.4.2" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" + crypto: + dependency: "direct main" + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + csslib: + dependency: transitive + description: + name: csslib + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 + url: "https://pub.dev" + source: hosted + version: "10.1.2" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" + dio: + dependency: transitive + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + disable_battery_optimization: + dependency: "direct main" + description: + name: disable_battery_optimization + sha256: "7fbda76cdd30d01d75e091db8869b8cf2fd4c7b7edef3abce0d7206569603051" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + dynamic_color: + dependency: "direct main" + description: + name: dynamic_color + sha256: "43a5a6679649a7731ab860334a5812f2067c2d9ce6452cf069c5e0c25336c17c" + url: "https://pub.dev" + source: hosted + version: "1.8.1" + encrypt: + dependency: "direct main" + description: + name: encrypt + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" + es_compression: + dependency: "direct main" + description: + name: es_compression + sha256: "174d2cee4e182d1a8df92712eaa6ee56a0adf83d4b8a14838c66380caa4e65a7" + url: "https://pub.dev" + source: hosted + version: "2.0.14" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + file_picker: + dependency: "direct main" + description: + name: file_picker + sha256: f2d9f173c2c14635cc0e9b14c143c49ef30b4934e8d1d274d6206fcb0086a06f + url: "https://pub.dev" + source: hosted + version: "10.3.3" + file_saver: + dependency: "direct main" + description: + name: file_saver + sha256: "9d93db09bd4da9e43238f9dd485360fc51a5c138eea5ef5f407ec56e58079ac0" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c" + url: "https://pub.dev" + source: hosted + version: "0.9.4+4" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.dev" + source: hosted + version: "0.9.3+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_background_service: + dependency: "direct main" + description: + name: flutter_background_service + sha256: "70a1c185b1fa1a44f8f14ecd6c86f6e50366e3562f00b2fa5a54df39b3324d3d" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + flutter_background_service_android: + dependency: transitive + description: + name: flutter_background_service_android + sha256: ca0793d4cd19f1e194a130918401a3d0b1076c81236f7273458ae96987944a87 + url: "https://pub.dev" + source: hosted + version: "6.3.1" + flutter_background_service_ios: + dependency: transitive + description: + name: flutter_background_service_ios + sha256: "6037ffd45c4d019dab0975c7feb1d31012dd697e25edc05505a4a9b0c7dc9fba" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + flutter_background_service_platform_interface: + dependency: transitive + description: + name: flutter_background_service_platform_interface + sha256: ca74aa95789a8304f4d3f57f07ba404faa86bed6e415f83e8edea6ad8b904a41 + url: "https://pub.dev" + source: hosted + version: "5.1.2" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + flutter_colorpicker: + dependency: "direct main" + description: + name: flutter_colorpicker + sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter_highlight: + dependency: "direct main" + description: + name: flutter_highlight + sha256: "7b96333867aa07e122e245c033b8ad622e4e3a42a1a2372cbb098a2541d8782c" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + flutter_inappwebview: + dependency: "direct main" + description: + name: flutter_inappwebview + sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" + url: "https://pub.dev" + source: hosted + version: "6.1.5" + flutter_inappwebview_android: + dependency: transitive + description: + name: flutter_inappwebview_android + sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba" + url: "https://pub.dev" + source: hosted + version: "1.1.3" + flutter_inappwebview_internal_annotations: + dependency: transitive + description: + name: flutter_inappwebview_internal_annotations + sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + flutter_inappwebview_ios: + dependency: transitive + description: + name: flutter_inappwebview_ios + sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_macos: + dependency: transitive + description: + name: flutter_inappwebview_macos + sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_platform_interface: + dependency: transitive + description: + name: flutter_inappwebview_platform_interface + sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500 + url: "https://pub.dev" + source: hosted + version: "1.3.0+1" + flutter_inappwebview_web: + dependency: transitive + description: + name: flutter_inappwebview_web + sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_inappwebview_windows: + dependency: transitive + description: + name: flutter_inappwebview_windows + sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + flutter_launcher_icons: + dependency: "direct main" + description: + name: flutter_launcher_icons + sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7" + url: "https://pub.dev" + source: hosted + version: "0.14.4" + flutter_linkify: + dependency: "direct main" + description: + name: flutter_linkify + sha256: "74669e06a8f358fee4512b4320c0b80e51cffc496607931de68d28f099254073" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27" + url: "https://pub.dev" + source: hosted + version: "0.7.7+1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31 + url: "https://pub.dev" + source: hosted + version: "2.0.30" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + url: "https://pub.dev" + source: hosted + version: "9.2.4" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_timezone: + dependency: "direct main" + description: + name: flutter_timezone + sha256: ccad42fbb5d01d51d3eb281cc4428fca556cc4063c52bd9fa40f80cd93b8e649 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + sha256: "517b20870220c48752eafa0ba1a797a092fb22df0d89535fd9991e86ee2cdd9c" + url: "https://pub.dev" + source: hosted + version: "6.3.2" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" + highlight: + dependency: transitive + description: + name: highlight + sha256: "5353a83ffe3e3eca7df0abfb72dcf3fa66cc56b953728e7113ad4ad88497cf21" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + html: + dependency: transitive + description: + name: html + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + url: "https://pub.dev" + source: hosted + version: "0.15.6" + http: + dependency: "direct main" + description: + name: http + sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 + url: "https://pub.dev" + source: hosted + version: "1.5.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + url: "https://pub.dev" + source: hosted + version: "4.5.4" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "8dfe08ea7fcf7467dbaf6889e72eebd5e0d6711caae201fdac780eb45232cd02" + url: "https://pub.dev" + source: hosted + version: "0.8.13+3" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e + url: "https://pub.dev" + source: hosted + version: "0.8.13" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae + url: "https://pub.dev" + source: hosted + version: "0.2.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + linkify: + dependency: transitive + description: + name: linkify + sha256: "4139ea77f4651ab9c315b577da2dd108d9aa0bd84b5d03d33323f1970c645832" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + lints: + dependency: transitive + description: + name: lints + sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 + url: "https://pub.dev" + source: hosted + version: "5.1.1" + markdown: + dependency: transitive + description: + name: markdown + sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1" + url: "https://pub.dev" + source: hosted + version: "7.3.0" + mask_text_input_formatter: + dependency: "direct main" + description: + name: mask_text_input_formatter + sha256: "978c58ec721c25621ceb468e633f4eef64b64d45424ac4540e0565d4f7c800cd" + url: "https://pub.dev" + source: hosted + version: "2.9.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mobile_scanner: + dependency: "direct main" + description: + name: mobile_scanner + sha256: "5e7e09d904dc01de071b79b3f3789b302b0ed3c9c963109cd3f83ad90de62ecf" + url: "https://pub.dev" + source: hosted + version: "7.1.2" + msgpack_dart: + dependency: "direct main" + description: + name: msgpack_dart + sha256: c2d235ed01f364719b5296aecf43ac330f0d7bc865fa134d0d7910a40454dffb + url: "https://pub.dev" + source: hosted + version: "1.0.1" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + open_file: + dependency: "direct main" + description: + name: open_file + sha256: d17e2bddf5b278cb2ae18393d0496aa4f162142ba97d1a9e0c30d476adf99c0e + url: "https://pub.dev" + source: hosted + version: "3.5.10" + open_file_android: + dependency: transitive + description: + name: open_file_android + sha256: "58141fcaece2f453a9684509a7275f231ac0e3d6ceb9a5e6de310a7dff9084aa" + url: "https://pub.dev" + source: hosted + version: "1.0.6" + open_file_ios: + dependency: transitive + description: + name: open_file_ios + sha256: "02996f01e5f6863832068e97f8f3a5ef9b613516db6897f373b43b79849e4d07" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + open_file_linux: + dependency: transitive + description: + name: open_file_linux + sha256: d189f799eecbb139c97f8bc7d303f9e720954fa4e0fa1b0b7294767e5f2d7550 + url: "https://pub.dev" + source: hosted + version: "0.0.5" + open_file_mac: + dependency: transitive + description: + name: open_file_mac + sha256: "1440b1e37ceb0642208cfeb2c659c6cda27b25187a90635c9d1acb7d0584d324" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + open_file_platform_interface: + dependency: transitive + description: + name: open_file_platform_interface + sha256: "101b424ca359632699a7e1213e83d025722ab668b9fd1412338221bf9b0e5757" + url: "https://pub.dev" + source: hosted + version: "1.0.3" + open_file_web: + dependency: transitive + description: + name: open_file_web + sha256: e3dbc9584856283dcb30aef5720558b90f88036360bd078e494ab80a80130c4f + url: "https://pub.dev" + source: hosted + version: "0.0.4" + open_file_windows: + dependency: transitive + description: + name: open_file_windows + sha256: d26c31ddf935a94a1a3aa43a23f4fff8a5ff4eea395fe7a8cb819cf55431c875 + url: "https://pub.dev" + source: hosted + version: "0.0.3" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" + url: "https://pub.dev" + source: hosted + version: "8.3.1" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + path: + dependency: "direct main" + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db" + url: "https://pub.dev" + source: hosted + version: "2.2.18" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + url: "https://pub.dev" + source: hosted + version: "11.4.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + url: "https://pub.dev" + source: hosted + version: "12.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + url: "https://pub.dev" + source: hosted + version: "9.4.7" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.dev" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + pinput: + dependency: "direct main" + description: + name: pinput + sha256: "6d571e38a484f7515a52e89024ef416f11fa6171ac6f32303701374ab9890efa" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" + provider: + dependency: "direct main" + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + qr: + dependency: transitive + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" + url: "https://pub.dev" + source: hosted + version: "4.1.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" + scrollable_positioned_list: + dependency: "direct main" + description: + name: scrollable_positioned_list + sha256: "1b54d5f1329a1e263269abc9e2543d90806131aa14fe7c6062a8054d57249287" + url: "https://pub.dev" + source: hosted + version: "0.3.8" + share_plus: + dependency: "direct main" + description: + name: share_plus + sha256: "3424e9d5c22fd7f7590254ba09465febd6f8827c8b19a44350de4ac31d92d3a6" + url: "https://pub.dev" + source: hosted + version: "12.0.0" + share_plus_platform_interface: + dependency: transitive + description: + name: share_plus_platform_interface + sha256: "88023e53a13429bd65d8e85e11a9b484f49d4c190abbd96c7932b74d6927cc9a" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "0b0f98d535319cb5cdd4f65783c2a54ee6d417a2f093dbb18be3e36e4c3d181f" + url: "https://pub.dev" + source: hosted + version: "2.4.14" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + smart_auth: + dependency: transitive + description: + name: smart_auth + sha256: "88aa8fe66e951c78a307f26d1c29672dce2e9eb3da2e12e853864d0e615a73ad" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + socks5_proxy: + dependency: "direct main" + description: + name: socks5_proxy + sha256: "80fa31a9ebfc0dc8de7b0e568c8d8927b65558ef2c7591cbee5afac814fb8f74" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 + url: "https://pub.dev" + source: hosted + version: "2.4.2+2" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.dev" + source: hosted + version: "3.4.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + timezone: + dependency: "direct main" + description: + name: timezone + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + url: "https://pub.dev" + source: hosted + version: "0.9.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + universal_platform: + dependency: transitive + description: + name: universal_platform + sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: c0fb544b9ac7efa10254efaf00a951615c362d1ea1877472f8f6c0fa00fcf15b + url: "https://pub.dev" + source: hosted + version: "6.3.23" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 + url: "https://pub.dev" + source: hosted + version: "6.3.4" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f + url: "https://pub.dev" + source: hosted + version: "3.2.3" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + uuid: + dependency: "direct main" + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + video_player: + dependency: "direct main" + description: + name: video_player + sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a" + url: "https://pub.dev" + source: hosted + version: "2.10.0" + video_player_android: + dependency: transitive + description: + name: video_player_android + sha256: cf768d02924b91e333e2bc1ff928528f57d686445874f383bafab12d0bdfc340 + url: "https://pub.dev" + source: hosted + version: "2.8.17" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + sha256: "19ed1162a7a5520e7d7791e0b7b73ba03161b6a69428b82e4689e435b325432d" + url: "https://pub.dev" + source: hosted + version: "2.8.5" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + sha256: "9e372520573311055cb353b9a0da1c9d72b094b7ba01b8ecc66f28473553793b" + url: "https://pub.dev" + source: hosted + version: "6.5.0" + video_player_web: + dependency: transitive + description: + name: video_player_web + sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + wakelock_plus: + dependency: transitive + description: + name: wakelock_plus + sha256: "61713aa82b7f85c21c9f4cd0a148abd75f38a74ec645fcb1e446f882c82fd09b" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + wakelock_plus_platform_interface: + dependency: transitive + description: + name: wakelock_plus_platform_interface + sha256: "036deb14cd62f558ca3b73006d52ce049fabcdcb2eddfe0bf0fe4e8a943b5cf2" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket_channel: + dependency: "direct main" + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.dev" + source: hosted + version: "5.14.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" + url: "https://pub.dev" + source: hosted + version: "1.1.5" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.9.2 <4.0.0" + flutter: ">=3.35.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..04fe75b --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,188 @@ +name: gwid +description: "A new Flutter project." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 0.2.0+4 + +environment: + sdk: ^3.9.2 + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + flutter_localizations: # <-- ДОБАВЬ ЭТУ СТРОКУ + sdk: flutter # <-- И ЭТУ СТРОКУ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.8 + + + dynamic_color: ^1.7.0 + + + pinput: ^4.0.0 + + + mask_text_input_formatter: ^2.9.0 + + + web_socket_channel: ^2.4.0 + + uuid: ^4.4.0 + + device_info_plus: ^10.1.0 + + package_info_plus: ^8.0.0 + + + shared_preferences: ^2.2.3 + + intl: ^0.20.2 + + provider: ^6.1.2 + flutter_colorpicker: ^1.1.0 + + http: ^1.5.0 + image_picker: ^1.1.2 + path_provider: ^2.1.4 + path: ^1.9.0 + crypto: ^3.0.3 + + cached_network_image: ^3.3.1 + + scrollable_positioned_list: ^0.3.8 + + socks5_proxy: ^2.1.1 + + flutter_launcher_icons: ^0.14.4 + + flutter_timezone: ^5.0.0 + + timezone: ^0.9.2 + + file_saver: ^0.3.1 + + file_picker: ^10.3.3 + + permission_handler: ^11.3.1 + + encrypt: ^5.0.3 + + google_fonts: ^6.2.1 + + share_plus: ^12.0.0 + + url_launcher: 6.3.2 + + flutter_background_service: ^5.0.1 + + flutter_markdown: ^0.7.7 + + video_player: ^2.9.2 + + qr_flutter: ^4.1.0 + + mobile_scanner: ^7.1.2 + + es_compression: ^2.0.14 + + msgpack_dart: ^1.0.1 + + disable_battery_optimization: ^1.1.2 + + flutter_highlight: ^0.7.0 + + flutter_linkify: ^6.0.0 + app_links: ^6.4.1 + + open_file: ^3.5.2 + + flutter_secure_storage: ^9.2.4 + flutter_inappwebview: ^6.1.5 + + chewie: ^1.7.5 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +flutter_launcher_icons: + android: true + ios: true + image_path: "assets/icon/icon1.jpg" + adaptive_icon_background: "assets/icon/bg.png" + adaptive_icon_foreground: "assets/icon/komet_512.png" + windows: + generate: true + image_path: "assets/icon/komet_512.png" + icon_size: 256 + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/images/ + - assets/icon/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package diff --git a/windows/.gitignore b/windows/.gitignore new file mode 100644 index 0000000..d492d0d --- /dev/null +++ b/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt new file mode 100644 index 0000000..6fe6c87 --- /dev/null +++ b/windows/CMakeLists.txt @@ -0,0 +1,111 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(gwid LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "Komet") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + +if(TARGET flutter_secure_storage_windows_plugin) + target_link_libraries(flutter_secure_storage_windows_plugin PRIVATE atls) +endif() + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..61f4eb0 --- /dev/null +++ b/windows/flutter/CMakeLists.txt @@ -0,0 +1,110 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + ${FLUTTER_TARGET_PLATFORM} $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..2f0c299 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,44 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + DynamicColorPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); + FileSaverPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSaverPlugin")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); + FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi")); + FlutterSecureStorageWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); + FlutterTimezonePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterTimezonePluginCApi")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + SmartAuthPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SmartAuthPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); +} diff --git a/windows/flutter/generated_plugin_registrant.h b/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..d150f00 --- /dev/null +++ b/windows/flutter/generated_plugins.cmake @@ -0,0 +1,34 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + app_links + dynamic_color + file_saver + file_selector_windows + flutter_inappwebview_windows + flutter_secure_storage_windows + flutter_timezone + permission_handler_windows + share_plus + smart_auth + url_launcher_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..394917c --- /dev/null +++ b/windows/runner/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc new file mode 100644 index 0000000..1be8780 --- /dev/null +++ b/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.gwid.app" "\0" + VALUE "FileDescription", "Komet" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "Komet" "\0" + VALUE "LegalCopyright", "Copyright (C) 2025 com.gwid.app. All rights reserved." "\0" + VALUE "OriginalFilename", "Komet.exe" "\0" + VALUE "ProductName", "Komet" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..955ee30 --- /dev/null +++ b/windows/runner/flutter_window.cpp @@ -0,0 +1,71 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/windows/runner/flutter_window.h b/windows/runner/flutter_window.h new file mode 100644 index 0000000..6da0652 --- /dev/null +++ b/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp new file mode 100644 index 0000000..3761490 --- /dev/null +++ b/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.Create(L"Komet", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/windows/runner/resource.h b/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a2fffd6c2abc1abdc08f82e933678cac907469aa GIT binary patch literal 23137 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 + + + + PerMonitorV2 + + + + + + + + + diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp new file mode 100644 index 0000000..3a0b465 --- /dev/null +++ b/windows/runner/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/windows/runner/utils.h b/windows/runner/utils.h new file mode 100644 index 0000000..3879d54 --- /dev/null +++ b/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp new file mode 100644 index 0000000..60608d0 --- /dev/null +++ b/windows/runner/win32_window.cpp @@ -0,0 +1,288 @@ +#include "win32_window.h" + +#include +#include + +#include "resource.h" + +namespace { + +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + } + FreeLibrary(user32_module); +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + UpdateTheme(window); + + return OnCreate(); +} + +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h new file mode 100644 index 0000000..e901dde --- /dev/null +++ b/windows/runner/win32_window.h @@ -0,0 +1,102 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates a win32 window with |title| that is positioned and sized using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_

{ioE79kW2g9Ua`a%34vMJ%4X zRU+$*u2N`jpWEyX!!|qOrFUDq&D#2R`?z@X`<{L?)<%i76Zc%Po=DW_{2(`+@Y#R& zO;)lQhp+MBU+pLa>_QU^52^|)VYtHMA;}jZ;Yl!!G3;g{me_pw@L_+~!^LNdt)cq3 zL)FOZ0@9mjH>xtPN6%mMgJ6rNuWO)6ttHet$e2O7ZR&n->hQ!SsB-3lRD&6nLs{-u zyc%c9`aa=-`|(TLPC*7EUVh}#T5Aoc&CQF&v;_;p!oKI>&Mw2aWFVP(j+CLGe)lSs zoZi3x=9v}SHW8AUm0<8~AtrQR7&sfvZaM8i`T3RMOJBNum%16_;Zd7hdU4U0`qR%< zTpY*k)RGwObwHF`1wES zE(FYWN1OMmfHsLHaSr6lSHw0!)#DgL_wWWG7)NbwN+ zqaNIbQj=I7R>SS9&?UkwkXb)0hX-t}OJF2`s+t9n5?GRMQPl78Z&7!MxXNs878w%v`DO#^ZRy;6E;L+~O|;?CC*u z-a`)vPVwkKNR|lXnH-@^{ju1ZjJ*#WuO3=(Sma@I@rz9|O40&Iq#x~)lNzJC`LYWN zVK;VfqpDCfP`Dr2G$b3`x??P+>HF3H zKoN_dQPyKoxWbEEz3 z@9N*)hKc~`sJswWE(bLDdKAo!RFx7r9&_I5?ls1{5g~z=+Sg)dg2O=4&@59PV{qxEgLRBwWU30+Bhp4 ztue+Zj!k1D|K9Jmy^l*xf5jTeg>$IZSYFjURCb~6;nS9u*oH!+P8ODX_r&9!oQZt|c z-g$YT>;^(uIw2_fWP1w#)__c`q5Q09@Aq;WA5<4VP46eBYoRQqw8w|rp~mlirko{D zoB;zcyuwn#y0V|9plpYi<^>eWm(6K=_0p6gjN#{y8CeuKVDF0}9t0%=a)h|%wuuEo zF&{S;hHX`lo!y6|in*AH+IVs72SxL#HZN?k+k}bfvPSyNUZFh9ZatAmv&KPukSkIZ z=avZlGe^JQmkbpFTcq?J3aBP^td-+&X^;{#A(-%x{?O1Q9C&G!!||5svyoeP$B|*^ z%#XvZ==~pBjO^I`Ag_w2nq zuUN#it+ckV)H$r>uGEupGC51*M1r3dN-5vG^9fmAVwoKK`tcBrvV3CxS0T9+W&8dI zkFYQ$rRL`T*xAld_{`jRk8j4tUG}zt>38CJB{NgzoTJ7SGsNPDm8Zpc!EtP?zU-84 z$7sv8+?no8XB0A<(MYvhpR$j9z(3VT`6LQ}hjZvqx2FmyHRS0)s9MPi!Q*ky>s#`g z7{`%>OHz!tpFMu|)n~6>Y2I9CD!$hm6fi~=Lz&Ejyh|1}bPX|9D=bCb5V}ySeW4U8 z$lHISdk;&O?GelXgQ_y4%*=pwr`Y}cdZoWhJXwuq>Pwqm++YkK$C+kcy+HSwedEb~N>SX!i2{{kK(li~jh86v8h}7<1m| zl@GYwQOt*|EKgU(GA?R;ST#AG%|+2=+GPxBWv$=V({egxxk#CmzyJm*CCdPnWDbQ| zqZ0RCQT!y~v*>QJxgiGz7S`7|?FO&0%@10w_UEg7_~6F+0N2e*iOHTd=2~Rfo+j*D z7hjO~wK^qx_X~--ZI_9G*Vnwt7;AL1f~uWlPZ4ExoEPlo%WpyXij&AjBFe?0&Thue z&&!MdVs3(v@{`w^^7XgJoXn3RqPA|@WvX z0TUAw*LII=c=#c>`Ohe95cdNLL{M5sAcl#>__}O=LOk}6k=Pm}iVvi3dLKDiERhq(L-~3Bi4reT{MFyCG0T^IZd4`;^?kK3_`bt^-K&-&$ zu$!RcpOyXLrGadAd#}!Y^iqO|mO|QaIYlU^LevF8;?)67Z~HKt-h00{?c(h($V3z* zYN;_`jAM+Q@3=N}EpoC?5q|Rx%tm1bN{ms1U50k#2^IoA>IU|ct{8mnGmi% z%K7H~@w$)J`SwnB?Sj%2ZsTn%lx8-a6znelNM@HUs(`ivFrez;Dgmh8Da(R_-PI}I zxndjJ*CgX@VUoy%#CPmwtLcI!rzIBT z0A?(aQe6XCP$;OJ!&!bH)d`2!9OQAIvJu4gW3E--SD-iiunC_@%+{r~wzCw*fUcB6 zl2mufP^j}Ri84Q10ut^`6V(0jm#VHnCQe@_1hZ<~&#JL3-+eLKvPg=VkOTMoMBHpM zXHtJ`{5bz6{gJ2if{8@dopcHl#(2-Mj`c)RLuMG@XIgJb~EsEp2XH-*yy+1rCqSm`AL8A<1ju?#_7lXJw^f?^TXdMHKjP0SC866@B(tN*wE`nRXQMe9~J zr)gjYuO+aFgh9?ZSJk1QR&v^}yiRFWE<$Km-^M6E3=#;p&C7Xd)?ND4p zm4}J&-H7TkFNG*~Q%d1hKe0+;`sM%s)9^R;{^rgv8l)L+mDo&%kj1zLq4IR|ws$6x7%Am5W!n zo_D1jXlkeCWp>o{hAd~E#1OEVG2Gl9YtBcvO`P4oCd(!JQ_KXLRe%nPoEsn zU3cS&%C_A1c^tIS$b)mhmUtrt!s1dA$Df zKQDi4{!isUr$l8r_b?3C0GmlERXyq&%q$eVf9#T`k_v^-(9oT+LfHn&!Wf>vjf0pI z{Uwmt2K~>lce4v#k+_UOio!apk~^iQcx5Bzi-#cpq*7uwx=rZH9n10@UdZN$FOnF# z|2hY9T0g&F=(4>}tNW$W7`ngNpDqR(x^KjNDt@s|ZuXO><)1GvHZNiR;!}Q@pLQIC z)dBZ=Rg{Q`w^3;8_rq#^d{QanY&hV6tg;-laR%Z&+ps^*uD^E*H~&dLsvVw3LFXV5 z^hXwH5s?rUKOlq{kMYoESR#4%7jb`U{`wMLJ|HN%Q?hG}xtba%^+`>}Wn0oimy5J6 z?n(c@|4RPGzJI{}by+ZkB}fT@IT(;3;nurlsVEp{iW8RW=JKsnkRTCAs@7ZvAzqq| zpwPPP6vXsYn2f_x#bQ<^M^6_T%5<&1)%suaAOD8;PbmL=;jPKI=3tl&jVvXg(!1e|#W-7* zq05dd1cDq$$_uk$_9)c&om`5?~F4oJ?Yu`~%Nl^p$4vHJu$j)qYrzwohG35m( zMqn-&!>7DnV&kE4zoSptZ&r(;*EVw{c0(VB)vVX5K$UD9R~VubV={gF@B0O4v!5u< zv_w;iDrl|Hi0xCxy-HqY)p$I*+LDYse5iLUpKbaRez@~3`}q2L`K>CdQgr%IRfsVw zVd>$^ST#X=yw+NfNi5ob{h$89^mi%#_(wB(K%H}@OJgXP$d%=ku#Z+yjPuK5kJmXo z{jMzjQG#R=2chPuy@cdJTHTDA>t8;I{hsU`t<`D_dUec{63z5n+LH8ZHJ&~9GO@? zZ<{V6?kF8=rxs6qzL}Sm>*rGhn(32fKgmeD;i7P9U z_y0Tpo7n7k$Ra#@vWl*-&125C+T|INFzD{GIeEA&q_V{{W)O;)>Y~OFJ&yRZIlP%!Vpyef`QSrixUEeG=Xk$Zbx$2AAk?A$g%{`o&g4dxHXhQc))WwX|Hk7A52 z*5Q@doe0c{Z|^ydL6U{8lA9CJ#M(=Ee&l(?b9@ZnjY+N?@8Se}en%9<3HOHjoQt+u zSyn3>ZBd8r+A|AM%|(__D;c}`3fk;vQ4jnVpg;%>JQ$G(D~aSO2M+7;*^`GhZ-m|h z58YY5zOHY^$2Zu^o8oOS#&iZ_BZu2ahQ|q!glaXsP(xusOuIw4jn!;j_4oJw0sYH% zd1#;-DGjhbW^-7tsw%J=(%ex{QPki}evp>gd>ok5w&!(`jkY^4b^ zD6hpdFDdstEtgA?NP&fVhgCV&)Q?Xs;q;i~z4^<9uBKFy*4>zmDPI5497fR}iqwL+ z!*D(!r#;M1==&IqZ;vbHPD9W=eJ<~}TTxY08Drf29>03_MA6+fr_7458WD>z#_;Yj zLc~iEQEP1_Ek=l#E^c!))cjv$QPiS+W)ita5J%EBTRL*GO zC)>Nk{7Hvzh&=x6j!P1o=?D1TeKUQ0R4?P(;8*&w6VhltM(ROGmKCqPjSUO&xVEvV zQc$ZVzbVR}ntvjHZ~78pwW1cw+Pai9S7&ijXy`0BT<)<9-NryCa7s4Uv51Ae8{H7kCMKqn zyLp287O1GjSSd}%y^$;R1IH$-gD#zS}Xf8VeE-}3MCjtude&iWDyUV_|i<6K6Hv&QIWdz z%u%J!bRcH?%AjbWKE%b&-NoVeqSiv$T&P(hwj+4oWTTL{Sjv7}46(Qn5jLN3@z8D$ zE~^{pvRJ?W!J<-W!y?I*!Wj_+*ZX25eD#m~7IJeRvb|Rkm|H2J%n|O7W&4v4qRtia z0ZCZ&&mJF(#P*&M{lj;@5g&iJ+jodjfVSNlyLVn(pT<(UAE`m1QEccaG&{-H->1Lh z{l~NL$3Ipn0XCSCNJ$bPNCPvvpk|`f^Ot^9u+QC83y#NLj<+Uu5nKi`fe~EtW+u_m zwuEyz_tEie?rw4K1F4U5EW7vYn2tkrm$zlr+Z*@iD?QO&g)wf1{lqq-H%NjY zv?a_r>}Dh8g5O0%4N3hxp@cJ|q^)V3@Cn7S{`)tpKu*_X3CjABEKUDJxsqJ4TrSIL zMpj7vB+t*i5B<~UuGZUIyZ0A7(5-gdZjhMV4>Rks+brwJxw%|5hPCtOMJ2Ym?aWPr zCL0x`)p%dU`>_%te1%wS*3cHAtmfi=OVps@7&=W3Y_dDoK@`W985tpQF}NX6WE>$ju|pJ;sgAHGTQhf1~mZVRY#{y?tfA%Jkg0QLZy< zk=GXC5Mf1PCB(QlCK$OL8NCT#{bS-+{9TW&vSMs6CWd=<8S^Z z>vTX4#BSEQu`f_9Acd`{YMxm08P%}3Vhjc`XekgYVaGbI$}<1eW- zbG~E@s%$5JzTf+H+mQsldEr_$T+BJAV1E87!pp5!P!SR3fp3`6Lv%vkwt_BM{sHTIV11>Km9MhY<&Mlj-Fe{ zyX{&7^GbrO`$^;0Le*Mh7<6b2!D5VqBsh{|W{pZPejJ~-kf5Vhj$;uEdX{Sza4EO4M3+lFW&b7EAP2t~eoXO72@u~9*l z6Tjs5Ywhj^MeGxP-H__uy%Y8%6O+s&#W;TE!i-J)k`SBwM06wERUSoE(PO?=EhmJe z7W&J;JZ5edB;MwHcwHOp8z2P_xvOQ)u9*|^MudIelmkt;OoS>el5` zsY;nlGSg}Z7WAP=L?oP>`vhyhKo3C4jSyXkZEWM>1QBBhf)AE=e(g60=kI_k&zxdu zYzI@#vj4&Y(+k%=#2oBpYVjKH0$xhXdz`Ki~ z0zn`X4!g1YxFlX&ReqjQm!#z<^)tUgN0?qbmF&HE z^a<(&g=u#}YztwSclUB}x;({TI!Ni%cQ%KCAkhI!V>om(S$FKZvsEqySd%6>&tW?$COjFRw=w8u`fUp?=-UyW@lw`77eHvdkx;Je?;^JZq z$c3wZXEJdVO%mn_Zea||TOevF~)F`NH}+nkm9`ms(w{p?UAi!m&ZW&0d}H>bgQ8kMJaNG zj)b;hMP$A9%Q++CrE$v#IFG)~`1u<>8Ikkn@`#H?-i>ek==_Ep2)E5AMlJ65KWXOF zE?$4QdVHf37bj~C3@4EUN$4KairvvWO}D5=XpGU--^Ms;=gB@whC(8gp-_mary3;* zsf0xs=ev9DoGNdfoEH1#;_Y$77($asOb2wyBBizsGM-Lr_^w7?BpcV6B58V zgGbc(9e>d;`8W4@vsqSz#*70LhI7v7wK{~@POfX!DnV?X=R71Z{)6B7?f&T>o#UKP ze|;W%;~=0nE;Q4sDkyHgbf?5^x^c|=1VUiH_I_iuc?;v^clG}GHp>6v{}ddiX&RTs z-HB{sdsxY;Tc9BlthF$vvnP3UcY?_H`1r;7u%8@TMM=ybH*=ad=nWb_+AUbOZ}1WOMf@=BW=`WWGc)I6(lBrhs}-M9 z`}oCni4ym=nwD*Sw~U>f0el?UBBeES^;LN{_aUKK)!IK$RiJq$aATDaiO&3m2i_qRR8 zbu393uU{qLc9H>iMzslPP4ADBC22nON4Qzf`iSl1F_s1fhLGU?Q24 zs82sv;n+!-5^F6+)mm$uI68PNq?-(uXs<)=ghf~cN=TIE)}-gNxi6)Z&Be47E|+AY z-9))~dg-zA=xI@gwogbU%Bd4_*v~I3j5|I*;XacKNjBT#y>~8`izicX+0BWJU|6kK z+Z^pp>G5X$uBj*zeWt1Vt!$_KIUC^(GvSRh?#+F6USUd$msa~;W&xDlZ>we>V`#5|XBVZBOfRgcK#Cl^%;4%8BJBk|HEZlk^O; z7c#jyIFK8xo!Dk4_8*i}TApUwPRwb)D7&S-I2T?VmJ!HA5jG#jm#wnCu~~X8A@dMI zRz+;fv$@ZJrC3XAQ56(5?>F>u{BguKz?WifEFJ%K85M`~SAf$KyOm@RGjNmSx^Q-d`YliEUNU1lhaST8o=) z+YjCbV+^`UVumTljH(iJKhWW`JANEPbl}bG#_P`7%zG8B=cs4v9;?opyvX_OwTO8w zSHe!-q%hrLlAg|zQkM@wu$<+U?? zySY!qG@0;{v~1`C07c33Ow8GqT1z6)hV8WV_d6Y&BaZ~{{z!al_*&!JVm5mm;zZF~ z32veGhVBr~6l!TiP_*7934O=-SYr&yM6%&XVzV~bT|1{Nn+e~97TXwwF-UHQ z-Nkk9TW?yDn7LpszN1Sq^0-x1#M*X=TIq3Id$GGvUv}b)(P-7yii@x$T=YY{)_d6p$kdGzS?=n+0RzKnbW^8RA$ z?Y*k6&sPt(Ic@-%aQOOG#vMe&t`ToWDG8WUAmWEemTs zs+Qe(`?2f>En~>rBs68rdzVs6MkBrL-o91QDAFGj4`TQe4h$C)FM-k@!keE%4q9FzTC=}xHn&*d0$->B~yHW15^zz+XUt0G0)~c+82L-t&RF8U@>OB zON=?s7LKE1WM{5dyS>Obj?lz|OnLMvU+tU1*Do)}qb=L7yv0-jIXns;hvBm7b}_6D z{?sAe~&OModpG&TFZhdupS|lW_FG5m6Y5O|M zs8b&b1t};QFu7Iiy<>TQ;ozE>UazqXn4_u~{uUF~pFR8@SJrDGS=sjcd()C^K0i4Q z->Ry3tW|b%-$)XA!h+=2N%|x%x8sL7=VwfOqX-oRp$uD$Zbh}#(NJCX(bC+xA#ffa zkEoC=OTpvca39>i4L6`}1WoIm>g9-b|UEaZ_JdH477cl#n3 zy`xQM`qn8did$4GV-p0?hz~>@FLB^<#K`;MYkZ~n0l%wPriEp(nFJ~QIR?x2i``&V z9o^^~@{a7W7OZ)S704LFGVY1}dFLv~s(R3EEx~*XZdU&Ee3spqvZ5eE#Wv?j=dBjb7Bs zZgcK_rV-ouMzB_Qe=s22Ja#;Hwy_(_nJyR1Ib|}&h^z6VQ!Aj1_Q1VV+8ho2nkAZD zB@(#p!5P9517?KW+&B2XFJ1%)2r(x?5kUk(Y>n6&fA9a>H!Sa8e6oF1RTmqDGJd%s zA>jvM5gacZkDLx=c_W{9K*$NVNTlwfr*O;wia(iKg3D2Wm?@OI0(QWZdBOl@PWg z6TbSd_y_#1Mj@CI6BaoRtJJW)MK)p#DC;gE*&9g=^I;75;lg?p%jIZt2?@rWz;JG1* z7{gFx-0zMtym&Ypy(k-(ea+mu-`_7KJD;CX#vIi8m%r7{?xaa#8!+IqaryDx(Jd}F zC*E)Fw*^KoMlUKTqR7mZGzw_fCRB;yB_9 zH;>K_81R;KgqtK$P@{so<5-YxB>8sQN#>eCY5hbweXa~hb~Lun8wyT-a);}A zGap73RPyL#lM5)T#X#r8zEIZMoM(<$A8w}Y_-Bhj7re{nw$o_5@9af3JM&{E@`t<3 zoJnkPzu7pw!d-_N4Q<)?I#a?f2>=06L8-6=xw(&pyFK7RX>K=J<{`l`M;4@;Ya}K& zrq4@qSh0KbrugFV4aG0_(fypJ93S?UE-ugSFYKdZ#U%pC@`}?=SkApVI)4++&c4m~ zN0M_HZM{S=m+gZE$;Zd5-RZ-h|4i~Kt_fx&66blU1cD%mwGjGjFRrh~Sj(e?Gv1=H zsu(0lZU_;H`}&ex@hxVxOQM)p$mi*7vL`%T2|M$q@O}-8P{i`~5|e#QXQoo%QeEtY zx3o`}{C+g28&s9ueEaqdS&QV7T2UAeP@kV0G^e-doqDw`s)!qso&DP_Z^tp`B_bw* z=O@>nf1cBX^ze!@w3n}pUO}H#xfSEv7ekNsn!EdreG23{5uYX4Zd{xFyh&BRsqar` zfv;cJV?MfZ%-Ow2Qgx6yk(=e#vfwqMZ z5w37ry@Su*yIE^P@-Z%zJ+28sn3af}y<2+%bJX4BIeRG@k$bC!2xT{^*0{OUAc* zuUjMY*XJE@4I&qzTafGYK^$nK^Y_E2emsA9^IaWcSwhCqL2@Ui!~Jc_ zaldEPnsbML{*&FYR$_Z3h|5*iH2ijK^PnBb7_9XV;k+f1*p}g=&+(Y&G5aK5rBE9Kk!YWYdtD^-ys zrYi{y#<;5Dr<3um&AAzkS{YqdN3&mcOkTD7JSXq=vv%fMn3z*mmEGQnzdYOJ_!E|w zIm!5$$(-DbhS9ik)Ohk}@$t(B^Yy8nno?Qc9XRJ)5JAt&R(SKD?UT&;he1`N&+|N= z=#Cb;5&TAd1UWy)qw^r~r}~oek#etdUo|}4lwF?PDAQyi#>A0J9}!2SFz!ErK9;_{ zWx=xC5Q{M0Ez7b*cS{q`MxtL|H(A9{g?2e%L5&RC?x3LxpDe`11ZyqsmVVj>Aqgq5 zo9SY5p_*~BLlR1}mxv-;-$q@;%<9!8O5~&qk}MZ$$H-Ba1qIt@Nd^Qfsrm)h|NTA& zbZ@rHvQ}1ii?tGzmITw~W|g*`jIoz&_#!Xx6@!pTU#66apse3-P%j?a$;DAyqm3pL z_MHL^fZKQK^)~;BRryST1yHfunts|=1+fjLLztY$=9h{ujjwgDccj_orcvLsQmS_i zrH#2F2*gGN5%tFC$MmT`;K#@l_nYPX+_J#ZLBGQg+aR`~CQFsuCJ+SXA}-!G4*Lsk zm~V*fDukE_)5X+XQ|02samh?P*fv*>6D56fC}O!enR<|Ag9Y!qs+w)RyD?rEm&@f8 zDo#*aFMs|D#QxoOUfRaC@o77me*a^aR>P@VC7@ou!swN>`sG%Oq0v@%c7;L!_MLiP zofq2tXG#-kd=ILuvc1Dc5=?}+9C(yKp2g#DsC@0udGt11F9FF|?aP5Ua=V8fO83pJ zpblaTr#%cp(h`qhxV790O&&kA|mG1F~7@z$8}rn;=PvcAFCJL838#4|m|!1$zm znk&=Hay_iy<4hDpF|=`x#jPpbXrsydYfI}Xgyu7Ut>0xQy!p>d^-kK|C|;!d`IKRI zNO<0pcuK;A<+XN@;}tw(MQtvbqp8( z(49HwWRmXBF`RD9K=d^@>-9Vn`+0Im-f8wKvvpSG2M46>*?KJMY@Doo@RBU%8cWzZ zPG*x>mb`oSS^2aq<;nx{@r7Sr|B_eyIP4bA5g2FN#b_uPZJ#54G!4F;XgGF|iLUx^ z@%HI^?gV*Aa_n_Gk3sk4;`orC@~2!$70T%qRu}U?qjA60Xqtwm#2#zV%E4)}JM&%Z z@kO-R58GS&(rSKFpoz@jQ42AbZc`gKV)I6fqjQN@=!?deX#TV3pJYlO5O8R@k@Zvg zjp7IOfF-tN9xs77xN!bc_}+fNPZ-Ve6m;_ofscQZA(&q4s{UTv!&jz78S3lqypSYUAa18Li;??382XnCGefp}pF1+VA? z8i6Vj{q$zrS&KOlBnSeB!7`7H+l`g%r0pwn%gZ&Pq^;{rBvr|yt{uWS;UiL5mhjkX zt(Ch3$xM>@%T*BDPuW-t*H`PcwO>05(!3wGw-sh@P@BNJ?Qjbfr!kO(wL!!R5wUQI zi)F+X_cq#SCzj=Ct9R$3ikus(CDQRoOZi$EeQ)Fs{si3YXOIl-OL~An>_&*)R3IB7 z$fHO8^uO?rDsL8F)oo9fZ`3f)g$N;+XA`mZK7RRf@*gI)#yyu&ho$=zs_WSR%xtN69QWHl9$Srb<+@=n9>~PVk(h9KIe@6N+ZE4OZ zbhnUMu?>kv#5O@3&WZdczLE0%dD~;}`aI(@Z;HE>YC(Mmg;K1`lkJia3E_v>zxUh1 z$IE%#a|#LP%iY~wI81YHq)5{1>#)5F5d?lm?h@t&NqUSi++&Of1QW+-l;rDIYLnlH zgQ$V(rZ%$$nG&P>@z?Qb3_+3uvd&m%suA*7b!nVi+;{6NlsacjE{@i-#du*^PLun0 zKPgM^SQc4fy}oV!@msq%bhx?K7{hKcnsMg2+H#SmMUg>rA;600F{dey&#hoBwEU-_bKkX$#qmme$T* zJ@=j9MFP7n5t|e8CVbfV2FEY=(c32dF#CAC<;YXX!S!V!%a~7M9{ID4LQi@T z7Q}eN{oN#4Fy>xwmFqTzds(Ec(;GsOsxZR zP|G^S&BfczZsVgHgTZ2OVorhxMqjTt{`&qRMS6Z^~_UfKl?j-)2Uvzw#@gs5X+k5O?&xD)EAtb~V$RYf|=u&i| z$jHd!(fGzK?|y&je;M+J29^FPZ?fB_Nw||Fu47ywbnFiE0m}>f?BtNt_~W71%^Ytz zSW~fT)LJDb2b~zn&6Kiz4blyNhpava-U7K^9fzSy$4u7mqU`tyqA=I0vKDUR(|CQ2 zE7JOC1h239@_u0-YORaa<+8L=mBxwAS?}~GxO@FQuCI}u>0FjFZIV-2I!i~L*PEoq zWF~E!o4JDnKD#@q0js}l-Xsavc^si>9z~Qf)~CO+WM?MXd1;ZXS^f@pGXfDrx8vZ& zEh0))HRBY8I1cMK{&Y2dja@_7`TxGvZ2o_iU+Kr#Q_YJIJ&4_lux3E)j~*c*k8*kG zbH4HA!X@5nMzhvu3P*W7kH__}Er#an+omNUL2Og^#UJgy zzIM0z={P7|Mo2avnDaPros%_L4q2{O@dZx|uM+!*4=JUvoa(Z?Pq{SYx=;sea$*(=x*lL z=eN*M*7{X(e>`xVcgc~xU>sC=AN3@Exa7W1OoY{MmZM-qGuC$QRW+yXMez+jjaFn$!R<^6F(xA7 z5Ozcy5$9sOHR?wD+8Z~FjJO>8yWjgA{J;OOU^e}fAZCL|>X0CIr|mZ+^N2Ym_Cr;M zuB-iE2@LeNkIqJ{82tJuyQevY-l1(1B(@*jA!{JW@v!ag#w(#;m&JYLsMptAu?IVX zg#}G1)d}KtIJ^&DqsjGkFVAhpwi~JUL?UfpSG{_Tael~#9PnYf31^wc@NHA)_-30V zH_NuSvLvW7CuKZsW#(4S=7;$N|xBZf_#OQPSZ}ATz z5NZ%VV!F883nqr$)snUw7!C{*04m3@38r~- zu~4>iWvmR!X4#H5g=MU4M?iJoIqRL<@8g%AFv1 zG#!Y|-|80`U;A@L@^Ps%v@WRUfhciD^H%bnqf2K z38N7%1ky!E-Pr57Ki~WtVDlg5`2ST?HK9CD$ao&fVTgUF?=N>-6G86o@(KwDJo@?l z-#&W$A8`A2c>vd5O76-1gihE_gid>L$dU*m-eAO~5pUSMWZc7tI6lVucq;^}isvy% zOvA{q=te>gm7k81&AGgaDUf5*CwB-Eq#IG8s^_2GaNAhkd`36s*;9fshRzt{Zx2Il zM1ma8vK&sx_kqch13k-t@uSNR$hurC35(?Zv9^(28Dl2e#Wc4gQq@`;WHp}7Q^e6h zy`+NNlBE9H^;O?YWP|MZY|Ei1YZZnL-tM!xB__#c_GTU%x|^tqd2DL)U1tgLoN<{O zpCcmBH_H$)7+cH6U15%a<{S_rs1(@>-!Xeo0dVLfslsBAUH&MN1gdAo<;&#_wXKBn za~6T*-}enHA0a>CN8W+4b!EpKcoE|=F0sV;V+*&V&9ThM?X7W)krDl)I$ze~W6Y;k zn;1in>$RAD7o5*y)N0wkP5S)sDpd<*HR-Da!c46{ByqD1VtYgukF;&ZX1hMsN|3hw zT&w1*wR|`k*$6>n9zE=iX6mqhGxmI=16k_>Uv|!kQHs)U zKC6ai^YhQo&)37{8I*F+>`mv#BBALN>v6i>yzp(aCT>HI0aeCpt>xov#7#qzJQ;My z7!03}$0y`l=ZzB~8p)<@ZwB|V^3zW@h!9W;{ngiqvG(W|RS28;BFq9#9qik%;eG?| zgWkAb`g6GX&!%vDHSY_#hqAYKvpp}Gtj{^CZ5M`EF*+wViAR6jFFF3OpYCn8cV+A7 z(_XR&E5ZuLm_;}?N0;0pqwTTzBl);JzBkT;+)3>_KJN&R=4(7iyyeMU!Nh|x2ILiq z{#JEX;LXCrZZ_PDq0J<$B#aMM46+Dfk@Je>4EGAAn8$o0)jc0m)_S->ni=^5S=96k zt~)g&D`T8`X*k|PJ`_I%B;`D(n{1XwvpVu^g!@1-@UtpF`oW#QdaMbieLnFzhUr1 z;#O56h{AWR>7D9HnsKi6oonShBG$V|o+e@RkWgMSgGWPHE(|++! zUS{(V_WgWcQS$wGTvy4?IFl(KM5DWt^aBzc_E(hob(Iez$u|N)>oLAM9cvQ1V#z( zy3v;IPXqV+__nh>nG-=nl6U4b{Xvi7gY_700DC}$zX7)rnivL5+yilAPLHxzy73(B z`+sE?NdYM9*XyR071do_&SQUrpNd8nY&G5HW=TChB3y2>A+ki2$C?2 zGq#~IZIjt3i5JJkh4HjMvk+BCX@Vfh7^s5aBhhxld_8c3*lm)DH3pJ3<@$hBxJ;Uq zWm&Qx?`ti}y>7EwQAM$=&|0i=eNeq7kF}GK#@Ae17|Z2^T*&c0Y}YbImEm%3gl;c< zJz&@_V>r)RX7(=6Be`uZ<`5s_Nb^&yonBDgy%6ChB9!GA8A2VvKs<1x$W#Ex=AGDf ztV-4Po9#gifj;Si*gPjBAE5r$UvzodxX(x4?pGEb^N1D^ImVbL#1&x~w;4B#wvPC| zJ^=ruk2TkK>zhom&25in&tCk9Z~Cj<*anNJD)I8bME0_|Tox^Rri-a^81`d-3{hT~ zDH}nh3RN)e&OpJWx!Y~4V!kb~pck_rP<}% zCWE!}dyf4PmygJWLwn(z2q_1`$$bjSZ_a&J94P{pkGWQ?8M0Dr6I}#n)5gAMe@75u z8b{~n9=$*Q$RCAAkIwJ)4!l&wlMxQNjvOLBTaaLVz%h0jTz1?V_cq^zcYe-S*u3kd z#9|B-LkaH~*C#-3cTJQe|4JN(9}qGww(9fIv2j z9Qb8j+9r0pD^~1RT+Pq!jiSzZ;{3K*OiM7v52w3QEKz!9Tsz`gG@1!5$77+hoIc$2 znhv<4I6#g_Sy5R@)c33t$^pVpeIfq`)9{e&?Fdf|PJg}CsSDFPU*+m$@yP5eWx5oD8`164G$vB2e{{(6iNEE8{ZcCoAC{CMG%CZzK!8Vl4QAmn68CQ0Hpzi8Z^>{R^OWBxz3e7Arj~WLl026&q7arv5k64kBcyr0VDP;j~ANY=6}32UWjk8_OiX?x%4pP21cuh^aUuj_%T{ubLH z$81P2ZRhZz>i(FD6Sv#m^nod4_~=apCKLNFe~E|~JJv18wpi8w#!@%ZT<=6vz^@bF1CQ}J{byo@pb3@kw( zktIlO$Nhf1wQ+0n()iBLnZL62F6Xm)y@qX(AiHTcBndIUuJua>30d|N<5(EM&D9M{ z!de#onpYPSBRN`%*gg?VjnArugKpj-Rv1|iYW*n424jrhCGko36U}^k%fUf+y;eDE z-0!Y%%88`daat_Iwv@!!G+nzcG7T$AXlj4PXswqE-cpgHX|JT4WYr9BZ*7~MGaIjm z<~r=oG0wB*x2zgQ@ZfIyw0lDulQD31kAXSG^gt(xhPlW_5;@=JoR^E`fS+uRig*+q zE9Tq?MO;FaY;dHMQXybBPf$_^|5^z9TG2yHcWNOLQ;0|B9T8J`~{W`gdjdj8IDs7Ft&xUXjFgPL86WI?Z{NXNjAdQyZoiJ9@8j~#&Rqzd z8gvy=={}9vk8P9K@0EfvWc{-K=KH$$`ItLx+BThRx-;k3TTH8S z9#e=$FHrYy3bMs1%W;nY9$?@1Zvv%4z_tugn)dzb&LKXo$u?P^amXg_FKfmL1nMRY>;v>wrTP5K&FXL+krya z4T6c`)oyHq*bcQIn4Vr5MO=*S7^t<0ZPT>oy@A+TJLWCB;!s?Y;x+jg zwoovJaygf#ZKjJ;<21Z561&+$C@6%cv!lIqZloEAxtP-1ym`xG6gXHQn*?$ng`gKl z8*kv~|47XDJ%UVnKYw$B!00FZMdYJo#3OFq`?1|UG;&Eie34&(L!y6?9ZL&wS;mZv zBO@*ueWaI9kgu}&sRlx~1+hJz$0n$i_!=7XVeH7Jksyo#u}!?+lH|+vW}M37&$8JK zVi4Yf#KoxjiMed=G`gQ8qiVUUbwPMb@sKk%aD%9@#vC2R>SAKrJh zIPYp>X$`Ht_e_? z#v}=fVQg!3cC=*fIhagh$MrgACdr)fbV?8clRBl^I5?nNIS2csT((7|LIBe{TVLVs zA9>e=r1jRGNk~i9)sN-nJh;S?y#MkM_$(NqZ=BoiPDn>`c^H0>$T9y(Eb{X5TQhwJsan?3XN}dO+pSP|tM%7wzbw_(V%;{!#&JR}3XyWPdYaf$uHzial z4E@*aM_RWk3W;MuLe=s($O`0R z+RospfyF_8@#Z=lwj<6{9`__6OnIBrqwF@EB*%$vwUFy^Wl>Awm4X9Icp0-U7TrY!!S&J2hHYsJfR0kojz7;RpzXYAG0+TowpccPJH4d zkGmKCl;dD>qcHegq^d@9e)}ZB@of)bSSvZIN;AIxQA56+m>D^2uic+F0mHu|(=@mw z%v6Ncdb}HBh{erV;eNjxF@oZWF&#+-0dIO-d=*>&e=!@0=NHqUoyWWW$oY8!k9;p5 zCGRiyI^X8e^-=Ld9t_|0mht772391H&=M^o4&#=~5#D$y@Fu(;zJtI0Jl@^yurso- zyIu!kJE)J3cJ`PJ{Ow~cyLI$QHzcGN zf!%{U3eun{4KXtL`R&D!%@GVyJRsEl9hV zI7Znvj5&)3#*iD@;-DKVYGGXF%+QyM+d#S#R`1WZTitBdm>W0TJkCXr_w2jkNGb^4 z@Ot@|{JCVt-XRlV;GKm>ujGxpM_=u;zVOjKZnup>{k`{WLIjTS1eR$8M=nHg-23v@ zIPwPXe(wi4Uty2Gh#T^w=w2f?+-{8M==UAjM?v`J@%a7v zaX zw>oYaU)~HOU+{f>Uth_i6U6%lQUy`UAjTMYT-!79m_dI-+!;a=`@?{9K(LbTZZFP8 zaJ#k3NwgORa}1U{F}`fJl?;~qJrGFnd{%{;6A~mO$rGVStsE=z@DQavZ`&l9d7Tj-F_8|ui$ZwFc3jF zYc0~dgE6C!#~&_V?F-+ww|6*ZCRAlbTpbb7Vo6w#2s2*1s`ezdEs!xJ5c1drNqX6y zP{^BUyRc#=Az|K9v3-<2)9s~mwr$4fd!zf%A+fb_y^P7YEQ_|-9M*pIuI|a)T8pd= znn)Ty>9E$hl1d3l$u0PeyxJX~qe`-KkNqUAkat*?yg3F{71VVS-!SKm2-X4P9HST% z_xox87WYjWV=}tW-BP`~T_VPTh_HSohKN9Ti>janf;T_cmp2dYzJcvO5lIWqFX_aM zD+?py(FgPQ_dy%?e)J9k89xVQY;k3+1B>QLI0UY}Hw1mfB_x6h{R85iZ^FmgJje4- z`?M-s!Oq=_>(v;KrI1mIJ@){6WUO)D^18zDSKu2eo~6nIE|BuFK=O9Ye|Yc9?N-4O#6pz>cS&DIxU|CE=F=(t;foaTNFa^ z@#DsqJH!|v#;66tpZYZ%zk$hLEQrwb+PlaYP)+Av=_HZ!4>o_EALXNajgRhiEqV+b z+_yLGn4cA|C`XJhk*wgzhFiCnm$$bJM#i7Z%gtNWC$8Rv<*wX4NXzd3mU2&tQa(LD zyBn8NXyeN{rmyJ=6TzzP#9$t#VBp6w!nl37b4AD)e12gpM3Y-HyWdvTF_t<{OTHk% zO{ zEE;1~9m{5O!qbHH_5R(ZSL;nulN=RW+u&EUH_IHQ&hxW`^xIC}O~@}kdios0@yHnC zO_BxYdALD8j<OLG_{KLwGS}vAI*x-E-8GFKqpi*|=fzx!T2WPZo5Pnc8y|bk zQ~8KO#1#hry8q~#n0_6P|4Ly*jFJ7_yNIMEV^0px8jl{CK16+3`M~mU+avdz8X3Gj zofEEHLL?#{hD1cQAhNg4C>h76x5m*I{OjKRPkP1d_RnTTTD$yYiBg;|m-D#l8(JAj zYa}9#?vRiwbSB4>WZcj3Ny(5jULmZ-x+){M1;?8yzfm7@d?N#&`E(V0&El7Xm=Nf9%q|aOjHf+UweBzN7d|yCg3HEbsrgb>tNFsQR;Kx? z6)LJ~C?wO%lILBWrLvPuU0x$Ad4u0nAA{3jU@UmN&dnQ*Ph3Y^Ro&i;kLLDiKG4a= z*`^nMnK0L)6#WhJ)ZP6~Bc7jc&jE3nnYZs#W*)gBFx(=z$J*vci~#K>3dc8hd;2;k zfBb)hmGAl=tj!dZn#G=BYnp>Q@dBDg`D)_A3NW8CYZlqHtpElKPkpv40CW4v-pSHKq_~=}? z9q+w4Sv5*wMcdvOY0zghhPcd(Ij5&J5n=gkyVur738iBw4&HSCdZT-P|Nk*|LI|Ch zrrG*Pgcb6B=tnV1R*EW6VSv#BynyRn@IBwpO9 zxL!qL2^4{#F{9he7IGh}o06)Bm}@HCHDua;9hgjbef4{c{h0QLvJJiS;_MB^fC0xb z?-0B3(mrEASYBXSZ43|pvNA$#a;Qs6Q?B^UXBxZs<)C=my6r!q7?5>g zW+s6qOI(b^++@wJ?jNYC`9TrWwlN)AgZatTy7prct*x!K3gbPcL{_BY&*}2I{9QAn zGHBiMRpWD$m%KD%G(J_dZ7)obooUW&rXCC!cH3jz@4+P2MK7x0XqXF+6W5jC+Px7G zi?Hk!RZzec2gvnxQ&j8$9nuvPzyT;Ipr{T3K?K>;{vpramE_2pR1vWtVnMYywr9WRz7$k1q zu}+5Vt5q<#KPEZ2>ZVgvTOn`1=HYSykT;PYyQXQ<`%&_$rL}b? zfr0O>*V8^EW|Ns5+d}% zqCoNOHn$MG`b8%kC|B{X$QDWyzZ)O4hmI zwkpR1;{DYJFR6`+#UZiK@@MDcFuA2cxyMSSWaz zM>uKUJJYA+R(hc55-`UKG%h72SfXcOhyRc(Q5QKz2U3(0ZnTgE$%Qx~33-r^7bnB* zCH9wi<1^lRdkMs=cFt;=4<8(eh2zDr(NxyeSz}#~Q0;cZv_X_XhTuK5 z)*aXD(~IHeh0`{N-L+Q5ASGE3a-L^QNOs0?)%%3}>1pRrJa#git=@L#hPO%cxRZRI zaK(3H-U7)i!cjG1Ym}&gQCdD^$}A9&?qI3hN3|8|CMoo^RtR-ksq3I%Jt`8wV)}j` zLhj=17!EHHV~nv0LC7LOE{a|SnRQQdTO#4fQ}5qD zB}o$L&IJ-=tcgwUFCXF>bA}l;Q1uA4;6N}ow~vC8{fKEq1d%NS7ZHKJ z2#jux>elGdU-D1?k;}&%|GhymW;#M~NYAqmg%Xl--^29sI%zh=G%yHhW~0%fq+l^H zH3D%lUOa8%#lejIo6E7E9R_Nm+cw1RkOXM zZN}TXH9v#FMEqV;_J{q}_Or9P@iVWuIwkSq-bkSyRe|ebcwpH~ozP`ZktltrCzTZ{ z%Q;FKjzGb=1OX3a!Z7&s-o7Q&jE7r2AF-|oAqs*RBOw_saSNaG1AO7P_sCGk8rPef z*zMw}H0?#+Bw11ox#iVMWGPsd>II3}FSR9QK)WTe8&1{`x-rFCH`aPomAnyz?re~R z+6ZRMqq$y@%?rcl2yGs<8Zsw|Q1x(e(qy(Io4@;3^w^oXZniVGo0eTzsB_!bBl29H zl|;xQ*=X#hsT^+Bv6~tf*XmfqT_)Qyv&i>D?=w64zL8|DV)li+WIM*~Hu&a#pVR(C za$%p4S31kkOv$~&^TKq4!Q^%vjd5^%{)L*8CPLN62!kL1-sgB8jp`DIm!`~8*&4kYU?HOARbkHE9tFq7%bChpY@jX9BL29iGq4(_7AG9triKFWJTo^^Qn99WHa5)IcUeB3Neq( zFbDN>9#x6+?CU*}L)&JYUmmquj2@j7T)m39+s#gk$kkBP%77B<<%F>=ZNpZvB3fg$zBawAJG%4X)pD*m%a8KYKQ6tAVqN1@RhD(xsb0Or{1BrhEJXWQ+Y8x> zJ3O|R-8GMoE@rokG15Ek1-H2zN*;xW#1Ke45+sS0d7epTV*hh6#)AaWePTYt7=xT= zZr@^d0^R3PjB%bYXXJX-Q>*%&RaNCYC#I0@a8p6e$Daoya}(blkJ-7`NyO65MZGKQ zT;1&wtvLp#nzYcWs?HwI^L*A1p+P9y1A4+&DKn_GRwH#msh^!vu>g=_VBPTP+Y zxAzCGSGUpd@)aeo2iI53q(ZI4u|ZJ!I1bD)Mg-}-@5XTYJ=CyVAgeGqWW@A^f|yGZ zhf;e%LrRUJ306=AT?v5kMHmpP%Z@gdOy=Yc%8dWDAYTMlAdMgTn|K^Zh=fSE9F4{| zF#dA?^gi`r+u>#%2D01NE~b3>%DFBgq2-=B=jtZ4y+0{j#xVOLX|gV+t9|cdZak&K z?14sN25xD@;I`cVWZNY26IoH!s2q0Z;l!{C$s?f=5+w_@gg-T2|54Jm9~ophlVg!U z;C|pd|AexV2lDM(lYDTX?KS;Ws=1xB)Z^t;P;G6^X+~4YeMRgfD-@wSDb3_%g7@a3CixVZUQFGfk0=c|}FmSi^OU%X#oA^B@C{^?b z0u4d@9zzrhv5ebd30ccFWow$|ej9Yz zq8e__=#i+@YC8O$BVIbD?Z|~~H|iv1G&yGPn6kQuZT5C!8@p2q-oHmVy)09r!{Q5% zg#ywKOA zy5X>W-1+(EW&SM5Q7FiuB&wsAC0|tYilnuY#?z;Ts%qZWK(aPQh#R{qta@3pgBUw+ zbHKgaZrPhI4q90qXXMP$WqI{#`(``m-n6~SV9bp8gl`|kSD#Oas)&eEw9_FI*cS`) z(ns4;8wN(o1g&?eqM(3o12791Sl~;|W6~CQK3qqN@G@O(8e^82F9a@5P+V#a9(^c2 z9Pfv>ppN@ty}R>jOUliQBFX7ovxGF+hg6!|>Q{`K$VLi9-|c}25(Z!5O&>pPWFSW# zK{f~BuscR6G_jw;%G-}$*D@j5lNckz#f0`YkM#Kb#86f16}JQ3RFPGu-Pw2sV)vM6 zT#X}mT?9o!WD!`jJ`{@D_<5(xz$F}$>`F7J<9NFZsOwHOqA!|Pz%??+8mvY`x~Bi4;TEitFnCD=_!c7{m!r+HR63{dADuhf&uA& zun*mGum$iJga~_Ayc7VcuBs7Ze*vhz)c4}q$CTBL6V2xlA{Qs37rC-zm|ro5g-DDm zDtW^==A+>)owvkY3U_y@Hl0va?QnEEc`DKN91qfTUX_!imCJ?Gnp5TT`n>ZQNq8Bx z)}0UDKLnQTMdLRPr z2!uI#JRc9+)^ecz$`Ix1{ryM&dP!kouQ^+U-BqEe=5{c%N^PW`76;mJJP!6_YR==U zt9?0Ul8H=0YtkAnf%9$WyS^fJKlt*@AYnbYUaf>!R*du7{KEDXO~a5(?}9 zEc6#Jk$Q)Bk40oa52oSRXe>m`Lj-Y#gCMdZHiQ%78@F)#?%&8i9NX!{#zZc0&68qVqR1HB6 zlEgDmI3AVcfkg~!E&hI(lls1q=W!%~Th{V=oo~?60Vpe zjG^aL3IngNeZu<=WrK_R!Ay18;ahS{ND@qvJXKvkKE8Q%yUDWeTyNsi!}6O#4HWN_ z%ScOk!M}5=3J-_UXlL1Z27m2&8wNAP_A}BIYZE7GnJ9 zaK)Gplo4-=uk&;H1bmIq#yzUAs}n^mfi%5j5lf?|V9mL5DM5IbCHqJqcog`h6Jnbt zvn8F>p-JnS@M4Ql*FedlR#XCcNMj&m45$_Z|5nY z#S1&R-B8ir45(@slYEEKi^_?dlyQi=ZrdC5bnz8EWu{A**Xx0do8iQpk2)HWUA9U! zb2NGd10sgV{ykp|5Nfgt3aV8)2nw)k??XPlZZe&d0}xg&0tYc&VvKOXiWpz<>lX&^6iu<%pVnWtDA8QrH4mVwNznc=pg89f8$j2&4SP06B zgwA{3+nU;yVX%a@qV{92{bJe)#MmTB@1|w9#5P_$T`WZ~Y?Hm)?e?R*)9t6IP7N3um&p#OU2$@Wtro|JI<;ED+11W#M=Ta#SKoNYg&ZYPxm% z&Q9Dm_8(-kdm#3o2+W*aCGlNnOo(xgkqfaqcXlgKru{c0wYa`6q8@N<`^t;w=7nWRCWcSp zH+tDL%F*iy{`QLoKQGpkU&<2z#Z%Wc3n(aA10ztxIHtTMCL_FL89Q>V;I!#NAjk`g z2zlLJjz(Yb%l%08mE}{|RVmBe`s~@GycjRJJH9M~Fr}ySL(JB>=G2{7%}rU)`m?tq zB-_5D5Qxa~w!a!Ti55)-TAhmz{31?mG-5d=8bo z633>`9HI5-CXdHM>}RJ3j$@t@eL@tZ)^VCTDHPdyO`J{5SoOTBw07~daIF1a%h}l( zRNRFk3Ni|1Ta(bIzyF6L^PgfZcGU zkNa#1jl`S9|NAmAj*uC1QEOx68e@!TosrQb*3eW=u0|T>O zU>pTFW8<2kIKqN(#BS5{Er+0mm`2P;BjX3jhsW3b8cAfQwIR#;`OT*-k6y{`PAuB3 z=`4{uX*BJ%v*nq3S3|;bVO>=SiD@!bl}5M)$1#{@EvjsD%!Ju#)-pws9Nh=ZCY=9x z;zz$rx7#&4GRzs=Jyk-M-T7E?w-88PwXlvN`1b7~+2n?B=jd*RK;{*W)=?Ut6u3Wp zq*%vgm$dd^ppNI|`gt)>>NB&WYJV zVJ!pmNW!pf#p4s|iO*XOirA&33+@wo7+s=e`U@`nIn5*RxYkY&?|=m3q*!P z0dL%C(i`^vr&$z_TZO$Z__SSQ$i?$pQnhG%VF?mhU4G#^ zd`dgt-L>ysdf)F<$cFiTu6SW2v#q7`JjYsp9$C;$w2Mt9I@+9`w#Ukoad##kNMbxj zx3#K`;%0kn(sTaQthK6x+tq%LF$V3W*8|CuCRNoPR6U*_wC?^~t_f3i?UGjl6qlDU zM&6J}%XvDBRiW2^MoNLp{ zcG=$N!fshrk=(u^N%!1Lc^*eMmrGv~GhPN)M+9M8VKt(So4MM>Tz!dO@B}Czytp+Z zDj|wS9g1U#IR~InanKCVcx>rsNAmmL-@%G8;&_;i!xFwcz1@zZ%g^}0%V&JN`m}x3 zpQlQys_ggsl18K@kVxfQ%;%b<(d5=H-|l;VYgm@^x7Sd=)pvZlWV%R}OaeFB4eCBd z)Cg`tqQmrnxY+G8iL@#nlH?(_)dmde>+n->Gy)&#@o7#%asgF~wN50=qvM4Wudi0s zAQq&pd6P7Ige*bWC9#>cNpj~{m+wWx{eGhN4sZKo!3dOEFVw49rPr#uR}LOi(7e;J zd-GR(VvOPa?vHKoctEWcQEOCAlz2N(_8+#{G`IJ6qmea(9FNU0L*crG;#EPg4y`|2 zRbGeR|6RL)KpgFg+7XfiYEZNeC_@D!B?H6o%BQWOo29uNB&HDgUW3n!BmmT`3Z zbN=P}RB?AF3>Y3oJ*sLX5{ax{-BwA$y`Ht&Ykfyx?^K^sz3>$!cqhT*{)ER}+S?4K zzTdxJgOD5CkVJ1fn@Cu11c$Zygl|(eu~x7K6(2$iI^9IZc_PS#wUB{8^oRXyI$WAGPIPo!-eMbtBGQY8S|Ym-#-qRsV4)XKvW8bv>zC~j@;GQ+4r9b2 ztcc7Av}q6_i->4?kmTi-&Iq}@_R#d!Vt#;R4FpADrEw6^%v(JQG)0tphn446H( zRd>7D>}E4f_{JDnOHt|tYJ=kC>q+zT6AE#Dnv<&+W{xpnW|C=617N*bp7)CfFTBSvn$)=?b#$1YQ;d z@yZ&<+wr5~FZt-v;}IdNebc7kRfi2BM2WQ zaR$fH=$>np`^Lk);)Nj@({`HZnzZ#;?miDM{0wG-ukU61CFpp_7@ApQkU+>Lucp-{ zf!LiBd4cc^;y`QgFcRcjofPTON@CB65aT1{iR z6*qT}`_1Dq=D8=A{%+H{u&SyChcc@FH0Qb$b;9#`XllW-Rv9Kl6|ct&Ttnj$q&erO zPuE_gZt!XkXm{f6l>6uaW4NHl@m~(czX@q2E z8LuqU=>9|y;atLsF~oFftZ@4o|Gy6^pCDbqc@-IKtykO>CsJv*Sf0&gC{fOvL?qIL zeA(X7`?77@k)m0M6-V``$&*y zZueDOTwGjC4|dhsvG%9q5s9`gE~V7C+qT;CGRZMX7Q{-DS-tA))g{@yur~;XK~18H z(LFppLRpSpM8W9CFXZ%?bJRc4xYc6}X79{7r$3$>UiRx%JdeOMp;oX4-V`M2-EB3B zqnH%WWFLyKu>a#x#RY{rTxV|r(*j_O$cAD2m_VK!)<#x@74iBOEaMU!({+U=L`xX? zi1?g0;p^=K`+XW-LJm#U-KU*n{sgjwR5FX%RZo|<8~{9u|dpK?B1 zuGd=gqiv4AKE`kl26uc!e|+SJyKOgw?mRW7NS-+l)*}ZxkYh4bB8lxm1`G+phvWUQ zKZY+0veNl`7lpVEcVXb6aTVq^!BR4i~SO{mAMHYqKs(ITnnI z_lsVaw{J`9gR;rQC1^RIp-h9?No}TNPmHAoJ$qsd+-#Qe6|=G8by(l{X&IIb)9`|BFVsyn-| z*1)R4Sn!;b7OQ0>j(I!oA%Pwt1PrOhLT|B2}3`GG0w*4 zF`W$i)Apm=iU_jJNvAmv1=nxyVkP%v;!L|uUT=_mG2zAAWRW#t=PGi2&*4CL4Vzk5 zHWkQY0bFzyTq+2B5>H0ZM8x!jh?f>V@c82Ke$@}UP$kVCN)=h&S6)1+XL4j|WEWW% zQJl5}7qh_<;+BC3V!0dw@#1WmFjLWfKfw=gNKw4>pbZmR4 z_p*-UNInLM1;V1rX3eOf(a45Wv?W8#hK3j}&oPu2e{8n7z+YUB{W!Tc)QSpa8@|~c z+4=6%sbTd%EPRF$iyO}t#bY1XuTxNpw;4iRSiW=y=y{xi0|N|TR9@P4#x*XvGQRc> zL3#DJc@JEky@F#5V*KBHWbySzo3$HWhS=H~_Lj1?nSFIaS_rvI!jm&8kEpWu9<+63 zBa`0ag|QZb=_)~X#t0-x?8k0h+wL7b=MxDs-(EM#WCdf^;! zDEnbT5a)+&a*_kV44%Ib%G<=vZp~C>4g3VLA1_}>x*HF;W^5MxaJ4^$S)Ij$W9=Cw zZErnA84X6rZP(gz#Mxb1BS)HX#&_=r+v$;N8kY;lq{UmVt(dIx#kL%W%WWe0#C0=9 zz2ja<*{rC=vW$j;TP6PbPp)U#F5BF)L0J9u-j~6gmlMQV|CED%_fc;*<0&ph=R|p* z+5@k!0aHp4X9=wqwH`cS5)$R2rFl{h+S8a&vpn_NTIA)!stJBXSRru%nkE3UvMj*> zq8iv)Fd6WP&9~v#57D=eX++Wz)vAnyRu3oHxiA`AyMt2=!|8M!F0aV*7jZluj0Zk< zuhdu9>p(-Zsa31Q{AxO0$0azTwdl20r60Ce+ddM4sM@&MJ`vh>Ac>zPMH`MyBzv_rFV&AzP+HNvFHYKAtadYwJZhP~>&%tqIl%Ib6 z^}lLNl5dyS@|4wD`ksHbWy;2E4c&v$`VVb{u64#?u&ZbsUq%chIY~Rw)Wm_ zO)~A0b{AYSR$6O%?-}a8qmif0BzD6id1Gc67%Ev@5#M&=c1yBZkHhr0Vx42?>XV-N0|Zx@sKQnuDA%t6bB_529pKNSYX^d zn%UEN>I1IT77pRcutM}j2sC&D#m)c(0^XfK_)foq#}D3@ujJ{i6$^(h{ozB+7)v5& zLuRt#2nc9|;K zqTT*TyJao=gIC+&K*IY*H~dXPvc@^N-B`UhcVf4YM{LLaez(;uFtCX2iy2#Fh*1~& z?IZ-qjXBBwvCCsM;sNNC^~?t(ZAB03N zVh=1rR6iqH3&O%YvpY=cdTNl3%fTLlg-8Qd(Pg= zhl{Zv$cAr>mkAZwUBKgq$!W8dR#>Vje*IbIp7GwtTQxX2B1_9Te9VFdz^q z0BazC1%N=w_HS#CADSOu-s7R=P9PZZ@S!S0y^^aKmXYYab7~U94!iT+Joaawkj&NE z_fpCY#?Tt?swI=wjv4*gpc~y_wq$iQHS8uK888g}eKy~gmnO#$IOcsv!t-fZk&s~< z1lAgGdrYJU27;_g)TAf!xTtBtRfw z0k;u=U?)Jklb80x^W%rMZ{Mj;A2Eb7rbi89PpaH$QMsV?yH`iGl$s81LmRHld9mEH zZQJDa6|eoh!~C|5p-&wh9?W0IpjOxG;5so}Pu8fPd3a1>-ilELlgFd-?Vpp71n*Ua zdq2-TCgPu&2U(w9nuO0aMb2k}h1G~rx8vc{_K4=doI0=2_kAY>+hwdQC(5yfUc-N@ zN*ixd)y}-!T3eh>#pQ6ha8ZS0dvb(nY|YkIC$_fc@_iAroon_TFX!_W*-RK^o5b$t z7=x-YZXU?l61#c7;TT9h1CO;59<8k)S0Y06fxmPC_sOK)^dq zT-EyF`Smw{_v8BP&%U~Q$Vd_0^#ud|PtFAxY} zto1m_cJs7-)s6AfygxP>wy}P@@l+4{cL@oOIlq4UCZAbrzB9X<3Dw@a3e7Z(Vo+cy zH#fsr?+eaaQO6-kJFYN1T^a_(s-=wcr=1~OpLW9ejHVbPxY!Vn z+v2P7UtkD3d`dtV^01)-9hF|90d433h2N0(_zk__r9(_#aN4+f17!jjWkH~!O95dt zoZ|YS_w8eP@c53`iKU0CCTf57LPCy<;3OHAyBArO$Qvy7{WIV7&GANg`}Xq2vMj}P z+ZaDzaB!fkJt`asRIT#kC+PS<*7XP(QKCs&VhC1#9LCwi#W{v3;~Q?b2MK~T#u&jz z(t(wYj9)}&lXXs#H|X!Xg4{koJGZoLcPE`BUE};gcXL)HXwYdx?2os}_1&}cajd1* z0m;c`s;aE7?rA~g`Rk_1>T9Eb{um(iH4HyUlB80$!2X*~$_Ulvg@L|6ZTp?*K!{y_Ab`=%Y5Oo&}4O+~& zzJOOB0ER$$zkZ6C$+!%)&J-x+;Q`%`I7WqYbW+1*&BwW^}EHB>H#W}=^U zGtPNnT^D7tpfy6qMTcbO8}tu**_&RPwKg}n?hwomFO7jJ#C{UH?WG5EHi?3fJx)eo zTib26wO+>shq%KMUo6jGv=hMLEJbT8e_SKECJ7GkVz5Q-4 zjcshFz=FI;mAbiD;>97Vyf6@IA$+);7tD6I?SqBWmaV0rx!>3tw9B-W*xEJXe&gn# zQQ3Qc@m-Uk&3S2e2yQO6-{bP)GW?!9(YEnjZ}m+{JLd}y#MxNPdSBYUo#1jbgi?ml zj_S}VJMSblX&?N>GX3bl=eKDrFNlGl2?Zdd%K#7`uj~Gfui)`{w?;@G?+jY)stQXC zDBBNb())48khxF^i{Y3w4jlKdZaG6+Gc#T1W{>*1_nytgj%~Qtacp{L48x$-W8EbX zS+h~5^>BI|^FR{YX?sRF;kK!vDfv2#of(ojDb^qfvcr_rifa1W5g)jAFIiAXf@5Zw zN4@tUv(}QTXUB@o#L?+wM1xdW%8WJVIq8i`Z;Zq;=j#Q;wn_Fr$FTo;VSC;C>4Mq} zEDYP*r5HQm)*SY$O4T)wP$*>n+U`)~5HngdwP=02iNc}2UauYyi;Wc+s)hw(myy#=0>#emwJ~DX0Ajv=)E2J_*ti=NvYFpXF*_b499nCR z3a_s`Y!}Bd8uJknBxJ%d@a8-B%{Hnk|7gNmjN#0t;Jm-z0%EQ;+BPrC;A3svIV`dub)?OA;PJ?%caLK|4=q!^IG@y}$Qy&KSm=H^BCjl+9BexVfMT2_dcoehR~Z{h(kCZ4Y8l9x8-*dGq%(Iz;Tz<*#e2U zIBaA0eqbqURjqurJ7=ItT)3Q&zFfQBcSg)+ni};qSJSdAH|9NS7xc3<+5oqYic}A=*FJdS|{2)P#EOw;{Mb12JCycUr_e z2mpZsngBFTz#Lt4pN^%j%Mno+&{<*sTRp=xNbCL1f9Y1rK* zY@2DsjWOGY?e|s4Id`(@ZkId_EIv*ON2PQQ7#wOi=w6|ep_za4-7|=TAc$ew zUJ=NJKp>PNT*Y@>zH>jzOM`5NVK)l#-Fqh%c!3DS{Z7rK1p<}0-#8LmdxviNS2UX& zWMCoysxu0Ed~KirRm2#deg!q@Q32MGs>AR!Njc>)<7rj0F&`dl zhzqvHAgin~TPxnG7+*Jj-Fq-GCy@cisG=a=E{JK)&34)y+j$s+Vsq2}z=WE3BaOwLIv9J#D&@x}Ng^FYCs`0WqyKp|V#$!39U&=i$7Yhdm zqt4@yZ>8I4LcWb*`QS0Q zxp@{sDDIxJ$%eq!I;<$Hbu+%D_FPF=QodplJVfKnXe&w&jwp=`;Z6|J2RZD7( zP5Iclz2P~#NeWjvj^ilk)8*ubU~cFm$R-wb2%&Vg&KU_)C4p>|1r-h+jvWBy&U8|^CS(dj~hh+1Wf>6rVLLTdQvXzgYH`CQP ze;HoQ4-Hp`KXJQB=+3m(@;VRZpB70vLA;^S{g5$+M@+)1;_Ddt!DB6N2?=D4z4xY0gzQgfaugE0{#iQ4TuPJlN4%6rDc zZ?T%Ve*c7+{vbzp0Yh|@8BhpzK9Y@chU-2~FRerfgjkOmEvY&naCLPdQ3Z9V+R>v2 zIk|Tk_8pzmWsHOIK)(N`Uw`kIjIT5})X9M{|1ha!t$W~Ud;NGnW>1%s$gdEKCOA8$ zZD1Ass5bKIrGfQ6>2h;$i&s_C{tw85!^IK$9f6n)#sg)HZs}w1hMq~;461VZ+UMV_ z>%1^!hU-IB)fF1;HQraWB6{!AFNK4hZ!&SYCuJKltIOS)=2^&>oEl_L80@8 zUOw=bK0jz3*%!`-Mc9G}XaWQ*fN*!>&A-N9{NS#KS~bZ*SeT~N!Z;diu94g19#yHY#k3&!_SwOBVF? zO+p~(7&OPhvFVtTE{WtuIucDGueIW&4;*2c#JEf99GS%JE3z!~Q$hksGYP8X#(LH+ z&dw|g+zp!Tt)bc8d;0s{_r0Ua1Q!JfMwMU;yJ2pENqgbV?l~l3NVG@K$skPIL(yGp zZT%@f5w6y9wlEg!_-0*N}l@-K1}1u&_qll0#F3JjRzwD z{H&kdnXXY`u-FW;EJk8;3FIM+jRA%R(@Sfl3l*gtMfu1l1Chd^#{r+X4e1%{H_fUSQ`cbPf z#xX7j)nmn2CNFs4Fh*#y5pyT8Y!mu`Y~+}qg&^7MqmVnZRA`Q?WTV9>yV)FbN0REf z2|5$uIc*;o#W%#u$4m~qlrF7u zTa$fpGA~YJ1uIVvQ3R2#HNJM@ri53Gy#(s1!1`z(#^Au}Wn34B{un3%ZU7V@05tKU zGpzSvGy;svT@Yk^nDFVe4(kHRcsuTEcc*sNtcxuBQL1R|a=HBE!R&q2jo~25ozgzD z;W!lYPfxwStK|vTAKJqM{S&HI%;RB_&W1?76gNgcOtR5!j4>R_Ht0apYP=oLzuFC> zvZw?>w(&_eX{$cDE ztr6kSOCU-hh>j(I(Oh)8>jAD|tOtw_Z645rDrzDrK|Ph^>=|+IYf9g9QF^~RWperbrjJ`V=Ej`X8n@TY#W^9H*&~ypFvdHw9y@Xz ziEZ)@({eFMse-^Cdd_EH{=Gz-A;8lYx<)Z~`A7eNixly=B{;P7e?i_PK)*H`);zzc zHM{jv(3&6~uFh~BL^?6Hh%xMhU<4opC?L=fmRk>UeXAsiL=s|aNG!26A-%I-hJoyA z(wbrac&yQ|@kUcH#>XQ0{%3!f+bm@}5B>X}RjE&x1pbPS*VpbK-Sj>E79YLnc0z0q z(_|NYZB6%3 zo4wZSMGr~}vQjm)X0+6a^-0^aECZyfQKy6AY&Ay~)Yod^L`l}P2<`F(c^XuAkngjT zjg}lHnp-o5xvK8=dvAN&`Q$*)nIu$I8OFdAbKZ2DLH~lp)>$;6`d8YEbzGz%ymz;C zp{f6`02&P(c|uyjImw_4W?XJYpN&)LHA-NEZDwgg{iXLg1LZ2XYA3C-Ok@B%7et{S*Z2akS7F z_1TS?47wuG2f^53vAu%YrS+waOKUamp_Qttq1DwDof4b%(&@SD-o6zJL)nM{iIf*- zLD0}*yC@#ROrC4hoiWzJ{oZYV-H&(Z=5{+K47=6H)waduG&oGCCMvBlaz>ej%2x~J zgiU?!eB9q?f;m}M=!74h{4mYrtvwt9ZU6#A5UySRb^M0&79EpA(-NxNj}?xW?>qq?29gBvJ398JvtC?Fcg!c_$wAlZXvdI zQ25AQQDrzjVmc81x+<&cwu$Z8s%l6uE(p_Z|Z;_7PF``NZ?jpeo0P<9vv79G#~%;kb0D#1{W9K9}j!m@vYz9&v7hc7jI{|)kfwkLt_4qg3 zZunwlKzR0rrJr9$(2pFh;0mmGiL)~eve;LtxAE~8AN++e0xPTx$Au%%P~Z)LfB^&` zF6}yX*D4Dt5Z&fsBAFJ9jt^}lhDievVpS$Mvxg9d1YcajGA`jz?TPiXh{@Xk;T3V+CA{x4}@?r={AQ;0m%GTO`vvk{&LtrsYu(C5<-7V(5x<->k3<))u zLdm4(zIXSpGcip#eJCM68eFgVE7?dgH?wmyw3~5yH}E;u8WXQ++q%n!A9(MLdF!23 zLEUk>c%4)C=5_-PNkiH5&DtCP$Nz3ouyzaoej(I}QhBW(h8ZqF{y1}7r}FdgJQcn^ zKiz_Y3(+D6auAj^!HHm)1xf+|@)@nuy4ICwfDya>#QYUjdaM=qYlPE@q_!(1_hs9R ztjnVMvhP)qgk2qvgUXX96_VK5TJDPFi9UBQ2EE7V^y5vEPW2c+*W(lfosdygt;#l- zGf%^I4M`!~CM0j9{EXN}<7l@rRx*;fk0d0-tvSc|^SD1oJ8auFp*+U@9@Iu4fdoSh z5*WwC=?liXA>+ka8^<}*U80GdU&uvA$~ zxFzYg1Ciq9TsKZiN$B3=@G=GzJ}ev8-4VN`4eKh+?XCXg#TnHS9Ns`FW8bS64iX&N zE7vE+hbd$*W-k(gIT>phTaqPoH)~ZL6Y4Xz=?x!pU?K zQ;x&5?K;oGSP#5zF3z}C{ZMxt!E&0hoiWbKYDvL(T+YZ~qz1>T%M`?Dl!kSExwXj5 z^W*!_Y~L?tFOYMsl1yetnX%uk7i#(Z{50G+5b9l#rI0|9K=Py;YnF*$^>>D61EcGVIZ)q6>gdYfnTy7$_dM9$=Ul4A3g+YmJ#I3vMh0vxth%?F6OR{qry|0 z^H13|fXKji54N**cjot|oSbARAO&FtUtyQP03c8V?=_aA!M(_I0 z4{kfg+s9xt@YkvcU!OEtVWUUG%i6Jw zo*$305ftKt z`7PooZ+jzH_d(E}j`?{o4TqRt78;^&)`t}qPztZ%8iWv7ZoSj*X9O^^vl|E|!Od=h zx=6ie>=3iX=GmpKL19P7$q)wzelYvV7&n+c;c*o~xq4Oc(lG1}yCoZ8xI*oT?UnGU z$Ywz>VN4ez-$kn^vf0MvczNDzXGi5i2I0ZJa9Uq|?UAvO zlP#_gV+zK2xgXrmEMM!uSwog-6gsUf_!x?&aTEfuvkd_VXYM-F_0lS!st$tR!8AU} zd$&kl)heN{36T$5Ym~~%x)2GA(ac3_84^1N*mrZ4u%Tcnlcy&f5*T9)^7jMRgVfLS zO0C+wZA1~q?Hg83qPwM5|N0@UB=+OgoZ&cD*^UQnpMe5>jPb zE4XcBM>fgKQ@t)i5w45O+3QrowPwbv>e!%a2-ekWOTS1~y7e>Hb|!c0Qj!6oAbFp) zwOU&fD)j{t-N>{Xa>$@q2Ularv4iX-m)PmO){gcI9n~%4L1L>dVe*NGh+<|yxIYoD zmG?~&Ft=}76PLvb&C*6v%y77x7{e#RBJ>dtS6{_W%p4j31Bl_G2X?KnjiLecl{y@A z`jb1vcJ>d6u{*@FP(tr@uk|_G9}UO*_hTsYDuiN%yhuF@iY_>hB2FoY)O3{~uIZa8zoN{Qb z>ew!|R*Im|2yp(QEq^hC@agDQg_^erp#MIvFs_9gzG3C(oTo}U0@27ZW(8JrW!FS@ zi2y=q%xMZhwsCl%;}-{GVK+pdr?H-EEwcF1w#y@V5lUGt<2+8MUiaRYI}6;EZJSF@@tE@)ZF|hw@O;9rzrNlAub;w9l(N)a zt@ZV#pyj;dbXs;kpm((1m)Flns9-7L*p4l#O6PoCd$;(^cF-(IYb>TCgXm>hbgvJW zOVGRdc7w4|6s%6FYTOBPbGy&kt#P}}*-ebmRea$Y%W;H1sTnMjZ$;WwGdoexM8Zo$ zVdbx$pFomC53wv3jSwH_zMo3ga?z$S25s!a-q#Tc3K{}nG!Tda2p65+TB{`s#zA)1 zipvu*86LgL3n#|9ky1|GsyJ;;vaGQT(V`nxb_dPoG$GHcaxyLFQ8wy7prf?qAZOqI zzMs91`d!O@j2w(#Y?I_8+U`25Vpw*AWHvFz81{dXMtoq{Klu?4#1tOA?)6wi&nb{h z8H+>Jq7#zP&o%>boygo+5zWdy;dr^i_?r6s1mzK;xXr1mT(qj0*^=SC4ZFpvN;~VJ zA&*}@Q_GMi?ip+ZsaI6fo|;-a$AoNZGh_QU$FME;y4erS!)~`1e%Dl9G$fMq(3&D~ z@wPS-*j@%$&>+0?Ea*Pq5d;}PvS4Y#3OJpQ+Zz|Qm>r9A zZixM$h~2UsC@~#Yf)8ZhVObC*^uUzTG`kUv38gs3nFjVimb&CYfR^iu>Vu*&sIEIhgR?5fbz@c{PF$T?eV`1UQls%gGR8_dG%p-KCNn{OTmV`sI zHn@N8h}~eVD&wCbnvlGa7&AlN!t8IpbFD%yB;g1QW0aRpyfsLAhjE4Lz~Z?FVOQow z;9~B0BdL0Z*4pqg4sFPQK3^y2=UlT&*}4^sw!xU`df)ja&U4#05+**pd@vZY)<&`? zBpRZd=6J1m?rbYh(39wH90RuEEN(!!-M!T-df)y8u5^Ul@X{eYo!Na4X~IFo^m{VK z7(GG2=v){OLi5Ot%Akz`Eps7%Yc?z-@Su!jM5<0u5Z^w5)Q~REOO4}Zg&)nAkW+}5!OL*CUKs= znGKnLg{og6k0#<*NVPRa&_Zu=98*i&0*}YeZr@m6krUa8#;;@2cxCS-@9GQOxn5g1 zLySslKe)_X zOta$IHTeu~0*8nYT^oV`K^CFeT?Sz4{XEmPL4&K1g;2i=LXgJqfCD)MRbbyU##l-i ztZL0pVtuW(HpJA=&R%s5hf>&gd{mAo?r3d%f9U6HXV*7%glOv z>$698>TOd3;}6_dH;KklMV4psl!WI8fd!}SZAvn|ywFK>Kg}SveUikyg&bqlS_HBY z+e`*Kwd&7!^4!{U7;>_;kB!4w7t`Di(}M>uH2)&+GQrY3@*|OW|!^>O4ZuewO4N3C2=zH&`hlerDcjxQr zPANu*^;iV4?awiWzWbg0K-oB8&3A1BjxAW_VT`@@8UjFjDl9F1F#;IYVB zb0oGw8pinB#Sq($L>ELQaWNY)4Z7saV-jPqwAMcEHZu0ATK4<>eq5%kE4jh$x@viv z4C{r|$nkVMuAC;uY_P}jX%jXLVNpr#Y!)27=^Nd%Sjn;3E~4+On~S&PrfqxX^1Anq zD%tlPy*r>CFdAi_`Kp0pClVfi5^gu{1K>*AWzlFDC$DFc7VJ&X;*CE%4t4|@AP@kA zn>Wcj{g=<1K`&vOBm@pAwC(MSg!Zf}gkm~G-+N`CX~mFnl<5lnRjt8UpXbi2S`MX< zWad@%S_+pj9PxJj;~IZmb`xt6?P4&0sw%{`KYr1ocUCAtH+PQS?5-PYGoUj`N}}f* zV=N@`(xLu1T#jvgU8u5~Z1!7%Bgpcqw+mya&nb+P1l?xu^tQGczOa`kcUX zvmo>2H+fOeJd{uDTopWb*L2RF1y5Mv<2$T}Fw>zl`*&~~5265|e%wNS&ysf?2>|MEc zYnNCS&AJN2W{=I79!pG{8@nB1n@w!rY;&{0Q=ib+LRiqS>aedr||}rN}z55VY|NQ86w=fC!mlXK;e)qF;B72(W~3B+TQO zGa)3tAof#6s5^ZpWNl6Ou$1L=k^|WloppD9zAUvn31VwiEDE&kKq;vR2m0;x`K#UR zT?|$PNq@-ZHe@qK9%RlPfgBs>=13UkJdT3}iOXYi{ZO{G=a>^#D9N1HWD0s7I?NGd zBEbEaU285-kg{8JT$aw`fR>G<4WD%#Q$Gx$+t(Fpy-W+n*+g>P=9{H>(wQU z!$C%ct>k5X&g3kdWo!=<2eEPwE1oogL4e5AYPobO;H^@h%gVFgyIszY3tw^_aH*mT zvK%MI`P_t`wo=Nj7EDyaYP7X>r49RIIqu6(KXk{k$QTb;mimh2(~OVnE7tQw5=4kG z=0G4w7;Dv9_TxzcgWK)fu>wtNR-WDcZj5ESE(FQPSOamnpU-)~VKBb$FEl|nLRr+) zw4Dt}41xQQ>K+OQn!73)hAPwJi`s?#^+9W|&Kg7Qs*<9Kf?_c<_C9YcUs*mWqK~3A zgmE2LhfcHXW|Mq;>{ts!jkEiHzv9TI`vto50MAH9M~(Fg9sitvtto!;a5Yr;P!aTm zOYS3iD)|7V$A57JC2*cQ#uvnGY~NTC+#PhEMtePwHH68wZGjLsm4E3}*J#0Pkc@=8 z-7LGor|p%Mu4uBd2!GCMU6+(Qt+yHdGYilA+H>a z5HG!nvue2~u|H(U@Oa>ar!a;!thJgXr$kTN$k!kX0|^$SthGpxVCqf|9aRPdiD|d7 z3~3}yvLS(>noWYdyu8@jstyNBuiU;I_Lr}}rthAOl&86*WKVNAFs=g@PkP_)$3WiR z!S!xg#@J%oQ7eUkTXNfwWM@LzeSZDxwJd{Ok1ROePaX56J$ph2@2lYw$jby_dZ$~>qYEhTL+dmL{x0|%vS^#1hw zo=k(cw<{!mAlIvG)mq4j=?H2lYMeh_?Y|v2sWR4puXg8+&IScFP_{t~^B4^G8p&fq zV@`t_1Azw~El6M?Sy*s!%iV`g=q!ubB1zdyW1jbYzKCiMdX>u5T61}MMp^I*RG5x3 zw&rPZ+hxNANl>Hi1BJLe=WR1vavW6Q{rK`_4B6SeKY8ecn2$bX-|cTZ^>@C(#bkGe zTN)~Ygny;?@wN*wt?`Y&_byIP2i-1la0H*mRi@X*BCLoYf|&ukF(Uw*%D;4JzYkTf z>Ip|sj6{MU5@LI7=r{D;^QaV^%}l> z;fB~w2h4`7h1C7yOYwNj`PvBO5qNNa%tB<78*7Ec5EoNiQR^JA1fshaS*)ObNG2GgjkA@ z&H0ir5aSxyn&9-FGnL}fVtX4@QDJC>@{!GJt?t@@WjJbG67L~iejmeK#*K#=t z-9EC}@4dSiqpG~{Ji`rR95?KJGSFJ})ce=){SW)PV}0DS-{dZaD#D+W?_W6?XfCB| zd6xo=u{|A6#(OR@hIeOh0<10X!A1~}0tsUxOfOGC#eAqCA(~sp9n7|=p(RM~#m5Y5(R@V2&ffi4|l8Z1GXiKbRRqp!Bv+nq4%CKnJdtchvj zmes%K4IF)a=iYHIdM8l~(JlPHEnKcYY#@8Wb=}&lZ_~$7`f$BA;bZcNI3&2pqpr)e z@%eWXUffcD6`@Y+|zbcs#0B z4%s9jp_Y5eB3A}OD3ts9g}z>86UNu!VsMxQ318j$gkCRmgG})JimtYY1rtmH(UrE2 z6RX3KXQ_51Jf*db+P@CzUA>W+E;hx!U$&OS7HIUY531Z3g)6RZ3Cv9r{dOIntYP?$ zVbxmb4!m0(YG;gR{P-(){3_OOj$2v4f{3pco~aAF5K5y=g-l5w;~F0~wM2X(A>!xv zj)O7=I>^c%gg+Qf3kBipIcwLaML))n`U^7MJr!pV!jyxIAUj%HqAjQ1N4b~FI7L*^ z=L@8o3?-9Vmebs9Mr%Wnv}L(G*v%dXhoT(ISC#8`{lkE_yd~>nslWa;65Dw&yZ;GY z@gWB*@oBJDmHR!@bUB%h$;c^;cpLRco_Wm8^M9 zKOS}y>l`E8Ij@trImy`7?o95o^nS#Ggkcy})kRu6F3SxM`fV-h*{%lct8jhB@#u6i zUB7YLRmbkr;(Ed+1bThb3WUSyh!m6+DbuK7NJ$3i_&lGJCKrLVH8?(=)-x2V#ve{A8OvJ85~va9pV|kiWHp z91pZkA{+e!K1UhjD(|Pn#k{@s(hUAS5Fa1nuS3S~(pyjyS-iqp_!Q>)kZ<2)<5rSY z$qB7toy2TXt?_*A-2EPlVQ7R*$LeUcCTnZ3AFe0ON9v{G zI2fbIauGkraa6`X{qwnOhtDMNf&2vXO)%lX7gR#**2gf0n|s~&9km+m$A0J6aQT(& zDvqO7g$jbQ;J!7Xz8qv^*@7I(dB+R?o@3mJmEi0;;YDvnjwF$PCG0Oe8M~Xl>`WQZt zzx`E$$j3*0kl0V=QMG>3UpQC6#~?9ax|qNRvW^k2OE7aF`1rtA$S;!E&xbMe>wT>? z`@l7>adENkXPbg-MpRM4Y#A6UWTxtUaE9l82Q|Ru%_7M_)ny!~r1$CWMRS)KwLCqA zm33W@^xpZQcI;n}tQJS$NLn?mk6y-rEIeHN$D4jVWF0-xD=_Sj;!Ja6R61hX4F8Zf zvGa$&Z`Z#AiAeZcBCNEF>>0Eu>}E_^>}%SCn+?U|=$@P!uR=Cq zi&;$v~i~9(S1_`?Pz3P|C#jGmOV*3ueI^Nx#pYObDs-W2%mfB%uLK1eh<2h@4 zejY3*M~HZ-wck^BW33_%oVl<&yC}$@=AO7$E`a6=S z2!Ck`tK4cwWiyH)UEbkE4-ePmedDbGZ~R$TT2D!5V>d9r66j5YczJZw)sH;7XWToQ z&0TRQMT~)B3MskByr<;a_dGcFne3eeK(5=B(WJ=7x!FL=mUc0=6w$)MY#Jt_p~keyz~z^y~Drx zZ~Vq{?`!v;-=V}j;eqCj=hUlHY^b=+&$-`{3%+G`EjAYNsAuDP6v2RqSS$b171aPE zLByB{Qft*xPx2G_4B@2~B#1Fgd-g6Ih_TPzMbouG6*0CryU@x}N|H8ya#@x|Sr%mm z3wpj1Y9hm0y!ordEhIXVjLmLLW-zKeDY)HW9!+-}+lj>P627jVCbBa#354$0J_v3| z27mUuGZS`<3YX*9Lu6gbZWHd&v>un}1?F9I2^Xb`Zb2}J=ALXO|f%GSo^@c}cU z0?~GlwmUrX_`rHcTuE>W(Nc#*trjIo!wU(B$y>P@ery?YeRef zcl=}ikhkZx-_iWUF?eDZ|JPrZ`nM5$O}vZpfYv}sf^_Jv_Zy-(r7rYF~q-ke4qcuY- zR_&!}PxL%^_3XKeMj_$pZSV786-0KsbzZF!u{B9ms$8CO9A=vOI3BLocw)}!Ak4Lf zWOJUj$@{yOVyr*Iw4Y7S_5N<;fsjpiVlKywKYiF{6V_T;^K+c;-y@=lWk2D^&tx5B zvV^f*44h(`o%ipH3_B+jP9>DQ$)J@3cV2D#Iv#8PEEzcxlFLh$Yy_=Ut<#@jx;W8O z!;C=%sjgz$e!q%pCj|llQlgiZh4ORzSqmqgNc@SKe4;fzrvCZ~x8O=2#ESyxQ8>l` zl5ySLj_qNvxL61f%$NumUUeopRpqlz#s`6xAayY_-o^H@wKBTjX+J}jY?|&o zS?ie9zI+jhj-w5Sh7#N%lek!;g_a$X{M0kUW1bKgv2A%j>+7dlYY`qZS4b~L+lDu{ zTgVPMeqMaO4}x-pVzw+OWph^wWPQInp~!$N8s~($cWWE29~8Ue11=$PO>9mVmriK1 z)8Quvj@h?C5!*3T*Eb9R)y!~61)xBTi9Mpy$G-TzRbM>u;)zmtJIY@}u%jB;rU!cu zgdl+!g=^O@A2*u}54VRIXk!Bb;?xs=?jx{}67+hhhdT%&95v>H*l_hByY@9!0#WO(; zNom9)!Dua}4+4o2Nr_}~PFqW}EUlmQYV$;*;0|#}dNU^$wQ?XElGogDGgX_oFe?gT|_4?+;q z)y!zjbh4cnw(;_AYv((5h|598#SEkhvLjx)Y~$s@50l|LuNBtb?$yhu7blRIw$&{k zY>^a0K@pM?a!a$h;Hs~)`@DoKWV2rk-}z}bE=F7q_>6KQdLi{c?JuJE{u3qrR)+HI zYE08u4m(NgGQ?4a0D)5ky>MDMZQRcVfQBp9F6+T?6VR*Hqc(v^%TwHc{DTC>%-F&8 zdbI8H*|p#*8tht=2n&XgD731QSSDiYh@^z1o^{7#=*Y=tLTvW49}a%FCUd09LU6mZ zeXKQax0i9auZ0-IHZzWEt5nq(_d>*O3!cxmlD18d#P<7{F(e3M^Eoh|hqWG;UVJZ& zMDKgdo^TY!u&!+k(FU?6QRZh`A`3w(G4)fax7r5dh&mw~;b8l5jJIoV)Sz~foo!8Cs6QdJ=q*jHnKI$ot6O0dm(w2SYCyhJKu%BU4lWRZ!rN5Em)jWBmFFWL*WF^*EPNO z)3YAL_KXRB`uGSA)*2Eb5gLLq%J!ot4zI*^3Ed~UA&G~@daAe>$458jc^bYTE+)v3 zWDMKDEw=UAzl-13IELLM_~iCBF^$E(uiLYrnk}%DHin|v*Et^C)e_~-iX|p{&u_Od z3}@?l4A*tlMY}>=UhXh#=U?9P_e{rKmtf*zOEf{9$=@9G62IBBk;zqhz1yt zs`M1wB*?MyeBM_*W(2{MEW2L_iH?%kjU~|<^|{QBNuz0}*3hK-q^e@UxUc?L?RJKe zC0Ijp^k5XI-Nt4f^8-nDu*x>UL6}xmRcb?{`{I> z-~H!}?KYE6Hkm;K5@!jq1ds?f;_LEcxU$V75bzot*f1QRV-G6Z7zjFeN^C=TVz3rh zZ5x6guL1|8GH`Y=PuB}U)f)S=QPpf+wAM=0`Ng1@)?&yd37024cyKC0$c(x7I-hm} z*Q*!KMl^vzATjk}JH|j!r{C-MvjRZ}7Hcsew^yr7hBb-Y z7(3|`kV>0Y;abmpi%x+p$a3!QHoD%_QEB2KpQwm6KnN0dDS6+Z*cO2?Z<3d`aR7{} z49Dj$9ynH@mYA%e)gjj!li|@);8AwwU8z z_I|U-f@c5e%&@}rDz`X;Yc_!DnJbZ?(Aws_hU(X(J=};fIEAMnypnb04ebiXs|S*i zI^!#~NILPhsqT>Th9HVT#9e}eFICId#X-SX$7K;eXe|XnW)}=9>vlbQO zVF9l)1duRn6VnVUvnXQ(8kmp=?3Mi9Ay|KNwo?lRW>h7SJUaMDVw)m~-H1XQe|S82 z%#I(iE@Ys0GEK`oF7&etB^-ChW6kO!)LJ<1T3b(hMn=u%5t?Nj$C_oHvwF2El5X>1 z`;m|sqX&=A!HM8jXq|_fECnQgpMZR zM!Sa@`~5>=4&4W`$Cm5apI(LXkF)dwAUkh`psLjms^)xHU)Ry zmsyiL?xyOnzRtTNC1nX?L)suHJIuGSjmuaFfYD`~|9YO%AYHYvpwOqP4zaDJ>Gw#Ol` zR6!uW9{BQZB7b`rFvd58nLvc)L`x(GuidPpbWHh@A-wsJola-JUU@DwN}ivkndVJ4 zhZm`mFWO5*#yqLEWFfLXSl9XbRnN|MBO|=Npj^%|6I59XLP;J6uT0wmi!n|JU`J#)B^xb3=U0Q9<@tB+~w312YVwbpHo1C|aA;?}^`Ow!5-h!IgVw6>v|h%On`!ra zS-h@dvaX`%SloCPrm_l-&xkdx4Y67Chby@!2uT(l91q>yl7umaPs13_bhms#Zk4s_ zo>29`)C7*978To`a!s45`k-ow{iI2dT1yeQp%0VMP^Gyl_<-av5|k~vkr*tlSI?%c zI~C(({YdU`j6)%oV7gUWbE%5gUctJyHqW-kFkCm1EZ*L3J?u`qRR&IntCobDZ3}>ztYl^=zB~G1JSvTiw8JI1xq}Gr5>Swa*qi7{bM5`RCz}R>Kw-nM z9SkER>x1EHcdgQdesbtJMvybe$|_?7H(zv{ucRtZ27%%^(_w{yN^I}VO@^6oVIt3V z&|?rw;^Gu0q=<{HS%*#$7ZWC?iqz`TcdFSUX>Z3!GKd9rw#tuKDPmqR-I{u94T-KQ zhvMjd`(13m!Bg$Ek#d#TcDtDLCQ{|1g9M(sgJ$klWPih>4^$|?Bdec}&dkaqbK0zG zdmi_uyht2lEX#a`?HwB+{OFs+fFK9}fozC@*nQf@Hg*Fk+d#LiU5LVjnNf-&MAOjb ziKap@u%y`xoERBpV^>=Uv75a>2qR?Y1}U=H&6RAnK_J>Tc842e6T8v2gR<<$$BOVAh*=akFbtNrk)43FQJS6Wwv>;cLJtb)kx)qF8e+QOT0`iDreW$Sx8pUd5>+Ka zlChOZ%xLLVRoRHYheMU){%|G7d9@u|K@;^LEM*>T)}_{V+7Mpdx8rdh=Y)_#Yb{&6 zxHh$clg&gMB7qQNAOx!xV+cY5?P7R5H~oPmUyU)wS0tj5gD^%4aWMxsCex}K#UO#$ zZD90*15)?>7$r8FZ zYKQ}+2jnpaD6Y61>zP3{h<%0oBy-9_cp@z@j;XSdUj}-OG389q6-mdN(n5lyJ*-mqdU4@~-9vdE(x*&v>7a<@<;C#FmZB(WM zsRtOch1B1N=Mz~~NRkOU8A#8P9nJcH?0Z8 zS=g{~D4`W*O!iGWE_b;cwC6IPK?E|6B}nFKO=uiJmT5J7ZDSLF-?niqg!ymr0FbaA z6<|4JK}uvTV;GU6Ewa9h!!{vJ%<+_O-&zolyWZoNv^tQSPI)028U@4Cs&=uilk;w0 zM+ZSGX|E0sh=x{ml%cgY%s8g0I{u`8_-Q`=8GnuaK`>r#j3B{)Hknfbu`S!bU1P93 zNJzdoV5wT`R7Ws$ckCBr`dK2$apW2Dt0Z5^4ben=$JbXRwx?+H&c5S$C)#t8m)2U> z_Sfuk6lIMBa$4#r5=pe@9K7XV)FT|cGMFY7#Kp8l~EqEG@;UD z=6aUwNT#)zZC@p=tsn96@$A>C*E^3*T@MT^S%f*UFh5r}LFztlL0}yp7Gpkox!uzI zMJF!CILBA}GdtsJf~Oy`nBHBiVyP9|Zu@7gDpD>cX^M3a9WVM2j4PM7=P}Us+FmHy zc~K?qs>KI+Nv$QvvaG8t3r@#ze5~18AA-Nmv!7f);A!^<+aX~lJf;`-3Z?^}a6P8D zEbQOnxR<`4r9h9))lY|+Qyf?OX>JAG3KFkTo@|s(+1@&V8zVtj0!WYqryC(I$7w&d zfw-L3@a|%gF7Cb9EThdrOHt%XbEDZF%zbswwrZF+k{}S@Xy*L;QXwmWVTJ{Ut#ZU%>Kz542KsMXPfar`+Re|EhM2e#I+;>NAiGXp|LEs zcLH4?F2CB%&g-}-oOTo2TtW~aMMpnJfx!V`MWnjnzPr>SjcAHLj>qnrPjQx0E~msw zhI0udt7jK9+PH^8bV>sZzhP8{S82N;q>aEC5<-aW4K<)f>_(Dtgz<3~E-k7kn^h%A z9B`Z@`V^^()?~lO7~1Iw31-Z*Ac6UIOvWjvAV`@Qi?y;5)(rZ5K--Vqp*TNDWM@K* zLC_G>ZEOnGy{MX#c5!&=1IJ-I1#vOiyJbS{r{I0x=}M!Wixh>#dRNrrnRVWB$U-w5 z!lWHaEvvKMXN&SeEmNV`&o1{f*P<{QOB-UXa*6#@qOMjbI`_*^Nex#o4{t zwlE)}uQ=V z&i2k~NT_P5QRLYzs^<4sNPfyRLh=U{JO~70WUc)2HuhE$ z5?IWSfB^Jr-_b(9K%I^3@_Zc%t!g3&_yA45e4g|yQ{{Fr% z`!{1CwfQg-PkQTCcSXG`r#jc^H|j2TCxsf2Bu6`AOK83S9EP_q{O!lbUUHM5%3q;= zTYL_#o#;k_Ic?RYhNvfmdlbTQI%{C#y-(%jjBzDIMvD+M483%D=UiZECYFXYd zOOX&+h=;p^C@D;Ry;F>aw#JcmslmEx`h0div~C=5{gC{Tkl2syM+T$ZT$y5f6S_CI z81O*P%{d(SZ{^X;W}|r*fAw!>5y!we@6tQV9z7q~woW3b2~7aS4+qDyRtd+ z;5o~(4q`KybwTVVZw%X4{dBQ0NQleta~k%uNsKW@Nn*H|T(A~YB|f@0g4+!SQQCuS z5@S4yEJ+x#orJ1YWgA9I&KEJ=XF6(ie}8{p3bJ());k4}1y)y(9tryOQiNrij+aQJ z$(a8 zz9C*3hHcr6&gO)}xX~?5-g}%W-g!S+%sbB`}+V zs=I`P1FYXYMRR>6i>b=%cTrW(wAMIP)#-U(k;G;Y=HNA= zpw>#T9_8_nKrGv~Oyf=-g4ay~D|T;Z5EE6s8Qkx+S~d+i248t#9;X4BB&s0f1CrJ8 zLTa5PmY{ID#*4MD7$0Pss*bTN%Zt-JXl5kKLjHEj#8t3r$680mz{gzrns-H-tqUXb@9^qOK4Z9KfoVR#xESxZd*`~3c#8M@1989)2jlO z2u+MJ1d>RMai9H_kz_J0+u*&W85ykoJ`w`m*)^`OT_(%$qDilk?5gtM!MY4Kb8Q#~ zcZ%#6tgA{q(H)PrpQ@yMah2$h$RL0Fi2Y!#`+d}AUgPcUr$Fdcw#g>;=bR0TFvZ22 zwrrQgRlKwwSob^RNy68~?Q=c5zr~a|g4s0&&d^;lv1-k1==f;*&4-7%l1Q|k#!;+y zN^^)&Rh7mxt(ErPX34I2V~??H$GW**-#(u7j8}q;EzVnAJ33Ze?dC!+66&4@G$;o? z583SOFBf?5&S$>91^c%Y(UYuy8HXp_6BIybn2WPggu15(h4UC3*{BLFz|jIG0?b}H ztE{F`kNg9v93(5Yx7_auT>nCU{rbch%#d5mq}pKFhJ=i3+l~3^`U4@?q%}Dm49hSK zeVNbC&(o5`+!6$Hdsceir9L;T!>gmgEk9!W1Y(@qR8TKSdLb5q* z5b=Aiot>dxWfA8qEjwYT|w@hYO z0#6^G08AwR=Jjv5k)zQ6%b#4Y+Y^qzNZtN2J$k~8T$CpTzK=LOcaN}W&K@jAa4@dGiPxKF0H^y)m z=BlD9I}THeu~$R2Ooo*7emuTtc|115nS@U7Hyj(*@sn}b)mOG7&GdPYnLA;93?`0* zz;v;n-Hz&yFN?rUl3Z=?jd6!Wk`Ru$lHAX4^!tUc@qrj{vz-LXb__8{@@TqIw#Cn{ zUYdSAo0bJBkgVHQe(-st%+DE;mm1Gym*Tz9F3!&CSkfE2*B?B1AX(Q{Hj>fYdp2s_ zUrvMi(japr>xu*^MG}C7ATlQznv=&zV6n&dfBf_PfBC&%#zrtD*0z;qgyYVg6i5e& z0*GU(4;vIv4e$@&;~d#A3#i8N1InsJhuDpAJS~@xBvqdkGtYdN)0IHinD`>|QIz@GvHdq)=`%<%lH9`472SDL9gc1dGWOp5%fFF^3g@*hj4Pl7= zAe-Q7d-y#s7Xv};mfb+VND#4`oy!SA5xUzqq0EehW*ljV`;5(a)xG-$;y!0vdv|m8 z$!!m}jBwr|VP4W&>mR(+F8<)h=k?Oh+qstFuqcDlh{p0c~sKJlh%f$C+E!5^t`aE z#@R(|rc6o_;w)8miU>(2l5l9PsYk8)ZA$fRF(+bCi*9{pu0b&EPy1`JkR}jbuXE7H zpI?wDWZHie4&U+Z@%Y;Z{d9*UB#gVuLH4ra=32Fi+E`a*vYbw_K;eg{F<_n%o2h1z zWhE&@o}c$_@&<0*sFiFcJ0;MV)iKS;bFgaBNmaBX%En5{TUeGry6Y z96D8Njbw8`;uT_W^y`;bs(3t(qqA{YM-7LgR@G7(gQXIV$mto?(x{WbQGNdIyHY-u z!zd3A)MCDv1`Ld0GZ=$0AY%yM?_6hdD5y0cNCswqd~@*qa!(K(4m`0`Mwq<`k{ILH z^Zc-l>Eb}0o7#9hNH&fye7!MDF%6y$v!6>j7-m0w2wQn>B2rb=hGKF!zyapVwT))u zw92V)x4t=kfmZWd-krM`ASDg0J_sw68Tr~so+m5 z1+r~)-}dpK>J#ie&dAHd-of%e<3<>(6|CTZ47?Kdo@~L^$J3N{o(P`T;=i|8l6Z{hi z5$n`?HhBgP|nDTC3E9sUbmMLlV47_rAZpoGnQ_LDHO9Yzt{iy?%8?zos!H zOY2ow671;AK5gv%Gp}K~gj{Yo?DDQwT7OH@2Yc@l!$9C6Ql%Jw4ym@ZewNJ!qC6O# z?R_#3TR!)gY1UV5`CD+A;t33daV(uYcLQ#g7-#tsKk{_~P|%dU<@~^%!Hs zu+7n}h4oEvyankcS-Rgy+BOy@ZUo+YtW}-Y8>D)lXHgYbhr_fusP_5BVOGXDHk<3~ ztWD;}Hd~sqc^!WEj%SJ4)LPZ+16I|I=zZ5m>h|+c-E<$+U*}gZogF@+>Rd42Y&%x) z{2@v^s>Fn=Al3BqkJkE?8{Akch$@f!{T$)^#tJ@HA-2odT)f$?wAat1u88*tNihgz zK*n*nxoP$bPoBAa@8z`zD{4Ac(WKbtFf*><*{3Bqp0+F(=nQH##)fzA8cD$+u@C)} zfQxS_l8_9J5&_Xy*IccU*ZC~|FZe#izj>WxE6GcYAq09n&EfzY+3`pIAAu4TQbI9~ zd7!^^Ree@1LLX-W<^J+`~AdaCVte%6NTkv@zg|TF748P3C=W`h!47;#JUX zkmu%=;EV2gE5;z31cEU8*>+?9Z*9ld(QEbT#UmTWk3X)#(-_sKd*TE~7J`z{&w6Wf zG0!hI4QS-}T+Efn@@y2p-S+-Yn$&b9;2xsgCw{3)5Ei|6zWF--v_CkyUWt+tC582Pg_K zt5|{-yRnVkXv8*~ifuM&Q9@k4#tVbE&lwg%RG@cD?5c?7lHitshHU)cmWN?_RL2+< zWwjfUOl7+XEW5D{%#g>j8!r#UcfN+ku#NBB1VNDGLtOqO39?z%PND3k6&ABc!JXM* z^VZuOXi|vk^w?}6vLahTCbQ8YZh3`B?iu$WYe~w7f~Qvhyl&NEJAaJfx71n?99)}~ zhpUXe<;OS+;Fvx6>Kb^6vt)Il2eWH-w@ipYBxJ`qmJ&gPT2-SY2w}!zrde z@cJr*mXV8#XAfR&tsIY03E>Qh)&}?NoC%>)?zf_s$xaz_ua(s5P_gK?ftTmSb9c9) z&tV%RL73fbH;|A^1nW`|+c7fUC`dvsC3f%kAaFynH|z$9iSRj9!Or_OCi9^{a9K90 zT5D}Qoi^t6J?rX}b+xr5&}TJH%Yz5>C6JA2GS_=_v`J>B5!}MEP>@U8?Ssu;2?2I* z-T(5-Fqd~e$OO7AF!&yt3xPA<38*ry3d$jywDS4JgO>j@i-b?JzNeP z=0squo#YN-9#!L!u&8oFLTrPFK4$`N_EWVEmB-`3Es!uJ>pYT8i~F9*Cnqd{B^JsL z!|7O3-Dp|SrxUElDjaCEfsr~qdlw$KgDMHasx@@#yV@DZ^KlcA-V-}rYDZ3`DJc#J zl8c>r`#N)bqm3_H*~q3nU?uJYiN_1*9P}Z+8IJ;0fF5i^|ME{3^PR*y^cWsUBZ=)n z0^uCz4-}4r!_N%ccr|!ko@xx&x2YL0w4(O?#tE`$Y3Zcu$;HKk#3DP4k9T?y?L}+k zG8pB!zaOsG$#~FvNB{I`a)IIXcyf^p%j4*$HrguAuZHb?(~ZQa<({nAZ~gx#WWN1% z#LqAS!IARET4Mxa8yClbdlT^?JKG+kT>qZ%igy~SiDpQ@3a&-66v?_;mf)o|q8bE@NUX$_05m)R8;>q?gyrq*n)^}+a_isw(CEA}1x4W2&qZ*$Lbr8;E=K)h}; zrc-NKD^vA}wexyw-p*^`#*c6a3=(357$eT%9Lye_fNLb+m;gOMA*ogj{^5Ac7RX^p z#Ti5rjJ33F!dkWJ=e6Xa+gs)mUq;8QLTchoJ)1^v-nu(>&ym5+ z<->QZx+QpnIuX1qxxBlDN8zwaO@H`pr+1-W!>x9!%ns2{}B_bGn1^6v(9b3-a&qjJXX z0o)Ey96XBK6YzT~pk$TZpWZx(ZHVtaM&#|yK?q;%#(oefu6g~!*g?*02C-RYlY2%5 z7wl*$q!g{?EVjQ9Gi4mztKtc{sq#d@%M)pL+88T>ii`2Wz}xWE#cZ~LuaHalyinE! zf`&|dwI5_73|L;6jo6K8{K%PDOr%p~Gd8DVP=d-vSr(sEGeN)2j7f@;tgL_FkVYwT zVBw`$vzcx`=h`RhaXO12!Go1e>2AFKv4xn$kCayk;qPh zBO#o8`J%bU$haS=wbXj->{bOLM(HQLzs zd%4%+7zeNJ#}y6^60;ws^7Pne%IPfxGN`roBuHR5!@vV=9&-|NGE}IFD_0~d$+N?p zi??iEnlkTeEzAjti$RXMAe-$R+9Z%=K_qT0ABTkKh&nq<#)f0m)C4V|8C&m-deXNo zspFA^`^%xV7PLmyNjF;ogRPP*$RqbxkA2N$s2l-A^ZrqoJI>nMR(r(i4~Tlu@~qTH zqULNWd;Wpl^UH%Z@2(->TWTd>R%gj7#Dr@svf=P`$WrNUj%lsRs*2>dD5bi^=Q5EH zFT7rL%sHl^m-NfrNRZKFnrc_%C{>ne-XUjK!S(6b+R)Zg``Ql|bDs;r!-E5#fBLrC zXQoY=W{FhQT~^CnTqmC5NMemK#@r<6=9Yt{>X)^w)r9WnGbFyIsAUX!75le2Z=>k8 zyvhsmHuaF}+f>n=1j*(;XK;q>$c1L08~S_qf!H{SM4npPXxCb6+8Nz07PM)F!tqf1 zH!gy8ZEf@{nUO>ay5xL53sifuceMtIz;2-=BR`vec$S}1<>0y8Ow{tmtbD#P%g)-!=_`*9qM zWE?J!%?!lu>X|Vd4_P4SmLVCJGY^&<#W1{RO;zoy&&s+Y$04IMpdTn9hcLokmDfhr8BLv-(Sr+QCG*h>fLT} z?{#VY!ad9Lwf7NiU0Eb2HV&*~K&{nn2NEsenry2jU-R3jT!CL++~3M}|EU;Ktz=>2 zoPTE9pONHFiT}58pVU*rD>goC#no1F*g|(ZRA*OFPxk584}}_uKoSy;!}caMqLPiI zxpS8@2#e$?p&le=x>ilg-Nl*2W)k%2v@f)%suIk1M>}@{OV!!gSxAg;GKNx&%Xqvm zbsW%>7qjnWA5JWV;Y@h#Zn9HrQ9*^{NO*;1TLvS?JCixws!U|_gygWDVwv3u2}D|$ z2D1E^7X%$7J^mhZ=jo;sj8)wY_HL(Hlv0|-wAC(}xHwxK?dpu-!Gi}38yN;jL*jU> zHn$ji9NoKcArVcdb(v)Dz)c>ftU^-49L#UI>RWjQ`&Wh6q*o!Hd zS!N`Hu_~iBzi<{MsY(-LpL?&}cjf+LDHizIpL|6a7u4$dwH@i;;&rNEpeZF45>leHZmN9bu z%>Fa3e~U-(M%Y<+{kpxgF~yS&WaIJ_2yyYA7TX9y2u+BF<%J)L;I1J8*&s*>=H6jw zHUn`+c{bb3IjN4yVp=|`P#tiX->tq#6C)HVNw^(HU^WU891jS`q2-Wd z*-rv(?cH7{JKZ9a=^|d^$biy~Bl9z!JvVnlYcSv#Os7?jj$`P}=0L)Q)@;iXH1vHp zO&r|j@!9iJO-i4yTCOlXts~ugC*^d;&5G@_gz&otgG68E=eCXTbF91_U*Dm`8c#A zgmEc1AtM<(j$^StBlO|WXEO;}u4>iUwjW4vype^t-|u%HQ!=&P#Az42Rybvujji$D6+1J%StwH7kKqt>%iMDteMfW8y>q4mOn(dC7l)3SjIt^ogI=r z(4w?$$OrL>;~|LPi;PiA(%mg%x*8rtx;uQ1;Xx7(q%Tu9MV~+K^EfQ6)q2z{cOp9! zYBxH&I6GUzTx+UI+t10p`bx1R%LU$Ow^}(SW%4p)dYw~P55qE&Bau82`24`ve=@?n zCoX=e8lMR{&$Fd(u5BDUP8n_+f!pCxRjuxK)*9l`uVRL71{rpMpW& z%h(TdWpMvT(C4&GbVmgxj1aG^-Z`skNvMK(^wCLXC*<=J`38vtQFa4~Z6~);qpB(p z+-{aCoJ&ha;IKqU}1_I2W=yFIF?q6)!*SSo>pmiW1}{h$&rJd*INAcQ%()?zVF zI?7E%?{gR1FJEgfs%mC@l~f&fI}MJ#JIPL=V!!`EIq0=s-#TdjbEtvhBRp9h&*pV) zHB(|v2t@lV&OfY`WVOI8wlzL$5ZCJ+auCEeSIO5QX19i>PZG%H_O4M2g2Tm`WM+*@ z5C})!yHe7<@AZs*+O)r6op6>(8E*%@o$lU|kZm8(M4KnDREZQdUZ`o=__s z`5Jx=t5W;Nz3wVZ8FbQzl=IK;0SY?HZjz2|QH$6n^RUg1kgDv2G(rR+df8voZrp!} z%@WKAu{Btj%mhXF`q!%HA})pu!*-Ss#KiflbUiZp`KM=FIApWU zu-lV6d6=6}#>OjjPnUzLfrs)n2-6snor!QfkjyD|dq*(6vmjMv`p$#o)RC^Uvn)$? zlg-vz(3&$`9H%>6Uq5TDCFE&U!AjMM{_OU8MkX>@g3ASxz1Pma?(gv?h9=p5&Xhu> zF|4ps)ttQ^I5Os(3qcIV+9a`U6EzZ&&2Ew@;fbn+aLAFo_TfA`!LlT9q0O_{T*g+~ z2^X!wuC-xTrd_pWdu$!&Z??fWvxK;2&N{*B1sVX9R@xJdBzNGLX%Xj zDX8~Qe;lQh)-v~HxlvUP2RQBPbmUq?s7oQXU#`t$GwWyd-usL&N=x8yK(Dp_&Ns08 z_cIyD$%DsXIb=p=V;;;*P^Ei0>dv{&lTIWgt7=3N4heztsckb5!P7$y3YOexnyYTI z?u!Q z%XOQA=f4JW6wz0o5MvQ^$KbHtGup2`|?^UaY>9}6LzF_EB@W!nRuUnS2J@4Fw z*i5oPns(al*Yj~1M`LEDmw|QNk|1bb!Oj2j4Ge5Mq9powrB#>W4JMGbQQ@=@4xX$5 ztDtS?vlB9dWUW=!s{6w_X|cY3C6WllNY!xq<@G9%`sJ4~@|Etl#F4ZwuY}i@WytH2 zfoc~Q&#x+EFf?+}=Eq~7jnAGv^X%D?SQBo`o%+t=bjl*wUEvZ82|I6J&y(0qU==dX z&rfn-vXaH(G4j3hL^eqk8MW3bH|QX-619FAqiiQ0$I&j1KmPnnP7jFWI8gtj)>2hp zUJ=aWVE!F+;uTHp5EbPemXR&FmeYq}DQs`wE@HDZmm9lWrY(!Jv}Y6$#(BP9K}vlf z0ugo#NyD67Zz0N};<>6-l{4o-746nlJkHZYAxPF5UkM3X2v5nw4XI%}3K3ObN8xTJ zNXfj*pRfOHk-+s@#Y6H$cjHGcNthfo>M=+0?4mW1s!8;jotLd;$%6+s)GkCCJKrV{ z5_N|l(9Xk8zRcLq7sR&8XP0dU8MZ@W+6{4e7Q|YQ2lMdKYt`^ThqD`De8m`xZ<~u# zUSXJ){qBx_CI{pyQbm$q5LiqXgAR*Uq?i`DZe%CbJcg4ycV~>$&No!I@^E`_eF~2>kNrEI{w6MOl z?76xatcR7@&USH(aeiN8E#8hukW8Hfi}R#A<_r>|>hv9h*e*$s<3LX_FwXkC@WS3O zeqM}m$B#kQD3V2yy<12rUanX3#e+aD8*+k%#BEi5U%OHSQtE5WoKhu-5YN1|k*qm6 zhRP%JGWDd&yS6>)J$&aNJ3%0Ysx{aH00rjz|5$% zoJ|$e_DT_YBoCg;%YPhvQ5a+0ACH6t31j@J&hZ%zB(}L9`8wJ*knkD~jZ+qbgfnO{ z#_N|rWek$~j0k>U!ML)V#-;c7r!S91o>!q96|66+;8-0Xv)Ik~VeyWT$# z#3CFA#yo>FuePn23d7L&i6l69Oz+**Q-W;91J}&h27ba1;Wma6V(A1DbgN}QFpv3H zVI5d%phC=v$>4fb#i;dw{R%l2_9!?yWLuW|`|_lyWA< zVmEk)bzinAtS>9j2%JVpnYt;dkH7Qr~^L<{CZki`0^F@~z9WIP;gl1WFDcZ$QTtbK z_f-_bu&z0i1Kq`0f0u6#vMac1HBv1lA`EHZq2AW;lWAwJ^?xsRluTsV)<4CIy(-%w zFsCssS|q4itk`yVSHb#-(_|$+s-yI1h*hZd&sbDm#YTCud^{<%#0UjE#c`A z(_}OI+>S2O?5eJ4jV3meLLTq$uHPb9GEia+aUK-nAF^Fwy zMa;(h+RVNuD9hmfOKb+N>Jr^$4Mf0KPYhu3fql3#u*bdf5=hC^%UrA4D%k4Ps6*v2 z^OSBRwjmLO;5dQ|5#*2@snX^{5UN;0LUu;05`qvz{A{ho6(+@8wL5kM7G!60Xwcfw zc2%_J&nVANi0J)dDLv#7W3&qbi+tvMmgiHTh}S|k`#CBx1_Vb3OLH7Z_HGfZl`-5H zLrOMlZ&<6U)!7lep{`XCO2r;pnPiQLzJ`*&h$9o(7Hv;`znODKz$ju zp`X%rE1~C{@66LW&m|$k-m3H#5zN%0M22vkY&d(FPxj+uUz97NSqZ)zGW?+o*?OUx? zV+ao3e)=g)YWW6d3vQBRR1xNUOd-jQpgYcGf6n<3NQ`aO<~&WQk7nAAzpd$$evdwM zD9Ac+S!}}+<&8acHjYoV>ZtO*LbExbiWQ{sW!C{>O0cB7{Wq|zZ8&@qmQc3Hm{tB3 z6BrcQBX+|)gycg=t{%14nl7)ZHEg>(a<1SL2a(a%-~3I!(i}&xIjz`U12ehu1Lyfo zLdeh>wTpf>Uj(u)3zgEN4Gq_{hzikG0mS zze&N>oKwtlE1wIA{f4pb_pGmjyWN%#+fL^E$eiktDI~BG#Ce`i0zqt3)+V}*kmEpA zC1YeQZkiK%r~a58NnX>b@$Cf5^1!l`Vrbj;*m5?{wDYL5u@2YQVT#7n*o@BY+67Bw z7}8KhVgJ#eL>X1){=7&=ic^5fDcMZ=tO`Ofa)x0W35S`T;P7B%Jq|h;D-nNlKPjPE8VQ6g_jQc4}Esb0l_xnDSRB4W`QWDpyZbO)|Rwz?ZlSh$;rAcu!OsRw6vwjUq!pz7H_RyU`1F}T5j+v6^IJR}@} zj1jyACG>m5{@b7byyOw4K*pd(3O}0N3xZOz2FQn44b6}kf^@5Pi4bBA4a7VadX?W4nD@Aq6|VL*R+aC9zs~lz@HN25a&-{>{p?K;B*hqn zb~#}|jWnUXaIG@Nr`X2s3akZ>#+)QBchoZ5T8AVM^9u_UdT*(s>ghnMOHI)d4j{t9 zYCl1}8KJDMBq2i-DlLn5wX zdknJ(1c7*Y5ZMeb%tr7NV!P~TVa{A4w$*K0G(Tch;m=&oUAbqYXi3niN<@d_%dpZi za#cokH#~HRD5)ShLfyhr(;=9>N#-X$omi^{ofwZ{AjEc1G+=iQ5Rn+?$$8kJ!ll^#QZiuD~ zXcW7un*v03-OgRsFp%h(h*@pJj&e~}6>kxrp47T;x^A399uJ-?kyvYuKj$Gj$2|07 zpoAo`)|&b8D%*JwsP88slJ;CjzF6H79Qv~=8K09I{fvy+ZMO|WW!JB-udl`(V;bGJ*Iv$ht;-EOzPK6~+CS;l%m*uIcQcP}sXY6;8ourOFYe^zIB4P?B@G4flv z?hpF7At8w@+_@4QfjNerW346V#B5o5tuh=8lm14~&lq2m6OtfT$8kJZ-1F^k+I|iP ztS`D-&6SX6chiK~WYX-T)_nM2xeg4%GR)`V;_O&`;=wXKhf)YtQvLd{kchx8s_3?S z#@-}-on^2ljdPL&m54l2AV0nL$6vZUVO>{-4P;*_P8G$1mE*W4(4;- z-dTsLl_yDjVm-fD+}#a17E@SmjMu&2Wxft}@M1A=d_K14xLIy5FVEKTviIkP6e*^c zzFe;sB;?Fi?Qh?9Qxbyp!8bSuI>F6Am8jFjCg>_oOdd&iHj_D|eSSlpC?xThPy0!} z5qv>6qOAk9@t)2Ai9mM0Fz3}la*o>#H>TYPba$<_q7+4Eg(T~qWbf^)s_sUwQ|`uS z+K!>Bc4*Z>xSSkEbNNHPhmX@Bf#5Q59LWqk!v0xTkmxQ>Ru&b(6?S_~zrnRaXs%n}LhMY&a`*K=LAH}{~C6RF2 zdrwv^Tz?WIb1sSPtKAih5==Q5(DC9=gnMjbTPsMA>|7l7D|kgq7*fj^|0=HEwUTiz$6%!AW#{$K?Ej;ZEWME!4xRj5X63jc=>Fw*lcvf=2W)cERGPw1jpmZ zJPBmRqiKI(^CQM?AS|^uvP0~~?t^%7HoHMKLZJfTZX2>OhO!Oiat4;~9=mH#kl4oW zdodry*2gF_-PWXSNj8X7$&+IB?0&%3%y#>+2l|v-#Y~3vYE$DdQ-hypPz3i zlTu9A#>g18e{MQ!ZLUT&T5CsDRRR5qRah`l7H+h*Lz|N8vKV?I8<+Sbz3koyiB)3M zdbSWzYb9uYN%A^QoR2(mwj{@}R+1p(>npXK$YY}OBpe9Bu!6f8qrlE|+GPpu9*ZVB z$KD;6`B}vm(!XSPZ5%Q(Bw`y&SN!YEkJ z71wc<54+us$APCs@3YrUXUpRk(^ZWxo1%qcNvygM_24QDw!W1&Z*MlpvWuS=ODmuB z9>e&jYt@QvkP*KBehdgC-q!s%GJ~5`C3Kw-x?(r(#7e@F@U3~+O?|(Zrb!(NeVln$ zBusg+(CBx}QdNy%7&5L8UL9vI+f}V)U9{%d&U&Af@_BnqSr#topYWVW@VF=cqyj%> zC4Pv;FsefEwoGE=^HbSZ8*xRBB{!N_z=v5wR94)xgAiY+kPOw{MuKvQMJ^lwU#_xykTg(A%BoS!aNFx z3LiW258u0`YmIu<`%qE$<)X_f!E|ltLeyEef1|FQ56xPZs+v|85*(}`ZoP@AAMD_| z*8e;km0-kE{G)%;zu~XG+UQt;0uv-3!%L@-cmwa_F)LR`$?ky^G1OFsxfBq1!X z<0(ljYffMkmSt)UJ?0L}0YguF)!pQa_v$(^AN8-_351rXRgZ{QOU# zNjR*>szU6R4xy@|?i)euPf6J(bLRa(pa@l=xOq*mAT_v|=$SyQAiq9vLo@#0LP=Z|+4`m*~ z|0PT`u^YQ7%uEPnm6r!q3qrKm&4x_jVH^9QYUW4Zv9qv{C?rgW4ev@LG^X9ClqN(4 zQKp$Ji}`oNY)r54+T;~tJ0o@z+Ys9jg-o(Zym+;k2tvgql-;0kgg#L9 z+=xWNgY4ljktu`Y%m96KV6;&A8 zcR!R)G5_iQPKD%hdE6w-;d(vK@zYza&HJVsArPh+7z6F`6#{KL-i!;o4Z%d72l@Jk zy=^u^AP;W#TVO;UNM4dLQB(~t4PK7P>^EcE;M^u-p(e$$Y=1xag>FvcN_p zem@)c)4Xr0tg)fuAiICSmaLogMvtv!r=iy)p=^}Jfdz>IYqu^V4PF5z@R?>&}*9V4wV2|2VO+QniY zz2@0O(pKv@j?_DfET`lWmU)TEOkNx)7zxkVAZNDT})EdHwi*p*Ps@kb4 zE*|JV)~odp_}M%0wzE4i34tJ+d5~3=MJDS6FixmbG9?aSRbRJB%5HC{$DM%b0sq2*>VX5iPNHit+K{BxGH@k`Qj2A0zF^-A) zQz0mzIcEDr=nZE>IvF4Vq!`aeNQ59n(sNEp;fy;SNmJcDYMDqS9APa%5R4H9LV|Wb zuf~}NA?5WtVt=l(ILT^A?f0XR60&1=-uv~b>Ut&wrz0U)xnSiI42X}V2~<%D0?`;_ z8Do4R5Z&_ZmbeEACJEN6`q@}}*(3KZimDVnqD|u?^9diF7xD@=ypNgBrAuh?X)462dCcklY`E)5v0&LR{xsE9>X8 zc^-q^Ym=xppi$Irr!|b;_FRu+xpyd!kIlZzE(j81K#gIzF%#Rw_RC|ykJq2Y?(BI`auZdztL(aI zfFH8kg;3Llxco>S{ex^N2c=r^our6g2t$xsnx zK3twVLD|-yVjDh*Aqd3fNlZf_ey{h3$L-Ftny z>aHbZU}nGT!PPXv1v+=;*-lB0>mu!<=XfN@xVRRoATHa8J+=3Dqpk=y&u1q=BDFb( zM<$N37K*}JlkDXPj*}b@?j#}6J4+Q-x3tLfql2$G-PbDH1i_Or*1=jL2|bewvwOzt zTGMvn+xFx=Xr|juzJi)2+;rED01gGdx_huJ*==f+ZN&?L=sr=uZWt9j!ACRMvnl!y zG$iICxjkkRYR2wI3l+;IspU2`?a&>k#vBA(DLu7@_7TL$C=$33DvURYf|oT8JY#f3CG=J?|o zBEcuYjih*cyFN9#27WT;plI79bmLrA`s9S$6(Jd{=nvITa%$cy(D&K+# z%-MvXr{>Lg9*>&GM4XZU1**Ly0Ie$+@48L{RaO1nU&<4fnKb2Fu?a={r59w0ZfCpN z0fMFl&n&>%Kp#cAxIZF@AoWv71R<}lIqfgJ(p5gS%U_)XAxOoj`zC~hAM)&x;bP+p z*K_X>heTDa>xDZ*6R46y67Lh^tG2hXs+M^0faMYf8?|PC;p{FLtnK-CNJ-gWb~DDP z@VnyY*H3{w@Oo6QW&C+SAP6N4%l0i_AXp5^hjBr7?9S9=#NTe{Hf>|!upUS^Zgvl! zpEpM7_tD)6_z~F^y4|Fz0MWUjs$LMn1wUjoV1IcwI{u_)cAU=^eDw$d zK~)`t?gtfUyN40(fk2ShRt=TpgFwO&V@O+TN?eR?&&I3|@(}dcOeEiGoG#}eN%vYw z?ALI!Rb5%3*+vB(h3>X`m@e?uj>@@T>5)iWF)O7LZi19?#b+b&nd2fe!o)s6@!vji zRXqge97=Yv77~bUYPp=k4Pu)^>#tGI2qd<1<^HgnIG~mc;p4iY?1zNJ*o{?s!HXui z*d4E^-Kiuq%&nEVKR^(ztz=tDX{XRe+EKY1RuZ!-F25z*kVJ(kh6Ley9fn%nwW`X+ z$#KA_d|gvQ?6+bFGVLeC?o3DGBv?5PolHu3>AROU##aW(qXvdeGo;#q2k)V(74eT5sg3+V?zIahp(TkIYG?u8+;ey;ypCPwuBu@I-4yTcaxK8uK13rwhRt_E=&FTW02i z<0L+aBpZs;i}UNp5+pcAk`T{mBgy~p?dH}>ksydNU3`1rVZK4az80NGeZx$^W@v*Yk9|_ukQ;-LQK5$>9Yy(Fl zsA^$8)XzT~n$rb_syiyEx+Ea{kW~`Y|J)>B+38CAtRUrGvCk!XQ1~?qu@7+I=>xN1 z3i=2Kku0-5`k_y>?Uz2QDufP_NKPE1=PX$g34+!HSxZYf) z+1%}y3}{fx^^)w4J$D?*>13(>zC1X8PVfSO{pIIz_#CZ8l6*O>H7_sSG-jIh{TbT! zquaFGE%x)?r#HG|x5Dj4qwQ8dtrgBjgdct-q4KE06x@j2l=XNZIFH7`yKU~%31N1E zw$0V(UanX7py0VFY$L&pd=4o-v+j0!XMGwg;V3t!`tT63~OSjQY=aM&LM<`~hFTjnc_IKRf@Kw1mt z`RdtWnnIGcjI?)+hTZe!MXal)_f|EnGeK)5xUhXL5+!2@v_5v%>+ew#V&?fAUsZ6# zZsRS(#e{?}Fj83RAxR((x10U44Vk>&4sND$3~`djkp#h89tV%*1`XdLN!ob!u;6+$ zVjG4OGocBPaH>^B>TXj!PJ2)#|Jy%Y(_G#7=-rGj^C12RirubvQV5&_E~H4uG|QZl z5(y!hcykCVzK#|_junD6wLH7Xsxejv37okjeavKrjIruZh>pzsG;M>NA77{{i8it< zt6`v(IqGpef97>tlc71!yxJ_H)zd0mE(_lN&xAG^W``58UxiRYLgGVE50{T=phmLR z7)J*J>1iB4`5R&=fs=G-bVg2Pe5H*If{U5g7Az>giUu*PG=#lMq zA&n9>Nx?rD;m3Dx{e2&9EK}|k%a+(472~)NI)d{|*+B>yo_w{94;?|QB7!D%(-78O zY-1a$1sW|SLF@*yQ?^&J{lLwgdlqEm4vpYa5}UC#gn~eAQihn_{fIYWdlCdeOfQ^b zL752Rg&k<3dt~>#3ZaU$J3|mvRrK*OVhD0DB%=E1Pd^1-5Q3Lo=AKU&_bj0}jyd5t z$a9{X+XLM#iQUqJynvOI<}AC5Y$Wmi?6#`pJ9LJqF(D2ZU-VujV@T}Zvo^<0HjeZ? zXn&;(?5JRv>B8b!hKtgjFGOW_Q~njZeIf&Y`Kc*vPteamI2$BWD5V~1A((Uze$B$1G+v5*KF(LWfQydsVROZsGf#q^bEHs`am&e3yf*D^E? zSI;=F^lo=5&DPJKmgUmN;4MW+)?x2^CW<5L2Uf+Hv){Wn{a(y}E^En|$M+==8U?pS zlFXZzXETt%tvhxHL4qStQ?lAX-jPDy%uuyfRXzSXB~BcZ^-F?d(p=+!rHT+>$I5lk zZMwknxAG23oom}n9HtEXR{xK} z;dT>}8j%ozhlC)6D66W>S~w1J%t#j3-0v)vw4=3)@w!V4#&IexF24I`OI2&yv07W# zHOcJpZf7}&&-$#BT;7rjpW>f^ReM0KNc=gP4{vY7T6O~m`hTd#D2y>U>?c@DEW1a7 z1WVOgi`a(TG9`yVaDPNg%ruPqg81=zJ>b`)O_*bh^N)=n?>)Jihje4qz))3h>fBIS zs-TLgD~guZE#ZwPy+|oo%t*276WuQaKeqFL#9RVWJXzO*8ONM5u4AsnoWH?m+@NYD zIVy;yI|c~{)OeH-iEh)CRaI`c5QKWZ4s@e?uBw@eKm0+^ERREteI0BL7Z)#bvd46N zU2-xY+_rXJxAeX|JFte`CLXhYkwJz*X^nk7Fw`A~1Z~E(CIG^!07=5Y7``rDry)Ey&NWuYClLnSraSTDAwbWVJc_of#A_pbo2m zgNCdhDpIV}O}X6ptbO;L8Op-qCkV0axYv2Vo%5p8S#U6iUZK%V$vMV)^z)cgLXGaw zr`V=SoH381gK@W8A?DG(EP_M`V%&a|hcaTUCUpb{FoyB9uIjFC-~n?c*Q-LBWlg8~7C)bI(2T$$|j z%Z*u%Zz&BSHlR4iBQl)+5!kK)h`{U^pS7R^qaLd?wK_p+kb-O^1qV&Ud8RO6b|>X- zj*-|6B3U?lBRs3Dx+et7LPmGJha@(`)RR|fXHQhBj)SdfuRcgDH-tp(f9t|RVz$=0 z@1_YxAF&_X1WD|UWQQYZK|Xs}j9}zj<1htdjIkC%1RopWQOI=h{loSH!XOBQBnJao zcB9b(38co&B?zj)fr3B$8@CPLv^$BNOL) zh#*#Mk3Ws^DRzU~nh(B6NJw5u5IK&S73#MJPdbP=TTYW4u4r86Lqeq;vP)vl$WChm z?WQNgr0@62GuhQ1xp5iR=5kq{Nx7r%FNE9`lFLO3SJ~B1k4m_aRMlc398W$4$6U2Y#%UFfqd9qRhI0EdE^`<79BWp zX!^kzndWp25={DYNRCQjyxPsGx>FB2ge1BO2v%7*R%5w^?osl{!--;ybzDsbU&k1> zr|l%h`1~^L#`c&zBVi=Eg9ju?5G?qF_x6_?8lzTK4LlwX*|z<(;vv)y=#H5?EUcJ% zt0h;z1yAW%9EV1C>}mwn0}f>_LDmE386i0CRd+Yit;%*Jkt3m>;!TdVbh@c5+jO@S z)0?l7bsZsrPC0`R7(=LKakbbQWE@jPNn392U z+(*`uP2x*}P!XeWp66lOof}Y(LqoV=*AJ<0|2NxGAGOrn?OGi`rHjhz`%30|ufEVz-VoCJwr6|s5ep1Z0- zY__UWg&Ea`$Z48RgL^KYmN+kxWw^Wa?@B3(1i)(?jUW=jvVRCx!5tdGAudJ>AqXKnU5@?O4IC3< zGZ2C)Fo_@#TX!}~5QP_uh9$6!0ng79&9n_Hg1p+s{_?^ZwEbx}rpwvXA{$SHh_V|m zozpgmi@}T+XY zy|v|i%k>RUJ=h#jTK1yZU){`U`@BzyILX}@V|_sEo)xrYGtyG`khB$kTb^GBc@5G7 zDPcZrgBH6X@W)y-bW56{_lw@mTvEHllyPx&Wo|YPhmxw@q~-i#IFRx_ap)zpQ3@p6 z_U+&L6!e#UjPpeX4&#>ftJf>U3&W$k<=yUD+FEOU^d`@^CB8Do${6NaobkfIRD&mX zatmY=s#cY_ICJY9hpgD%2{|TysXL3apYGXd7rpmOA*8`okHE^S8&j7i&rZ;u60>OV zZs!LVrj&@8LJtfHGLtb9IcCC~N2+tb=M=l$ohn$uH5nmfa)|BMs#?i`ki;)$vUrd| zs8NmM^+*!Dwyyek&Bd#=@sjacySyAsH$#m3T9;)S%CfBM9)IR6r=^sXt$g{?`)BO+ zdVMqvY4sK1haYmt7$S?}d^`@F13`G}F?iSyvqq{|HMv3vl2i;mvX;s`5n+h^F}@D6 z)7_X?sR7A}nEk{x-8~ndpU;ypalO(brBv^Q13#D5UYlGNuY4SyQnNS)M4XkMS%&e0 z=oz5z;m8C!CdPy?9{M=(wEKJ>A&~MdwzSeYDCmD02LW|*GF;IQYTUQic+FouBhy_^UE2Tf|B zTf+QSK^`3kZ;90>3DJV;XLr(}vl8`%*bP(-Loz2VT~K2hN}}xhI7?1()KqZM=)Jd> zTUE#Pyk%&^O)_7!2QP2tc9@8QakO?`-JP!X&rA~u`sYnd1A`HaVg159Nthkvfpm+D z!TPnkS5CZ3+`PWpA5jE1OtdJA5zGUzEiAP*8i5GJ1ZxRmhB43wd`yrcB+in!Wt)V} zMA>-s7%V>_t^i`hqT%^HMvRZTyNy5H(+5Iuc>0;F3jqibyKM-*;rf#gVm}00T#VgP zsu0`m*iU<5g&1Z-7IE_uWMD^{r69J3(Pw`57*vqa=4bU7V`~V65Vs6mY5R@0x5DsU z8}Xf!pj6SnjpFw>Y`cRb#C|ru+U9_#55!IpNGSqD<}Vd)iE)2FrD(C+-XccbD8Zny z`tfYv?o+~#YwuU+XMBbgkE3Envat}`e0+pCk5x(B5rVQp$P~Ln5CmEEKubcc(EEq? za#~IkEJfen_xF;UVUQ}9rJasK4z^wzd4^Gt!!bMNElabmmPMXf*T>6S_yk#-puY4y z`xq_;#>e02bKLKnBzv)q&)W-P8%dCXIF4x9j4{SnRm(PB9#T~VBCtRoSn_EqM6wZJ z@mrBtl+?N?lajO-Yo<}WMY4r#5jE$z21rEcqfjm6&`&PJVLxFNk&wusWtr(CB#wb` zM`)6K9m&^PiEV7##n^Yr&i$X+yGIGjNkP3!4XQ}&hOpG}`r3o45*g1Jreb^++7fN< z!jrgrVEY*sd*$xk7L1U1L9ebsAXv*bXTqE_$3_Mm$qL!bor_~oRjXUF~%4W*O-$7zCikIhmpX*`lW{5NCF8PQp5#dZHa1^ z3rm1c#N`L`zJ7L;s>P=|#HSG^kSm0*T`ei@@}m#IJGe0C=;7YT@Y z5CI~<7$QIf{{-Lmr+n##M-DkCTR(*MT$M!3!;3x;eUpLu<4M;ArSsz;5LVP8S;=b? zc$EkVO$hnJ*$A=ftg!@Q8%FyKVcIDvYt{9=1Wq3dW$8 z8JY+Xf!K-Yh&jurzwII`Eul9)_+ba->*a?qvwzEg=$Zg7hCtl)NF#Xsn&)zmvMn4u ziP(P#;)YBw4Ww)XQxJj>#C%BhC5YKTYeB`<89~a9n5d0ju5E_6-%kihXgwO5xMl2S zgSH(mXR~|w^uhyiIhjzw+h!XVYi)Mpg~dWcoD#7EaUmgLoc{=H%u5<=XAzXL#VJ#C zMs!Y;1ug`XF!T#!*X;x9V@jbnau9wZtLAApBEh$Z-9T4V#o=;d*p}TPRUgPINT`*^ zU!v|kSP7!FSZ)^TL@Ttef%2~%)v-YvmIH{?QWV@P~#emam<(-_123H1vcdutVR14EW_7?X`K z28Jvxo+Pm?annYx{ltBclD3%2qEn*rZ#BMF7{h3E9q=$DrG$e-mhCZZN8b>{aj2@C zl87M3ki(-E;s?Av?uk53O;S_FO5N`xEoQT8*YV8#J+(?TP4(mHLQK=DlA#TA@9%A` z9VZ$=PMx%#B~dvbb{^baBgh54df{b^@3Cc=hFTACF|n=tL!b%0IbzHsvli|fKh3$( z-Hfz? zL6>w_M0y`fm*mWJT$X*47pokKXb!vGT>Zt>bULh(STkbmGg;eO?Nw*(0hO4oT1z*$ zChu1+BFVJA@9F-U3uMmF--5W9U}l}?c=iaVgpbvdFmdN3Q@Z&u36eZ?H)*;C>k)CD(9YY2=FT*kksLb3Xwe9s!9)Z zcO)t+$^0?QELcoJgziHJ|c^s$}) z6rS>9oNPHLdk@5-E*d9_JM?qpksF6io@@w&0|K!dq;~Fs0~6=dHi8rcLP$x7o15Xr z#o)Bq?6EaO85qs5EC{W+cd7_M2tpucL(QDnFG3*5o+uX|E@t8+h?iF=+w2jS$1q%u z7e?F|N1tpThza_K&bon#wTop0Q34l7)T`d6{mULefk3Dmn4-m6@Rm6PH5kYa`f8EK zDYi*0FI}Y~MVu~XRo@9#B;~al*XxHpWq~{NPS9Fq5oKg_y=0yZXiWy9DszPgf+HN? zg%Aj$C#+41X%IChmW#nbCHD|>_LsMAB6J;^MlcSti*l6 zBgcIsJF$Hb<@uC<(P;Sl>H>pq1?>tbs1|h=Jia1;~+*=t#43w@3)|thhFRK)ky5m zgcN}^#zn}%|Cct28TqM|lv^Omr$6=>B1wCM9@$Pp&S9PidFy9;OB*B- z`Rg5zh1Cw*G=Kdk59s~~7X3}MmVxIN&tb4o|D+WnK`hApq>Qu%H5b$HQtR3I zo)u4f;7j!Xd7?3y=el$-#*B)KZ9KR=b!y>hwhIc zbURpM7(sHv!x6ge&Jp+ti6&s|9BvE|ATo1_<&tIbV>|w}Zzm~}FZ;t^r9@}9Lvbzz z`VKJ->ia$=w!ab|ZCFn?n7_86$6`=|w(8^K+-z6zHP%`h2PBX7WL)w`^=NX({(qAl z>w?KNPkk}`puCF2x?UHJHe%U+?2$vY9Nej~5Kg)vuYQjg` z1}Ptn;jy#-0Uu3V4h{om70g58k9soaz)GsZ{D{kmFa}%%F1Q^?NJ3t?WtSm-U9&6^ zl*~nGqWJTL-pBS|5nTw8u?u1wf^5V#7_uQ@n6_sGkwFL{hKr#IO>`*`G&r+side*E zP!NQ$U~WdlX3+a}M`{PbE+GVBHgIwK#X=CYc=5Oph>O_-Vt-Y$n8WsJe@)*#m?99t z5n)&K7E0KYRLqXbNe0u-9Z2b1Jb=%Y>KNp|`H(00NOscJAf(JA9z?=g10jvIum~bZ z*4Gk3;w!=^LTrmht^N5O=hoahBqUU8v)*^AqH4#`+WKN`K}c+m<#2PS&vH5*%k(nF z=piYjwKe*#Fa#mXv`o8G0)q^K2swI69_A4;27zEkUl(Hk+7ohgbWhtxT=%v;Qv_IR zAi{rXX-dUyY{;mx-K;^%=wih>U8L}U4lILD3Y9-SgcVY^Ki{t{-w-k<6+$Ac>iJlH zautc~;f5ep#c??7M&zPa_FRP+K?@nXX-rd0Ps=>)j&JG43`E(s93K;c=nvU=C*ir7QRSDr z?7X2*wvSJkuy&vMpZ)_f^eCx&lR-ICC?43CNHOx2lf*W8_TN+_Znwki=BT)sBeDI+ zE3r*=trZ>+beBbJ^T43LzG819gaP}jm@bQ!VPJpD9a@obNf`C<37Q?|Q8SKt&e$|f z28pWs^jVFqlrMz7k1j8jt8F({h5um=?dGt?uzSy`; z`}%dPagvZ$a;CK~+LX(j;QLLTJX7 z5SKH*jv-FO@iiRhLL$3 zgZ3>@a|QoZwAf}8Ra#u0SGwO-l_FO(XoN^&zr@~eY+~0e!FEEF+n1$tMI2*(8j;%R z%doopPn+1S3`3AGJ2#@A-9ZFd2gxBM!jZ%ayDBvhgod53q0h0JZK3ZILIPD$mDy%% ztqo`GVmP}PXi$W9!5H^!g0l{%1+M3i-S~2ui2cv%RaKDLn9|)(RaO<+v5_m(7_!vj znm{8etC&SLiRtw~5Elc90C8~At!-;VC`n>aewQ3KWb~d$LsaK;KXiC$c6K8s@pL&} zT7+rZme^(|_9KYd7wiy04D*2?1hLtg?LqXQ3QcSs?;LC6#wrlvwh_o)Av~bHG>~C8 zoB0JZWiai>i!+Acunoj_4rIK9@>IT%t6!WJZyP)7k3Weh!_UYpMpR9b+HLyBdvk;y8-weEMg_MVY3MpBMHwb)-RtA^cS zHwiM}gzvMtCEYG&Jjj7#9*BPCs+)ayCRw|^^D|Y-@-vcoQ%L?czyGD*=-(78ki^Bv z+w4A)`VwnVOF~#JHR9~ZPg4>)QA0&k{k1-gg|9Wnr;7b0KVnYfCV?aZ@#~YeKkSE)h!s_tA3vb-fjF)_(@=l5pVszaA7gDX z8^jXK*H=s8V6(XyNzVGsjbfS(Qz_Rj21vnymhikWE~e|JmfoFSYqt*C7-!bIJH`lZ zz9e>w9vYHs%kyb?LP#Wu93NMdkBq_n2TsAwToCn0zSTPa@Q3LOBnYd6s_}xy`2rl&tT8uR|RmLIgz>)lh5GD4+ly=$$uI zMf*T%J>WgeXvXM;m@^2veReH3On4By}hx_~b%3_SWVHe9BiOprT4m0My zo{*zNd$EYUxkknHY_r%ELsUB*AK((vEbS%)2f zf|3#>j|t#9WEGUG0*V64_U#RBP6(nGB6>zrYso>LEeJ+APl8wodY?QCJ}Q~uAUMN8 z^Q8BA!!g`Ks?T%3T9HNg+{VCi$eoa6;Va7cX=mTB*Nh=hLv8FqnkY*MoX^uX36vCS zRiI9wsFLjgDWwz^`nVLyMj!%90f-Lb;M^x|E-3|@|s-DpyXG59Gj5F_{12(eiM~<>AROyX-GL=x}%-> z?Em&lEW(U~m;qvR5VX$dilX2MHK>B3N^TtjL4rwwv}w+u?T1g~a9?YWbuGakSgAJKCJtmCizJPN7cC{t$F>zN)L-Ai<$nYcCst_B?J3 zIBJGBAbyMgFUcZ~ooeWV01*O8Z`%;-!`S0WD<{(y}Ld zfan|$aB+;PZ%`Cgpr)e(RBMz(VCFc-DnazbuvTRUD~Z-#mpnEIYQ3sgt?@?t&=SjG zNpj`cQmJFrZod!xi6n>G8LCKY#?Q>0Xsg|>Vs~!HC^5mMMNFUPW}{N;^@)VT#XiPB zSwRBv(6~?o0Z2ZC1#%S};6ii++)@KXpNK#oya_{!dE2eJ+17IH%?_ZYEeR&!I{bXDC108l zyy9Vu%VilTu>H>uu1i=jpVgBmULCNwf{=Oco+Dyv18qF(eb&3>Sx63!w(t8GK`05q z-usS2-g)y0jX7gjYu*GJmO!aj0ytdb+$yLlI6|oF2xFYX_gPt@4-ga4?>7{G$$!9z zeqGA_URJ>46>_&0b!bqD3#tn#gyaZ51o9OKbv;6zssr_&UhRMiM1EMznTDkMX?Kmx zF_>rse#CNxgM&_U<8eUoF!FU-rpYi(IU~KJ4G&VSNfqinqs^>b#swpL$pfL@=RA;j zWVONfd@l3yi+bueMBxIIuW)OAgdq=43>q)Kkx1Mo{OjDZA8L~>xu1A7NebE!25 z7Pnm$r1UQ>EQu;wQ%Fl3SbFoU;#UD`NKn_P0w_QT3a~;-sqfT5jp@5vrgnVr$7^7bTezv6FOj8wn{bl1Ge@ z^B1#Y5UK>hJW6u&nBCp@^EffUDnQ>k2Vpn{h@s~)?qjj;LMwCtE?p<$DD5mp)En64L`n`4zmX;%Palv4hBd| z%rms(2}5hN-Y=9wC|ko-kZ`^Xl^~KE(q3R!6>Xb@~WV%gD5n&Xpiz&U>w+WzIL<&vo5G$c0_mcpip2R+ZY> zJdNYE+SMYvI!0^3#l0>R*;nYn$kZZB#iTT(bel1a^1OkzcxmFsLDsk z0jQ$7D*(zc(2!6-wb!eMDHAIf1C3+6DD*5@Bg-@fKxEuBasK)u7cJLhKP|J{ zJaP(6M__O-k}gWp5cVE{L}d%v8k(T69h5E_=A1+8l$w+@rF2*;QA_elYN5YXopxi@ zT8j@zY)1y3aZr%3_pbcUh4Me2K_N?3J9}`_hNgDcvpN_gC#rB-tLoW4&!Z7oj?2PK z@_dWg^FZnt2w|KdE(XH8?(ff@hkXxSJi|Ibx2atsSCvK;ND&~y?i-tAS!!whQ>qg? zWto9wy5c}`Li&d!mA9##dlS_>QaS94(sOvCvOuZ`RL2MHe-#LjO__AunDeXYk z=BQ?`rsuRqGacl4)e=IB`C`?v#4w~v=CrkW@NAb{i=C{(vE#PLB;Ez@Y9IuGsvsn$ z*v8Ont>6_PX+l+Z0M4JMbXI@}uv?;jOOXwctQp1G1~Hv+U{gKIp)_ex2cP(*Z=Od9 zN>ETxaupO5G%rS6V;cnVki9S$wFI#rs=6OwjH7l`uQUA5(Z*pqd5oRS#n##Vw{SJN zDu{v;{#RRr2cqsA`_i5d9&ceM5;IQAv@Sw3$qIoH6fm zsxPC`(zbrjw>xkM@Jdz{?V*5zVzFzyY9EMkejtc9fsTZbJZBYzc^q#WRj)1|&7^%z zw8`Qa7wf=M`W>pNU1Ml_yVJB03~fC&GN<^Lly6p zzC+2?#;+tu|756IORR)^VX;*B5`jJjDckNbka^7u40s*oby%8mU_6-43u$Pcr`f5t z-bK@&R8?72v3%wOSy!7Cc(Fcq&x0WLoqC^5(v0!?8rw%YiT!q*=)W42D&PTBNi~21 z)C>UHxf_2hgXZ25@8*9{Yn4mVX}^ zNy>gFWZe+cCkJ-(CQIs;-FiXP1EM~V+S}?=T`NFO0o724fJ31VlkOg;VmQy z;c1LG5i|Ko%1UEL79516EAJx#W1ugrx&ZsR-3W) zF!w%3-=Tyen_9oZ{y47p9>o~H#9C|2kPryY$eazrIZxV9KQey0d$1w;P8ha za^nHX{(3=nMs4!ZCmc+#yjaLeb4_^Lrd|^D$q#rj1O@s44p7_>6rE0B*d`$o93Qn1 z;Zee0m-8geM`oh*H^u>nm==_h_Xh>F483;A)#q*yl9Kb@cU2ieq_yKJ<_PWjuw`N7 zvD8dV$C>k9{k+F}a5cS-8=??klve(4l4?Q-Uf zw^aDS@~-Ibi2C6XTs(sUD1br_lu+9Zkqu(|gfZ;Kb|JQLx%T7U&*=Mm)5E=c1cDHx zH&hY#ZbJ)2Y#lZNF-@l+gm_{097uveg-uRLK>;@~^ltgn$!hkVy?XR*bFqgKK}^eB zzF7KD+^R2xbHZDHjv;;ip&kkfprn;1s3VTp&SkAyUO3KP1aWcwaUc)7&rS2{N3Ol& zD}`l|QSemjF&s1|QyAB?v)>46nodUv;#p%h*1+*Vx}iW4NpLRCy?67OQ&1#=K5P#Y z3XiIGasW+2dlvoT7b;wBzxzG!x8L#M*CpfUH(=VPKOjB4W9tJ^4_aQmS4;kMDa|YB z3s7=AoClNlD0bqP@}cPNP2aUPW_aJhu!EgUL7ML5@LwN z>4mHAkH_~Un5;c2qH!3j*6=c?U?DrhzG`6CC5IwPC!d)Iv2aY{!8#@31wzPOxvp#9 z3qpcg-&OicD+>}*w*Pnt(oG-JsyZP-H>@uz_2r&;V+w5cv;Y<>F%!Yb6Ob06u z#yDyp1PN(Oj_5iB@Vw!E6EA$8_Tp%Be!w))`KxSFmiCxkKlZ8Z?3v$H z`2I<6MU_=m1?pU$1XbhPfMW{jUR9QaB*EiNpSE#6B^+JNWcomGGVKtGE(!*y8@L>#q7jYXsyO|zVH3JC{j51xRK z5q>tjD6OY$d@9MZNb&S}rim^e_}fM1J{eJO+Sc2`w>P+CQNfeH1Y$rCVjBkYK*aLJ zS4Lb8d97|f%zx}&sb+)D3_GF(dxDOT13R1DfT01y%{!)(^OjE~nfs_tpJzI$p#1H2d-sBEeP-(oQE!X-{sz~V;%@~g{3gv3 ziMaYD72UQ8L3JP8p{aPAkIj6W9BS>IJ~MkjeWlAp$l+j~5nB_Son4Goyn-s;XX}ox zsX|l`9imL6nC_{1>`xbi8iZpeLtO`eA2R6j*1P=y|7DSP4R48jYA@Gr{_VR5OgEi5 z!=%=Y`pEL6@Zz`p6MaL1Fyn)MUDv-Km{`9&uGA{whuDr|I~)- z!mEb6CWbqOuWz=0!1Pt$zU>T2NWIhT_WSLu+bqxj#wY!s>xoZKyOI2hwG~Zc2t~g)E~cp;cvQ_El#?TU@lEWf+$1v#T-V z`0V<+$q41q7*VfdD8;fYoX3d!8Xj#U@bwu|>=hha92_=<%`7#?E&fCx&0+XO*`2oZcAh>QbchKv)5+|U51Do~RY9FRat z;c0fi63vDk-wsY=cIbO28I7q3TEy8N9vYZqr>x;HrB1sN*)4~%2#t@-e z=)=JU`T!A#4QmMwRz%#e@4}d2a!WDe`+%+qo$DJ8e`=e^GEK-3k(5iu6f!+_bNe=vh6r5f=`1lq?BK&IRJMY$T*SfI=t8b+v}W9ZK#J^w@> zq8o$D3>)vgl9HyHP-_NdMM0Gn8Z`4JN$oJJ$JKoC`G=dtI+Ls8g_Nzwg8QzXiniDG zLb>lJrFm&V5tgrz@TSyHFb<3zk+{PJrDIK20ZqOK44DH` z>xo=nNWMka_9U$*ay8E5<+N~sBvriG zV}Aby?@kGFClQE#DSTg5N~uOwfdvHx1vDihq`o#OA zaT6huB2b;u5aA#|1R_9WjB~>!B0yUF5pHJKGptE!Rg!{HoN1XNgbBoSV87hTlHMLW zQX9!2So)&6kK2SG!msVzdH28=Kmi@@4FOW9Q9u<^A4bfjEpjBQqjX6UNviXTB(JIN zmauEtMNa!DVX5Z4sgYP!5FtW}I3lqEhxI zkVf=?6~BkvqU~#%wUOfi_poQ3Yugi9B&Qvz*^^O{DCybzEgga+;YnX-7(+~#H4%sl zO@v+1Cy1Ga6j|EE;E;sy7%%yTZZ55~Y%3*8QkG7;CEbc?%gb9Xw)1GYWhp0Vg>@#4 zw$koCF)i9#Q}`>rc_yw($MaJEE&4x;y3?wctol;a>fgR~0M04dW}yOAl!ddbNgAhh zW}UN2Bz2C(YK{jS58LW2qqMw8TEFjNae^%0!hDI8g^*VEriDJc=mU|skQnC>*<)${ zPd9u7!n%=|NebW9{4c(9mFd%daJnQ-iTn+$x+wCV$P2dpDO=C|u2LVruTR=m*OvOH z_UgK(UfrhPSG@0bStW_29cJzwAW0--l_UwtJq{$CO!iX9Qk_T^Q6go<<4+u1Z6XUP zLLVaE*JGdGbEzf&!AhhJSxIuDN^QMs45AU^=fE@F+Ar@v>EA73Hf`UU6q?O!4YUz?%Pe^jax%3L%PIY8pjqpZOmYKdi*nj2?jUE$qS@=|% z^TJEgye9Rgv_25^)sOVy-O_S!*2P-}D`?VG=VTqpZRI7|>_?K^VkME=oXV&jw!}i) zYqzC}R5C1t1tPcz{-G}Jm*CG8>7DshB+5n#CX>9R4h;npRZ%@@lUwVid8U8+#jWSx z<`cG;_k3u#M_-iIQxZ?x)^idsih9@btuXg4*~#?uGvSmdQ$%4qz8oD z8^pKJsLnmy!<%MeLr6+eYPYJ!yk#|Rk!kA&R*JoxkT5n*aJ2T~*^J|D(TnnAP9(|8^=d!bA2+PV&+s!yHMQEM@Mj+6|C`@w z6VdN>wGlr$hr&l^zx(w6{tG_k>~~jkZ&dLA58-`iNdMy>{k=Z=(e+C9b6)$l8`z&0 zY2`=$p5L?OKlEAu%%J9HwO?uz^`RP{H?V%S{(k>WRo_^(U+R(Z_Xet)L-n`*;vv2_ z`2E%Yp3Ncs&i~CY)9>s@knk&>1N?N^&p1nPRqiUht8l|~AOAi7yN~|b>lN$}_O+q( zKyQ#LA)RqDPkA^ literal 0 HcmV?d00001 diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..1dc6cf7 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..62730f9 --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,616 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.gwid.app.gwid; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..e3773d4 --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..6266644 --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import Flutter +import UIKit + +@main +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d0d98aa --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1 @@ +{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}} \ No newline at end of file diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..b347daed6e37544767fef8e9dafec117b549f1e1 GIT binary patch literal 544354 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 z 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 yK0Ve~$UrUO z#>J3Qjv4?#tjhSH$%{2`M;2BD6idvQM6O*z-ZgY4iD81Le>GUE^j>m;%rYsQpA z*YC9P7Cf-@<@5`U^R=+-^}6{Y`k|`D_+0dQg zFb}b`dp8EDS+WGkGZFwqv3*uHPzjf!v@cheDv3u~3vEr{ihj3c#26I^CS zyo&&#d!fR)=n=Dy*jMzw7|Z+Jk2L61y(}s7Q5AQ<0RunM##`{rqN9|6dX~r*Pe%Xi zX|vZetN+DiU>(&lV#H_1)rlq|9{48~0m6T7MT8R67+or#S>)3!Zz=7El6^$=mU>3?HAE};nKqO? z0VYC?z-fl_2h3l_!m5tF+4aahu0;n+f%U>!*J8a6t`Tg8cmbN-O=%5?D)plF?Yok1 z(2KUT)gJf%-clpv^#|Ie?PWDjPe0Pq#Sg~}l{438OyQnXJp-}sNL!r6GeM9L^=b_^ z*q7$pEg;x`py)K}3cxreR7kZOSzqy!Iu`FnKAX9ro{96rNrtyO9rSr4QeM1xaVYw8 zPdIIW@_$gAXK=>+^@=*jgT8SJZ5{H|GjzRp@jGxC-Fr$u%x@Rv^3u`KCWHt}TC8dr8AOcpUe{${wE&~xx-_T8B`n@U6a4v1i;I4w` zgJ2eWAW)R*+L4;atcjPs7D530cEXHfus_Tw05#ckY1bSW&5 z^Xq7RDA~rap_xSGCAnGwcnMbCTz)^?TL-9wP)%r5HRs*+_>(%o3xL(tzqTWlC$N>a z4-q1kh0iNn?9sm4pq&Gj&$lj6i#T$Z#;WU+Hk*&AoBJ>0WyUvzI+@2^>r!hrYW&ja zV7fJ94F*%1x(KX?=0cglRW#NYfWpm!%J9EySx(8jDssOU*Z3bOwOr6FO2t8I8zkgX ziq3@;dt;%FV;UE-;hsWWfUl-kr%x0LdD+ zZJBUIPViV3ttM^six2O5ws2InZ9NTX9s^8QRK^$itaOUju8nwX)$GS#Vu5!@$5tpf zxRnX(sa2CghnF6YC8q%OF)CXdVEv(4Rm`CV$WT5#<)SSjW+xHf7meoRCZip?DKVE! z5~}i*62an|z2>vuFX&|FK;Tt5 zhm|{7{qqGZiS_Yc4tn1Ov77Kmhw234Vxjn0OrB;uuCCAK{QBa>ZjkIxytGkXtypeS zu|;foumM4oTcpgAE%DWS6KgAA*1h)RT92U6h+d;F-lq_E!UzrC5qmF zt3;V=@?BBjZUPI3*dDR#DMIQ>i1ziXZiO8Cpqal_3Bw@%b6n9;S@8+P4q&@xG4r{w zAE0r7+Eegw@{dL_agv?0-3fRR9yHuvJQ7MO5t{+z9ZtS0TP87r^?kV_S=v`i6@Z%I zy_WlIvXZ^j58;>bP(^Z0RMi9uX+22hga}CDP*|rE)Mh@(9JMBqwM!FzsAnwJ7erc= z8F}sM$D^=4yGFF?r}-*0iy{VzeV#~hfHLaa1y|(KZG`(+2>s%2*8x%j#a6bx6)Tu% z7V8P%TQ{Zfk*7sn=l3^hhB^)$s`v0!?e@3%$pvS?C-njE#>-XkErJ*Ita~)-CLCR9 zC#1hVMPcK}U0CV>Zmu;_+LGN_9jC}=sRBTL9;*>-QA2G`JIE<~JE`@feXF3s82Z`v zPoSn`fBTe6!Y%ko#eZ>QY$24Krx!no$MoY>SR&|Yt3YOA9uEv#n}We)l-KVqC;?U}atbVVrkm{k=SbE)t_~*zT+f*dC z=ya}Ys(9&IET?j4QMX4I-HCl!AIzIhu9T~#uft&{qV|z7SyXfq3Isk2MqAA>axL1JcF*Gd+ z4kjDB8xNJxc zKwe;)z27^vogeB;_r^OlOrTVrg!)> zv==+Efc;;EeWXthgvnv!q`!IW-K~)VF|`XER%V2iT6@{piwA-DPZQ-3qCzfgg$6(^ zH6Dsg)kznD%|g|K6oH5U>-E}5L@E(BOtFU5PhbK{xZMNL z#z7+&{qj0eIaetQ@(BEo4X)FaEmQfTUlM1E`R|0U1DipE|21q+(CnB-7xeefK<(te zBl-{Fn3~u>fK#u-kL(_AqaA_uwR)D7^MNuC0-JDlBmvN>q? z{E0fi%N$=UM`0~CU&Y8q^)})I09lwU7kuQXjIHR-8bV?CH5 z_5&Mj50&&k$6!)El;r#uFUElfIp$xyc=6)Jix=yFa;K45(Or$>|H7T-i!PKjyH5ci zE#}Jf=hE?BqWlMAFtH9F<4@0Kp3F>=91a^RM@7 zW4e0Py`OC>{z^Qfd)@(0XKgR`qd8QP5Xw4$xAI4%AlBcJ{T6RB(M-?ZtzJn}N!r|R!R$yWU2*zDr@ z?Y0iS)PHyl4Q6n^mbxEBi}CXXe6b4cl|t1x)f28x>Us#9E&>C+ofZovW-~Tce<}Xv zRR8>TTMBGEP8*=s;+8E{BZ_WH?=*g+6fahx-LVPsLKSb734nZWL{a4LlBqtTTQ?ztXv;O_Gp(E+wpp`e*u4` z6*rdidDXL$wb@-@*Rsts2sk>A73otmnTK`P7Y9Oilgo#18+}H*aREv_Kw6G+;fmTR z1)xJ2mZolijr>5Yrz%#|OjZzDG2hVENv@RF^P(P|kc>hiE{BPQ!uW0CyGXdKxhRjO;gIdqcRqQ3O3SsfJeEDJ_4(VgZHQ0^1LW2~`jM|<2acHr- zo>55$-F5bHAI9Hc>^DnOSLm%EUNGoL%v>*CoCIwCycO(V@6kFX+K z0x&$i*xWn*267SB#YazOG z;UB4otMH`ieG;t-cH!c$VxobLZ_C2Mbsy}d1;yVNFJ3fJlh*rD+(4C;>)yft%`Dc> z2Q!<1eTGD(qJ#?GR{| zX~C+>lz%lwBbS9JdPEPyrhBKse_u+PuFm5SiC9O`B~F_=c#1^NwS*Wa=9yT-q>r*{ z>6Mn{tCcwv=SXkISVHwmTT{k$HFddabR&lN;z!Y&9hUSyIT7^}Tt4pbh>O5{te9-A z6@vi$N~yR}%b%p;qxi>I;MCF}u`58nS5ifAAg4*btGcaj*;anP!#97YB#**hu}&X| zJNMiL4J(|eFNW~In!0lze(~aLkU12m2{iwXX0aBNdjOg#L4!PAG`}Ppv&x6c5Oxi% zQ4%7tg&8oe-=RV!kWUDo4`SR`P|(LqEjdL5puXz1d6lOZt5w(M>=T%7ZHKIZ1kNeU z^;k1_mLZT6E;(-x`~h6jhL?AowFE3oYFSqcjCcoSBP;#3kvdA$vbrb|Dk+%G>rM=z zhn=)8sI3<-j^_AmpRTNwajn3fym}^9DFEn7)b8)i7)_|u2;}8zSz;-z_xTCUca>uD zJd9p{HhOo#M*OY}TpJa~517j(#D{!pM ze+oNu@q_Sb>U5OU23fYcj3vVu>cjnISQZaA_W~mUllZR}wxrK}yRmN$iss|NZZJlg zxD|cpZqCb%cwr6vX;)1u{C#>LfMtE)bxY$ubz5mLfj+4gxGoK*fJ;R8kes z!N*WhCT-;j?FYqY;{u@KU5CVC9aXDnJr{&Z<-X`$OpyZ~P01Cweu{ithgpnH3rx$O zQ=!{|4dV?4Ro|?7SU*~xa7+3Zl^s}Nd1;JE>M!-w({O%}Dp3yHdA`EH3HWWFzc0#jqSt9_^du1EG)@s98pFMbh291I-}Kt+%nU`he7hIIeu z9@bY`(Mm$S(t#_r7$YQuI3^vSwkgeO`ob`;qhPoz48`i892gr1@39EZb0+n`jY-E?!j8mM9a_Cv|a4UQ`qu- zM`poP^DzwWs5xm!40>JnAv;j3-ErY^^%vLTiB0)9g8MkE8Dzrby^OyhEyW1N4^&?a zNF{a^rWAlmY#fxbKB=&rb5b6&9wX;GwCHJkn=FG{Rj+~n z#SL-X@U&9{Rz{d+mTBTh|DM4&<2%riY3*q+G`X zaoXYPmUbl-)lIR!CQCUH%o-s#wv$0rG_pn^yba6dfWqt0Nw_DWlk>EhoajOpqvsm1L+!z!x)W?W%w~z?;Lzpmcz{`9@zHgSU~Nf$4VA z;#G~`S~1nnMy;KhC1gFc0??=#YJV2tyi&E)F18){3nyx8EUNGLU*a^0fQWzy3E_+Q z)iEjl=TM0vgs>TZupj}Qr#$Tyjs+WiPBA5b@`O1z3GuS{$j%AJb25*peMKL~_PKKv zTAdlo23cu@yurYJ7_Km${gA!f~ZSwUn-3K2=YYb zE%fk_%v#ZT@!NP_BmWQ=9Kw;dm;Kl<(L-Pz#4{N8YqW6Gz(35mz7R|sd1A;52S?5mSJeI6-b3)l zh4GdaKSChNLEX^dw2bQI0H=ehKjtA!4CQX=7cXvvw{tFmWQt9%?49acZvuAsx(DOZ zM08#j=$E<`!Wxm%@*iIu*9*2Hc^F9L13g7B5~^A%%*P~yY%Ql!wJUW7*C0knq$$3G5*daZ|6^8%6~eC%IB6KA|rw>&&aZ;*D)t82h)kWR4k1681R^JJ9!K`**q6 zi>pLyd{U=K-h{L$2>s;dO+=+Ru@%JC+qOVW1+c87;*6if6NEhhL(2 z!xLhWcD^P+M2V`)jk?U8(XS>Wn0OH?KK+OCn}xWl6JG6oUYGe_?nAE5pAK5cfz&ae z@jted;j|OL=J_(x7cYJS&mGEHzPr2(qcf8B030=s_0*BRx&VVfe81vaP^i?pw7^bz zDLSf?>CEheSh#Nxfxa@OG(WK|D!BwonD;Rv<)ui{;E7Mxde1_qdPJM3pyGhqRvlyQ z)WW}j{ce@b8DCxFYw~9n^P|W}tF|%@;p`M|4|nc;$C{-PyA_??P=4z^rl3vhSFN_@|1x z$#x&wMqu-n;vykT#;Q28g+C@*k~ho4KvC%l6$<3CSA=gZ(2HSk7y3$9Kprf%GR})! z5&!@o07*naRHf$zStWa6@pi)Bz%G8$5NX{{lmvQAJTRO55dh!|q_zj3jeFdjZ~(?g zJ(Ht9sPbOCcpALnb>@)UluMQW6ng-ag~ue)xbVwM9o0WounByFcC%~im^9Rjr8`2b z=Vd+a`XiMRU_J_i2;?CWXf6Oo)*t|c3PwtgcmY6huSMIuCABbaD6NIpZU2z`JgY9V z`yD)~I$mj~iSPonsobn?9S1a0{3mGw#ejW^5qpf(GmG+|%6swRY4C>EX+v&n z7JfYPjsc}=S>*M%j_a4iza4{z`W&TYN{2$sPUoKUVLphskR~fGBk^+FJlP=trRZ3g zm!<1KdKk?6LxmdK0#v+gp;0fRRn`Ux>7RQ=IL9^Zza~vD>)_~>f<(8hNi8=yill)x zb^8Qt;{@BXaeo|_*-v=)sAGGP27dcG0F{j-RZYBVJq7^K*<92A`we!#K{-p&-{CAT zj>YrY+dv6i>3Bmv=HUux1)%iFx@cQV2Mzx@yk{Nn5uhh-FaK)HYQ!vvJFzN@N%)O- znk38h9w97si@(mZ!Ia{BNb zk6ayk5{4}VUP;kBkn`EZQg;Ll<-HmYZ?IAPG3N5(7(9Qp9AARGNa3Um8~9he86^kZ z$FW3swG99O6+(ZW9*~3hae+-o&5VP=3X_32r(TAur9m8pAYTihxMuL5=o3Y&(rOJ2 z5>^7MKSnSn;-h^r*}3eB004}~sHUV-4t7P5?om>PD9`FbCXtGK?}v5MwAcR+K({}; z0oucvzwN9I-Bo64V@uxXJgL&3H1u~Pn~AD*AUl^X7G-{&2Aep`fqKSh&$kEDZRaJ_ zk5a)?nyrOb`hT$u&mIZ@qsuTn;Am;QT&(5txKcI9aa^8yT^rN}Kzj z<&|ycWja2@{<9QzT>3GN8va{%6y-0KFwY+#7l37baeyH9#Dx-WbAs?Nyp8kX#a;ya z2mlmZT@F|tamZsn+z^~3f1J=h3d26hgrb?fjD}=1 z4N-+TQ$?5*{L5L!Bwx~AaZVVcv7rSaZwoLmN`cV9q@}P3 z*65ivpK8l|_6zxXAQnH%B9I_L?D~l9Hn$M#Bun~ooJ4dto6U6W=bqcEz`C_I)6!ry zcL&)=MSmVgNclV<2y6zGHAQF(=|!(9+(B0viI%vOQ@7bju^jzg%wOo1|HX?Jzl;UL z9UH%DE2J?<4T3 zeW`EXmKfrD;sN5qA71BE)*TjitUD>nD;o1#=Ot(AWz@^1?&L-B5a%iXLi!gkUc9(7 zHhBQ@VhLk%2Y|o~Q68gT2w}pAOThqZ4B-F>@%oq#0Oj*I6H^x95gc}IEH}+LEJY^q zb7;=P*0kgPlw?;fj&__7&HM>ax>5!R7jvH`G%3CC&Jc}=xn zIm=3}nESy@|1?@v&a_u$BxngTMCw9v6NphtYsSbI&q2*rdkc6*f+xZ3p&tQJG-SA3 zjy<{2*pcltISXUah_2?ZIy0@Fy~wM`yfxM--CivHgo1Cdu9BvsGRs?c#lvt-AOD+m z{o+}ub^%Xf#%lQP3}3X5`I4-XZ#PP;txkb!qxe-r zd7Ml`VoomyYJQt`MsXe`cf!lmWeeIiC<(o7-kUY1Ie~_&3p=lzc)Ilva*LK5$LGBg zFYb){YH;%!@V%gK_U#8&_oI8mj2Rk1KFBM7(hryvc%~uzN2EzgOH!r5-qRC0gWgO4 zE`KMKrVSJCx$V3M*YxqfS=TQZkI(>JHnBYYttk&L0V-|T<(}Wf@QbrA$)5WbcJmfG zgyh|XfK+6m9I{%+$PavVFCjZ5002Kh5N!0B4eMPCKQjsQQNM@sH0LJ`qUOA)q<(QM zF|8`=IqLZ~MU4%Ez|(!Q#woR_Nr}ikJyJ9S)+HU+!n(F1=4 zCr(wF-u*GK@F3?oI|!w>#(n_%;cixwyU}w5I{q2Z^g6dK^kh9`OT3h- zMKY94IYJ3=s8ULRJTbEjB7w?f$1yT9z|ge9DN0n3hs3LcND(rm?pL`D+1n^7bEsB= zhvO%^dK14ozAX+e=g-t(r67B!$Jv-8;qO-GIPL*xvCSj^my>~CV63E9s~*XDlf0JL zZs}W4BDq6mXCAE?{>SJu`AM^xn{QhK+SUi>Vl_k8TB?cds_>SWs;QAZKbSu^QoY-N zd@+b%D~*OFRH261()v%QH4}Rb^4p36L@f zQxZxopAW`&06_S1bge^o3_!mB!XaG}q9P}gBpK&KLzOqC_E6^XE~<_(z&Hr*P@J&ONw|Mf)~{)PSt#w{ZJnjNthtI1QDmT2_PO{fV-bqk`Kt>#zr) z28XGJncyRT*#I+kS-qv0V}5l6%2O2En_TYPaPsn3o;+e+8Z$un^P-@uG5f- zwqMD0XSmU2LL*&mY)0HC7NMyr@oV#Fs5(^2s*37jE%O;i)QdYHHZj^~wI3AP>ONK) zc~#4|+1ss9*xs9pQ~t=u?56)vYGP>XSZQeKV;;u-oN1Ywc=ik&$$A27CwR$o*EJMvAaovQmdlRtpo((hgPj&=LdoJ-Kl|sBf zC#3mfu&El;14%`qZ)q^;)+oSCAEsQ~#IzAikA0U!|)XYBdIR8b4S$KUzj40m;fn0=wql zi+b(mB|u)?q@^CgIz;HyT{0m_-KP-c?IEI=4)(#QljVro>OVlE{*-1H1R$0i0}W}0 z`=H_bHN8fjU0H#tF7Yn!y(OTy^HuaKDZ+ZCA|1R-LW@dKm`+Fux2{_QXm}>o6qBs4 zn(44e;G^>kO&#r&b5nZE-mk`f<-XVqX`4oXd>Fj^oCfq>LD2TxYzxXGbA3BkhW0TX zDrGh}%SnPjS3$J=V_26JT7r;Q>SXCZ<%~HN6se`E<|}~#5x((MG~kz&()22;*>uH6 z0@0-)kNbC^zj$#U;88p|FtHAEH0H%o`|=dEM{%6ZOMpuAH%cpfrOJ#kyJ85&%1>AH zM*l;V2x%I`l!94yFHBAJbz0Q1$)lPmMnRQlwsBDUY0k^5C9(k9I$6z}K6ZEK96e16 zYc8XjH(?t!erm5oa4^b&Saz)49S*?n7g+tV3f)|f$Zw{i@Iv<~;z?OcQ+`B)Ot%_)l?2%osI4K;BF%jYa@$Gl~ud@!rV^AYVDJ=?^JWwkHL1 zRfva{`lv_w0m>?luK4OarG$g)BjyV+*DcsWS0w42ow>b4r% z(E(eRFSSh;uV`=pLPN=_rGcfHt=_6y-RD^96?*?10Z+Xj z%Wl?2q?t%&-c=$nO@NWvC!UA$p!Q_Un< zUy!+^XL4gNw(VC@E?qNbx9iazeDjI9xKD{+NGR#QE{U`G|KiixSKw5MZ@Ax+=5EAw zo&w~Pnnf&s!h^_!Wl-60S&kQPq~XYy#3$#M%%6LwQ|z(4ym;~AXi&|ZvoFm-ObIFX zI1+T;1E9$+m~%NLtFTGp?(t|!fzYOqY*EsCzz<0-7&e==T9k zBxA8s3RLzYi>Tmmu+NU(+^7UCPK8|;1p3x3Yr2!sRt&OU8fbqGi$a3t{wOourQTmSA;MT0!J6QGwHOk+DDb%T9*ZjP~w>Yjra1@!;fJlWG-e^P#{d0#l2N zg1&%uuYIJ69lC4|aW(*l+E3fYc&`^`hA3JnP4YR-;9HIKXGg0vz*LrTGLb5M%L>!n z1&|xvs5eVz^DWlQh=-5#7fbPndIQ-38lPLH^O_mS4K++gyV5BMbyzOFz#OI`V$P!z zZHEWI$W}@qudzcMHEc7FHHTm}4uIrUL$WLEM47^%-c}m)0s3u7JPn25-R&ncWYnN6 zZeE1aJ3s)W7jVtuIJR^Pz50guiF!#3zyZL$Kq>_T00czpFk=%1rqoOTcy6su9%mB- zV*=pSk}(w#z{vw39i7Q+n{{lI;o^T$%w{I9`Js@z2>_jg3J4(F7LdIVMKO6kA)cxz zO~^7>p+e-ay7H#Xe#hdez465n_*=a}4nxW>54snyMMf>hz+>du2W>s!7-)8d`z`{L zhrxkbqF|)Ic*;B(tcoTzS9!7nEhK=Lf~pU=N1AWwMDW8tM8cP zNQ$P7YP-3{3o5@1(DOV@FD8vs7jT72%X@gREKeHBL+FoZ9z$UN3qj)Bk;e*wU+koU zz-dU_K9&V|A*q|zlxIlgXXT9WjUR!j@yCyu6@;~^P$EvpQ#<4#*fM+m6s|7)EgIl@ z3K&u@g(hVO6D^JCJ3Igg!B46UGwGW@k8TzqNRwTB0T!bRBl-%E_?w=P5alG}(l?R4 z+-<(Co@%FS^URdBH9>5lyp-v3Dn;TvCj)>yR22YPXK`#q^L&pL>8A%P{X?hgR{G`- z;WRsEw<-zf8^f5}`skZd0HE*K4SIhDbq?B(2zsE4-zjCy@C|z~y~d$|dslK6C_WY% zG!-Cwfu!^w5-5EQWskMID+kNL#q@z_UxKKUyo;<%QijK16+)>!qiCVf|67?6E`f7U;fp|`72h<*0N z&ty54CICu$WAA{-AIIh{s=7Z9zr^m85UgWW%^^~G@cI=6cL7Cal0WkDez9AZvyKf7 zNW4j`q`+-`@;_2e(-a_=uFU7J_OE;4G<(Gh9~U)1MFP7GQ1P0=1aUt0EdfflnzZeX z#5r=}py=dsCBec|AScNbI`j2($ySBADp^;|26bUEJ1nwMyaVauNGoPg>HunXLm8ge zp^=;zb;cry3S4IHKp5Ik2dqR^DS)VI8#lVx8^SS(NU9nGe|Kq z{>%Rq^mL0}~)X~b;j?$ml$98EA1*K#6F`!Be;uZT+`ptTP&b?ZEp$<_p2aQ+N z*p%kR7(;2s8Vc`c)*y1LGRtS@nRskDlT)44e0cJcm#VT`z!mKElihPEX6r>mXzSvr z5!8xV%dx1yUtoB5gs#`tO)Hg6zdvv!=r+i5OG9-SM;n|W(cqmfM`vld2{*nhKwIQ$mV#iK{Q?>J8Ditxr^A{0($p)}zVEk?W(u)^Aie-}rb0-8xJUa`9 zN3OXCfC}DOKZc0g82$TKSCMO7p#Yx5II>`K)P|!p6BTBkq5yy zZ|Lz)M5+U4SzJ#(`BD=s>rLmTGlI+|vLVMP8<_&JY9F0(Bw|rGhAbNl5=jJK67GwN zC%9@5ni8%Ewl4?PW=MD4QHWYBLCWGBf{;h~B)~hZE71 zI4Pv`jcQh{hPk$};`ko8rbqdcw~|_eVD9krP6H<+dZOChrlQwXHl;jH`X5DF)`(wn zxFUl&^td`M%?jyn7RP<t$KYmtaL*n9x%e_$Ps>n_vE4sR6GeEVQ5f?PTV=z;w~)E3)oiUlvkf8_ ze}6s{Z_y%9GOxB#iisfw#B`OJu0s^tB;>huUF9d7z^RU8rCf)=EBKk1dV(rnAa_YM zrh15aLdqBQ=DZjkb1Z;(*tfdMtvPYpp5<5(N5Fj${afPFTU3=7ANZWsm(^8DWix&WijuDSo*7F# z!;{1(`leGm<4{)=8qO_p5$~9C;6p-XBE>lxb)GFo!GDEk^>j zB-(I7#meS4QW5E!^oSh)A9l^OXzAxr`K7MwL2kOX=LA zvAnR5ZXk2+q>?~&*gpj}#Bf)4c?iqfvU}_AS?^Z7B?U(P%)CKwjIpgE(OUi~sMlIE4+qkp3ggWMOJ1Mf&r@Q)a*pj-TYHH(iBeg%KSfO2-Ya zxk~gsX>94rM5bAjx4H=dU87qSvH*of5fkUBIxO>NDXp+FDg|hEww!J?Op*9OH3X&Y z4!KtO6eqn<0TJK}AWl;iJ>T|J*~MNRU>gurXU@AnQ-Ca$=Dr6YF08$YD0U7~<-`lJ z+_Gbmn^7p|0EQFgglr=E>>Cb{%^@-ot!$@JfOgyf3;3B5-$tSRKWz&U8c*z8XV8j< zoU>x39egJ7ZcLWGqiC)Te?($AA3T53N+AoRAS@%+U16Y+e=XIA)=oK>hC;!L6WGuO&D&+6hSZnFab zz)x-dB4h7U!d6wCli{T_okA6b_-2iyU;V^^OEF~trn0~0JVCJZie9V@&AQ(G$|!!a zY(wcl)E5?{|4Xmfdt??3Qj#LYctME1MPfyCOhTjJ{P_(~cD(88Ob80B5n{hzCD>D9 z<|tTAINksdkksv1`N)MYfF4MgS~0Uh7akw1H3-wz`l=|PqHDEbClyMJvvs;eFToA{ zYkpFC5QgUG-!1-M!8MI|vl&)a!p$_UC8q%KMB5O~vgo#>_^!-bK}9cE25n)~l%>fg z8l1yHM%lcqY)2^m8w3@9`8`jKA52*R0805go7sAkQq)vPyr>`+G)&vyGQ2SDnKo=Q z2$^*eY>u%guL_FdJ5sz92Zg1QJ9)jSva%%lfK@igX}iA;NBu(3qs)=!MO$DHOXvA( z(B$uJ%$)!qEdT{$F+~h(^h4NBkoAR(ZpN3OXv5x+P3!?bdiDH03X-M0_nO5fZ?sFrb!H#i>2n zs$?S=7jvH1P#i*7*%#MF6m_*ig}Zj(?s{9=M$Avidu zQn>;AZNz?3h18Pjit;Mv7XaW^MQV8?QwsZYu?c&qMm0a^ZacI?4`oi*t8uyaXGW9+ z=u+QKtT^{^6up#tB@)m_7ZKB^FwlwL5PeyPqQDN-a8my;$-K2*iTgR!H>J<KbQ?K`3X8}Ll_utvgpX4zjToZ5&dO4dy{^92YC zX*28*lr-M#y$Lv_>TuygN;>R{&YESYd*aQS+(ERknz4=oPuQ3yPPYc6A)RU)!CLpAaX($O&Cp^?e*0n6L3GsT_@$TSCQi8rXTfgix)4(FgQWA6@USz7x}JxtmkIz=eLv%#uU$twjov>HZeRM|*;@n~;<`b{(nEER0b9dZ;!tF)sRgxKJ* z=__jV>1bq|$A=0;HWY?EIlLzHqbk9g5>gtN2WA`@Ul`EINE-jM0mVAj*!Y0y++AA? zT^tq%+y2fU>_5HAZJMl3>Bynuwmxw zC7q1oK@J$w0L#sm2C9%>TxITUnV%#b2F3j>-<^dAM zD$pI6KW(B=U0FDy(6>$yiXqC_c8(EeCd;awH3SqnyAFp(4dC<5(vPa1mH4v-pT{Gs zDl*Bs3xKyEtvCI5Qk2pTr9Vqf0h&XaQfek%{!`+kzm)QujzfC{?*ITG07*naRObt} zo}I=er#!0Kr)mVrLR>c`mCyCl3Crmmi<&8WUMjwvv3l-$zCR$D*Cd4m@Re)+)1PRF z6Ay`2xr{rj5STM72va2ymC>%qNL2oZmm3j?)^R4I6XuL5XOtL@<<3wSGN2O-~_fR`LjhSn9*2szFnj@i5KROdoOhbOr#E6ewaZYjdD*xgwg)S*HVU_`>Ya#WGgoCwYMbdh z5z5(f+JdI5X6e)OwYFKUK!#42l{(#m-d69$pzc_ng;&E%YMt*x05yC7g!awP#xm|& zS|lfyjD$@PQo%>;_gm@DEc5N5;0WrGEf7LiZ*tW7D7|p_y?8X zonB^n2~f0N^1n`ESUl&?C}s&on46yaCVfDle572FY&Myu6Jf-BoX@`_0LZIftsb;x zvA!e%i#KBl=nExfx~bpT>M9rf$eIZ|kQL%XC1s%EQwEo=~`@~;T{{a=9J%^R!B0CVAvza(SSpxrB(4pGw6}(<+ zja*osVWDGU1mmYoQmV=0Y}h}8tRAxx+pjdyng80DVxldD;A2)$mhg~Yx>4=nu{FJ8R(gAo2ROJMAGMBF!_B}o0 zNjno?QI$T~LX_!gQ8(0!HmA#Q`6Zv4SM5d!kWF_a%bv`fpS+6SsS1-+JbgVhxGZ1@ zotKkk;eg1T+Jk8h_E#q(d(uujZ1+X?pWb!$ciRCxmzvF(w?vb!Ofuwy+x;Pxu-654r3d(fAx>Ah#&386)=t zsRt&upD5?7v*RJ>)NLf+F!f6R$KmfVz+0m|@LmL%^YBsrgOL+D;`sqJ%l?OwH%aEc ze-8i_4~c@3rs8G2;Da`mN*J@+liMU)mz{|7T)fe4J&~e;G0S!(Q~4jiE^O^$=c+e* z7tMHVlufD6%@`IN^OKx@KAZ=mA z_!6gU1?GxeOaPq1gL6i&}QaP9UL*8-3`BsL5xJE$F z4>jq(T`=#xYiRiJwkYwHB&msSl+o=je|sJEix)qJKg=SOd6 z(7O7E*~sa~EROu7$TD;E#CU~G2Bj%f%d)lEJ=m24Q)jD{@8zdFfr-gZscU83$=S{e zLaLmpd}filW8u>G-$cDl5+Ucv98Fv7bSZ*0J2nSNn$Rg^r4Tcx}wZ-=)ULbkfgW34J%3=J|L11)72SAKta3a z6AW9b2I*x^$tb$)vby`jlhWjXs?~!OJt6T26fI^W>faPQTxqqbL>e?qG}G7+vveiS z6SWg{z6^=!2lagkNQW**Lr#d4>P>o zY%4OUaX$+Gd({&-Q-t;$plVd<;Z@RhESy&z~>3$Q89bnG z_?wdmCL(0F5XBONw{1IHE%#(OjX#AoPu%CO zqfj>8R+IJEd`$?5O_o@A!`jqEMTwwV0PM|#m3ca+sw8kS0Vq1}~z9W9`Z+#i!2<9pQyeZa~FlHY!P7E5>Xlm!FfYvZ5VtS@@2}1)uEi0RIm6G zF9edx*`JpzLIuc$J!bbgX@<(qs92>n18odUX)C9%1DIXud_=)%OS425JTA+Y{RAnG zR%u7TY*f#a03XPYIz?*@;8IN~{hC?kU!Jy(>R$vMTNhZR-h zxeTeQxpd)E%jP{WG8-&HZh^=Ie9E0@nXRgA`M?&Wuz7R7dOUgZuR0k~x z%jm>O)-}PydFGJfoXLr2@tVM7WzPNRc9?-4rPk7hTNCfJO?Q}~$8?qP%X#)=iI9byt!7H)TS${; zY8o{sWl0i*j$>q)EZJZ@$1h7dDyI~=IyEB+DK>tI6-cg*<<;w9gTPn;bL%JXh}%Sk z;F(gw)G1NcRji+nh&WTEm?i>Jx zoqc2jchDin!rig=4K4v{qvJoWM+0!Gue`Xo0XCpw{wY_wJJFqWERO?1JXt%+D8wCB z7GDn%XV1BmedXuz&i^1#QLa=$u9&ETaSAdb6bX{8NS_Sw7N(>5_eDZ#rd-p^a8PrR zQq~{q#_VJ;ZD-Gj#G-u*{q1i-G!1%Im%3h7!?gaJSKl>N!51%Hym+BumjK};2UWJ? zxp-6vRwT{O^|`yRZxE!rZ{wUKR02CW=@R!-)0 z<0HbS*hehg6PULziYK7tInamlBr>Jpvj+?y!ke8~-#?fm)r)D-&m ztFWwN0~#kFZ%@H!ew8)^dqkSHwhE4#ByCqDPA{({8?J|3?OEUTDohJj}~ z2R~2OTADh_9x$2EF}N3d7{{z|u_xAT5gF92+VF1l48acl#mPUfLOgU!F}w$$%`F92 zAL&fZ#zJ86s2ZSlx_**h#V=vEO)1vsn{D&`Ha`;cB#Ym!{VZR%$@eDsG*zkMO?b$u zL>Gc;vNnSnF>l`nxu61C+7lb{5nHF?Cb^vQQD3MM%vtuT$giZNuH9_5D~UZ@2XMbS zr-7mE#p)9Xy_y5n!dECLqn>8<@9r``dF17d8Dj3O*g4WUOX+o?0yykuOzBKtjHh=+ zT}-BNUiIIL#lF~pw+Ua|1^)oXWR8|IclyfGlD#Vdplw<9Aj=sq%<6)&h|-7RU$QZQr`%2r!B*`i>Zg1CU&@jX81!-)4=+mI|!5v z{xau+74d5uJL^wM2eV_dS*p}{VrNJv#xN$+IJN3;z!P5VK;J}kKJG@(i?a|-o|Tzs z%nW0boC(w7*;O-i5`z6D{wcj^`i+*eY%8*vjd(1k(V2@}wI$D}!i6D!ndC^OBK}HI zJQtgV9{}M}FCQGba!SNgceBcR^+}NJ?nUm4K%w@KHwMO>w1*^DY@#QULN-cnQL@oJ z^JB*%>6VshvkKZ;j92y{L!+7%l(`{maB3AuXfJg;b-PzmS(e@Xtw;c);xtt2v zmHi-)a3bp3)#R8FBY~P7Z(;&Q`tO8IBmEeGXGOv%4!IZi!rSyOPDlG9FswYQ6zs2& zPCVbyjUb$69(nwwH9})P_dT17T(kZ9`Jgo?^Vu)H4H(5@T2#RZI)*?F%*RvaxWO__ z1VDU4m{K)b7EBbR49G46_4)lWRd59Fixo_wwzV1%AJ{43^(d#pxk}kTV71T?6N^_d zR->G}`rqis;C9;0m`ds_+YlCiAr9iO)H_!IrhP58924atgmM@5B&yksq`OpRU#d-v z<|(vdGO};7yogH_jAMr5$)B*LLZqHC82m^nYem|xIrh)uZTc6dg5clUUWX13RDz{p z{Z$J-nY2ti#{(*9))J)yiLfadH*_6tVhqM6UuM49msjg z;bc7~H-x!M$0avJ33GcXw0fj+Lms^TC!abfC3S|BCUYFhpG?On*2jVfK4EzlLhPqJQZSwkq)0&?Wrp+A>&=wan_&PT-^|sZ)_EGr za}ZCL{!i^XFDzc^|3=t1mE8e@<9O3WU?y!P+t0=J<0$)>Yp|CF>qfqX442yBCbHQQlAAn9}%lzOjgd zBLGz{#qr9KjP*4uBoUwxX5FSJ40g^beKYV4;wI~CiuA<74dP!{e^AIhfT%pm{~m02aWOC9>pyjx~pbM*84JGhs5;YaX%Q}SQM5pA~K z`nfm76&?VM1qG}nq3zg1)HG5nQ)rsnH$o=JD@icjD1>JEYESw>xWU3ATFKG-g6&L- z{L(ZlUPn1h?^t!~?HIP_+reuMCo6b`<+ll{Jck!@wUj=7G+RYASa{`~34B+;-vOJJ z?fXJ5_s@%$32o~Eu3EktBcbd6QOimp0dJ;qS{iA)`DZNmp_T3a1soVUw|(G zUsWb8XezFIqCbjYp3cBm%o1Prr9^bz6Prozs67bq$DG*N=nzax$QHec*n<_>9&H|Hgj$|D@S%i`0h|a!|QCC9jYdhn$}Pw^OrUIH+(>__Xti&|K+-WjGaPe+a%Faq$|1Z{I=5FL0lPc z^dh5|s_f?pvdy7jFMT$GrJ*b601$>>ZYjuQbys~}?4hdifDSNHyb6IX)j1rFFF;%a zu#MV10YTdGvdvsPnzW9Z0+dY!evVJ&S%6XqK8~$YegY9Zg!c zsK`lEewsB~G4FX}8AGi>WPAS`H0xW{Y>54eY6+LII;*^`ARWQrEPSy9-J*slcd>>r zuNo(@jfU2hIqV+5p0;tQR?_BIDUoDGOg~$iE zd#scNG3=0!)PC8^L&Gp%?~$w0B6Oel?&38xuihja4u@k|AX@}HBDrf58w>sHAJ{8K z=f<>_rVs)_@4!?`DTfbB!jRwN-AzizWSzChQo@C{H!`v}lUNep5wg|a&;%;X2*LLV zarJPP8jwwv!7Y0b=VWlr_1hcpWX@Yv6AXQ zO^UiWb+%-UN*SyvP05++X5D?DXfelf*wa7w7@KZxLsQN*jY%a9@ttfsIZy@13i$*s z?miBOqk^yMdwsJ(`yjA-+LQuXLQWiZ?#$&07;GYuS8LbSo|c6^X2di|HCle(qkKWn#n0*BTqL z|J2QsDevN#RNT&v7l#i;_VAwXw?^XKZT@?(YNru+1(6QN7vg*RUSCPDvJGel;*c&6 zqKc6Y%-o~)wx|=DSBY^K1B%(EPh?9La15~*AHctT*E+K<>Ng7$IRL~Jfmsa3ls&~# zkVpoK!YEP@0T4svPFm56@?8WVM8a(~F@(RkX=W+y=vjcclP9w%3-`Rq3n1hhfMV9Z zNEQ}Ke~@Iy@iPM&)ah61D4iPw_?PUDU?06!hw=>Y6RFGwSG zI1~(-zM973OcUlFgt;SC2p~}7&=Fv!I3`hAWm@0f=1sd;0{JQy5_C4u=AzyOmq$;*J%J5XXBa3Z#I@vek=L+m_4C3)| zVG03gkE$An)&Ml2<_I+JZuh7F{^iACU*oj-Xx;6V{st8}zOOb-*qjwujdhb`@xo za+qi(7krcQ1`LEEHi+Q&VbQK!ME{f&_L+3iZ3E;Z5Tf3J@ijgRVq$BQ7yrV6VgSJhkS)h)2>~lVgbfmd zw>_nYf^1gCkgd6gqBaKBo0x1FLy%Q#F}zzM%_U4_=BZy9evlhes?)f0QC^2|AW_xB z4*OYp^K*>gR87dPHi7pY)L`RRnTooMi(JythWh(_pKVR19bLlIqg99<@|&#--Eclq7Z-1GJKtO;zbVX=CBq@#3y>cFGUI`-BkYt!S zrof{(q1&bH7Fwrl+yU9UGG{7I@i_X&HHU=k=KbisK?s82W#(n!J5piJnqR#O%cJI-1HbCWS!hsAfvZ z!RC$-iVNAaZe};k3^5G*pyZltYfty~c#v(=Gy2$8L~5Gp$MT`$Qphk0k}+y_D9$e! z5hSg_;D;xSM+^Pk93RuITD(YcZUEX0W6lSqsb;O+BTJZd;n z=pp2?_An9xRIEj-z8GIoG9!gl0E@G;1lY!j;%7kXL24})vB29aHh-|Sf&-Hy76P9ha(H+xZZ zODkosZQ8G4aA{N{vSHpD7i_L~wCeXX`T4Nfv)WM5C2V{xURUbXn$MS^&e$`IuX_N> zakX1oLYc0zM`IF4EBQ#Nk5n!{Kl^G!9SUbq_!zNiAR{*_*_3 zCWZb*yHDEn%@TNnJ)GrG(``Z`mJU#zGh0)QsVXpIHp)p^8=neOSG>@RpYv+nY+O&) z^bqKu^ACOkChn(=V$=?z;ie(FhuurX8D11!C|f3x$#GLA!9i{&=W13wxhm%$w;a_J zbciu}Pf^?2Pu63p6}A!f*({W~g5nMYDD)Mn3%h62ZW@aFRnOvZPbkLGOyTB&|6Hz%X_-gg)$4E|h~r7rpnw#1xp zi(?r7Ybho5q{C0+tgdaEBufd28vuPkg1=UpdF4Y1?kka=nRbbJFywqmGPGj}cd(T1h(sb8T5GZJk5us4YwRkm?KO@+5^N=e^zd0Q`weOJ1>HdqRRwoSevVhvdsB zF%V&5fvP^PE;P_kABino zZh<(bsQ!i6GPTm8cQZQ&rQ2#sCmj3xLgA73F&p#5HSKi~DG&Kx`WQ`dfMFY2wd+_6 zUT9o(W;z4inIgs&LBuBoHb&$(^RvyHiHu;oDTt#Ehf1c$@v1Z83%vph={VoVT!&*t z^mqDE4}cQgw|f;yn>}n0bY_6+k_sF0XB5O+C)E@g1;JRQY9wH(M46sV>fZzc#3bkw zTOxtYF%zSQAm0%Ne@PgVjnf19rSKVOi#`?UCrKKjaFbYo`Tj{9@#Q3{YH1cm$E9Ya zrHHu=R?EF7xBf?S@*FZfi*Cgez`Z26_J0cf^yZNs5%Dh$C_#w_h*5*QOu>ADY#8A^ zl%kK36=k$!sIK$CWOCMVC7i_$$2!0f1wadhmJKzF%vhPEc87pyLlSpLJ#K$oA^H?0Eztv zX8pUcuQHiv*C!67+tV_P#8e#A)#xeCs#OdCBOTEC7%{Aox9le=U5s4HHuK`mp=^(R zRwCN%`496AsRJPLxF0pTlNu$E?NyNOYzd~pD#aIt!Igh*5G97&f?TS+yMw_Ff2!Tw zi$=+sg?>>H9S(=UltsWvS@&rv|x!@QSVK4Z&J4vKF{ zy%>Hc!#pcUbO3}KTKWeFLRvHy*7w5ewvY!~n)$vmd`eplGR;PbktC#l?njt{DR#_@ z=cY>p*X~3+3ukI{j$6RQP2BT7s6oqm`AJc$&k+ES8kki8WEZ8WA|z4{Kb6$(#~=wW z5{(Zr_eJG%I2-~)i-03234~#k&nrgvM+4^S%`*X)#A#bKYYFEAP5?$K73srfmCJIj zop6|tgP)*y`~d=lzp#WClO!x%0UU^6Tf zpnn|d=IcD^KN5G71%21p)p)vB=zCh_!j51^7Y_Q%FT*H3tI^*=XKy*=0YLFb8jDS{ z6`I%eVMEF5*~olkq)~fTid+WLL+c{jzDY{xb<;JaF9V;DeL}^%IKS1|cC=F4Vm^~} zM@fx}7e*0&5Y7PyLss=+XV=Rw!bl;v1yyQbDHHH+<#0G0Gco5J04YkBBlTt$XZQb< z;l@xHOk6yA@X55@J!h3-jeIiH%^k-;snBRmgSeF+;W+my3TqTQRHn1r41sI@b%+_1b z-CGb_33F^1sjpknK?x=+Nd2?atBH4jb=m}pF{B&O3V_n$Uv5sOOS+92C=E2pqgbAZ zM&b3%aZo!LgkqE>H?ee~yTOgNOin>$vTW>^wSYyM)(O171O?U^*>1r)Bix2jdRC*q zg-%g<(m`PMR-5dcmmKm^qfI0yN!@wB@tA7w49*4Emz354_)A+HfZBdOYbJ$dJvFwT zZS+N=@~R{?WwlBFXdTCcYO1mlMYBH1*XtDW>#zcA57MBz1MxrR zFcf>`^Eg6-{>C&1soxa8=qHv6?9(F|-BF^B0iru|fnIK|Q1g!KvBH?<_#K$- z?O$)KP-hNyQiTa8-mSo#GY?QHOyS5)MZ_N))KPK?u&G1M-C21Glh18B7mZ+BNJC<$ez~DEpA|93#@?qQTDRxB*l8o zWWS9Y2LHpoW;rZUhIT8mTXFD-G0op@B+4L;;_$tjQ06z5eRb?Nell(m)1|_n!6L(&<40h&w{6Mk$%IoBOh<-eu%aw_ zzThN;70S`~oZqaht4$vk%hEQ5PD#JU4;ju!8}}0lz&O^bo6!N1*P_w~ zFyACrgf|bt=UdHT%wpThl9Ab!^i5uXc1e&q&4TZZ(!aO2!yED|*b$68%pqXaze(BT zMk2JX?zB&-PH!G)z7!9SJj)Jzj&H=jNexa3amAn*&0qiogxHet`uwStyj83Vx9Nx( zbw{T#lHwE8CoXft!h@|T6QXlmj~iB|5qD>Yf@d8dhYhr24;u6vzj&OFdYu@-Ibz{c z%a$mbDv`aP$wmOR9pXNbx%O)x;izDgy)ZG|qyzjZWs9~t->QRec$&5~Om7cY#!W!; z^4i>l;q>k38yI?T_98_JZSAm!h-tVrvp(d#F>T`L1BiU7aSyu6dCc?jI_ZDa;p=fM z!ICA2aC`@Ly81Z}fNhpRHNDE8?OM(T)w1nFd7Zk`Si!zRt6GhT8!2y$9;)$%C_iPk{Ayc~9y$OX6{XBT+ucDfp{Yhx zDEI~ZOhFxQ!|fC3mt%*SGqwTkx7w<$_aO_H))xoOJn5Ui`14SMI@tWnDBe}yr z^Chg)_&Fu1`Vh;d(|N1yBpj6y%mbU5PC~U|1wkL#e|w)w!8)JY(3xd}$XOQO*P4y{ zaCz|>{VoZkJk}{|i`qeUoYW<@{)8)-Ery5M~y+6EOueU|66$*c&l+l_zAJV_8b0?!M9c^0HC3{2RjtmY2*=kUAGp zn^dbuBY@HT9-VPS2?Qm?{_9Vv=Y6JGk>*F`>}0fm*v#Lj;hFB^xB|-vY|9XGHD(rc zy`H!jIi2XNlM^0*-DB-*MsVR{PcLyJQ55=vu~wC3w?ZaaXOANhuUfM-;4xu9JG znU8ylrYFp5)tToRbHbGl!08t%9~LJb_fflJE$qf7Olyu2H~b?2kvzGfK~`BuC)*TJ zP=G0Q27J-1aYp)Ivy>I_k-4*&*5S{6G$8xa80^WqSz)T< zH!-Er9yW?vDSbQE8L%$G7Z)w80XRHlmeK#6$lCy!(ic(;lEEx;_9k8ZaUV)qo+>Z! zEpzq+Q51jF-66v2UIQ)tBUd_7RyiJ?@*603O%i42M&3Pw35M(3NQ5NmDeH0*P=v1B zA`6mQ*QYl$5rlu_XFg1c1G%N$AFHA{oVx&p9iH?xqSZ8`l{;w&h~~i9Vi$_;u?~Oq zU`plPI!IjZ^y!{7tLFX656ACeO2?Vh`xfcM7h|ab>k52v(SV9=K!=9-eqkjwk(9pn z0EG8YybV#ZjG|mHE9dWRdJ8G}*RqCArrBlSX<*Et7CFMo`3&(D0#?3Eq6 zf?99<1>-UCzED@Hhq~sLsNiZ&hXqx4p&@qpPEOu5TSiZ!fCmd4!CR z>29t%)8rW0HWldVWjfRD%<4C1;PpNC^#yQTiB$&l!?>H0WlD}#2+(=DjO{P;McQ3G z3Wuc$Ckc(1t+eS5GWn}X>^W-?78mJI$XdHlDhWnpMeu)ISga>j7_lb!ELpk-X#vG6@>X=&Nyt z1%|fQ&MW#LMTbn+@j`i-@`j$B*n9K!wcg$LiIA^>Ng7l>ljLGz7kTGrhfoM{i%(M(rck+ z2tj?j&FDaXoAoZ3*4t&X%7nZSy^zNjNISi-*G8v6Acdd3h7i3P_00Fx(BfSI(%g=9 zCUzYyy3r92(Un$*CXZ%OaO}gBsi-R1;OpP=fs8d3-nurK^)LJu!9o+j)YU$;2Ar`p z%=)tHa3|9)YGNQ<8c7?4?rU$7fH(|dOq&k^v9I;1W24+%X1+g)_ZDCoTkEQLkU_IE zJzkXahNa;Y7HN_*wgDYQlEW}w0ON-+Jj)MJy~m$4#$?npIZIAlmj`^6^4;D#ze0a# z<6i6dE|i=UtecW-7*+bD_#^Ki@qKWa;|!#=rG}X5Ex_ zncxdB45N_Mh%`Ot)M6GSY-vnqU?oBVK+37fL~Q$ETo{@cDwvXPx}Oa5SQym{vUAZC z2_{r9vP^b6mrHKz$H$$lL1w~M}De_=rJ~n z$}RM`Ag__AS+;4BFb>8Ozqa;su?`R}S)81OyR961=o>yKQ$SETjBW3${^Wt^Bky7| z^GAmfrkA%{`vf(ba8aIvj-K|jFj)1OyZ7(enc~j#_<)FjaNCfY_pa^o1MpX7x{b1| z|LP2k40G6DOhC*teQ36xQNKiy=;;n3C^$-v#CQ)|N(Ekmh?Vh03_4sCa}n3&xh{c= zJpks=W^yb^Y>gSz80D2TOT`P#8{Fa_$4i+|WB5zLASIaq0O9XXdJ=foXTc=!YkcmNpM)&XL}H*q178NQS2+;~%?a1#6(V-r?? zl<5Ibvhvqgct-m+0>r@oSP%%ozTA}j`9wog@(5^ba&&l2i@z;VqKzKgAK5diIG0S2 zAS!VqnSue1)0?1v67j=>lhPA@q&=TtuPv1&G4Y8Sg+&tue?($7PnPsvFOd9YFO12V+p9jHh3Q$}RCNl#aUXTMgLf?-HQ%zjmr-!i|LC?WH zu;?dHcmPThZwr-IbsP?Vz0&9^DWUnnP{WP8tjLmWN&Kb70aUyZvrp1LM5{k$yCB3V zDjw&GjAZ1=#B0jaFZ-29t%EEg$EquQgB7*{Kx`3h+j#x1+&x{t7wR92H>Y4*dX0+1 z$eBbkUzGm}i@#XM$)viblu@m}oKx$q8b)fF^2L$HF#_cB*`kxl2)i*Z5SLtQ{YrP^ zZ96kc@5I4~`3%*Il)tzf1+`X_=^^Myt8NfO+y5{Qd6sHseY{J9+!jq7$X=8kk;Ql! z*=;kyUXHuCx|ceh$DMt;3l>4v!1oNvZ|@TCp`Xre1KRc@iwRDt1ng%ib6d$&ZWSV0 zjW!|2L!JP{_Z4vlWq&aXP5hNCs{{WXzAp8Gpgioh8Z+m<>f%#qEeE$1$hUOk79w%ds3w_D8nmNPa2S>l1mTow5kHQZ!o( zEWSH18fE#J=d?X&tRbfG0>mNz!a5=IGXKUj>uoY9J2c=nXyqr;gO%6*001ZlJ`wxR zLRp+#QSs0#cEDE4*e2Lne^Jn4_q(L8*uq891B5!$xn%MNIe1Y+`!nEmsBG=`gC7;A z8ke#vV2&6JFTWa>(tl(~OtnyP3sBVUiR%oqEj2JbcCmt$B!&^Zm2Ss3VvW&ty*?4- zpmU3W1Bmn#$Fcxs6HbW7=F|ym<(F6C5i;vLvXomEVv$kZ>Ru4Sijgcu!GM&^<|tMP z*9wB0^ML>e@Nd&hVv>@coC&v;A3>mg+tn~y)MGS|3XLs4%ftwyxp+fVa}=E89E^XV zXvuFr!@te3``d2^iavt`h@BoY{Nfhlf%9tZ% zOxmm~l=p)q`F=JncMX#9%qkE^G-(1-LfW7n@YxiGYH2s4J_gf#VfPYy>dU9tIn*xb7h-7<>7xz+BLJX3$)rHT-dg15S_Ns) zm>8-FrN55%ZgGa8sN!8BcIs>AS!MhiM|Wf1&Bj)jaxsgX${UQ`xYY)-acOS|0|>t3 za!vM;?lxgwpVqmL;OIy-n1{nL4|_f4(H;fRZ4-FZM`3vY28M!)!A+kdi-ZJ8X0EM! z>nr&tm2X#U*{0%SMXcoW?(U$s7jdDae=5mnrk)j^9%7ClNdGeBdNv5H0HY+S?9ti% zJPOe*FO+gAv@;?Qo3rNS#(9OZND0}0ruIqf7JFncX}7@*f>LQxy+k7E7oV6gq%A~Fb>i`OB0RXk#BYd?l{hx!;g0IA>`t2^P*o8TKTJ*tc zYOD?k;1hNaE>)$wEOsaR#5s)2zI`|~J~+dwnXR=1xAot6+yApQSpxa zi54-;mKiK)2D#b9X+Fv%rL>6PQ)8K6FYGrEWZ$HIrrJT7lFFTz3jxwr;051=_+hR+ zADjmRX{4#xo@Jt%$2fFl^XRyFQr^Hy3gbK({6e=N%|~Lx1yTqoXHDs7rJbuU6qk1> ze@E*#ar97WDeb&=U`C~MXrmYyDE~VL)f$*DgAZW7EOk>$bNntkddzZ7Fqw$9zr{rV zM7OaP0izIcs=#Q$wUYpVJ+mnXMFpW_Btqk=^_HDqLs;zrLS94LOL+Q_|4=tM>y2vY zsTutS73rx9P%~fU9b_Ttq4JSHY;BH4q84}Lv8iUE)MwHFTN1634ph>%z*^Qd%UiJ~ z7zHW(gF&W~=_{v7wH>uu1*37N*=$k>vJPT>zQSPFPsuTAd4rr=-d3NpO2r$CYM7={ z9Ma%bNujUQ(HvApMjX`L?Q)b2)8b+-L%b@d3t7&pWRIWtwkfZ7wajAF66{jR&gbN# zJ@`?JfWu*8r`tAqOdM&CbSgEp4#{>F89HSyJdm8$&*6|HaB>mwo{-(XtqiY?PlnKC zv)Mm&tC>Y1#Aok5wp2MK!|}HawFdJqEZ!O=xV-)p+Goj=WFAsIfx~gA~GzvU(D3m0%(f#6$l$_ zCr8Dv-#IO@m@w zc}&o35EHe5MpE?-6RNh^>Gn|<<#dv%yEUQcHPqM6FKaJ!e5tg~zEQ5D{Wrv3iCb*{ z4Ne1qxpjaTa_VUoZz!EUH90aEQz?2SPh~0D2IlSNU%JO%a&2Hfe$B4&A`FOsGccCX zEaIqgeHdvxic&}M03Zs$hw1M%s3QL@6@d0+S3WgQvMkA}+CghF=zE~1cKviuu`pzs zNie3`*z$Ozs~OL@wTm~K+Vqa~r0xOJ2!!yiw`D2&HZM}VBZ|N^MgEo5`14|8%&#MR zT2%?;%On#C*VxtL9Mff)$!y=+6p;)K78{0Al)9Gn~#?9nOwp)Os-o+|U8kMrE@ZUC&^^F>% zMbXxoBd8jndDq)bzFBLK&E5ORlw2uScbI~P&~mWEj#TLL=A2c~QA=7pGGcy$$7wt6 zkuGTJbLwYKDibE=gM_$}wJa8>ntG#JfVdVodC4ldNeJ7~up`mMlj!*??pW6X<)Bc! zD$*$h-aM2ul45K0l;Y}c)8y77<^%}&$DcXXzqVVZ<~*=eO#*gG7k`kxDk8AOJ~3K~%X%MN8+eTxX`jy#4(!?*c@JhVVah zw5odbof>m4>A!Ct;U&g+QwDd>3SthjONvVUtXFa+D<-GS(}26Dht}T zby1S!m(Tf%Jd5dbjYIio_FF-#@E2jUD{N(6QUJaLg_?M$?SFWjs@6-@XLefpS8aA* zJdd76o&$E`WJba%q5O54*s@1ANMjyWKNyy^QU zaKWs>|9B#CZ(}o|Gt+VpN!N7a38@}PV$C5*$>kw32f58G#;cp+EVqA;EzQl_>;P-! zV}fDxsnS!@!M%{C`1GhJ1C-1HTaGZOV(%a)AU@=2loKuI3~^sxp&!{iY*)$e$kmP> z%p0T@8t%ldzn$8o=<1|z)=Q#{KT+%*^_W%S;;bAgGM>Ba4UQ=q@ zGm>tTAx*ctxiIrTznh9zN(0QIj(_=Ol;?R-j8PKKpU6qRDJT9xW{Me3YBul96;ghYGyjx*17()h8S`!_DXm)6PDKj21*}o@0h%t_B%3NnL+j? zc9p0w8{9p-Ut$4Yr`zoo>|n{i#BuPbFyS}|;Y*}EZmodk8UXJ9T!7#ONH~Uv##d#r z7m|FuD51ElVorphA1})2l=~rqfGaH}tY#K&jr>vmG?h{5FaVIaCk_8;zkdYdBEC&1 z`KHN}8bPDEkJ%4qci>AZ`n8>VCY%W;fXuNO7|Cb1rZSzh^s&~xj^OP0et2tpJ@Dy$ zI|?+{0B{cgf6~%JDO;TZK#H0t%l^&|FxBMN%K`#GLezChQgBQsVqtzIWW@fMje`Fc z;r9gh$uXHBB!9*hNLK3weXW|d&?QQSBSpW!mPK?R5Tl{sClbI1;E!$gDC2!XQpnc< zq!-F#0%_3rsERS9u3_U>U)DX}40rD9jA556v(*gtvvm`o3E>gT!G|Ax4!A_V$MpAn zkHi4LvKWXNnvPf2{`0N&m26YkE5q|#?!|j3or04y=%r9=02q{?q9#8XpEZ;N$2oL0 zo-A4lv7FdkNbx2rtC!&)XRk5}(j=JN0wSqFQ(B`OZIsQ;w6fRv*2+XYQ(6%d(=qZV zameIn)D0-d`m?8MBOpO}Dg6Vh!cp8m0L}0BTzi^}%eiA_FyPO*XB3^$e;-2_>F}>I ze{n-WoAI`&e?t#?HUA~9>#L58_i*_FO24SL+zJc|!03S1Ej00*4&>ty=xyei*;wA< z@9E8riu%FgUtj`mRwS5p4E5C!P;mi$W$(&Ul&3{#`JmVkHNS~X`eL4#6$O!Od=0Ie zm9!4x=F#$8OQqK!I$cRGYLh3?C~4!-WxYTItWYt# z?aftbYGk+KJ~>=A%_mYpUE(tm+X1()DK7@QnzWz>W#aXBpwd&)X#q?&V~UcM7^$o& zl%{I+XW$90+P|i6ZC^L$z6_T2|4WM2i{auPZA^UFD>6+c)0X)n-qj;vJ4eS_Sap>A zO@xl;m2w)VSx5l?TDC@`l6EYU^7D@TmuvGA6snV(s1^_Ah3qXq~20 z#%gyxSx9?+qi|-!etg7K16(h<2R&8l-8@1wM>}nV&o(p}%YliFaP6G6SE&8k>3N&{W+pmXDw=f^{l6?Dc$2%y5pF z&T?*lReNWHVgAn6ZfV!YVDz@gH@w;uEY8uORUsmm;=}CKs_wX1+*Z{>mB;HsulRgI ziBicp)k1mADWW=)D>si5Hr!ETc*u%vl1jw=4r%QKVKgzO583zGS`Prlo+M!dCDZ!2 zLs)MiTIkVOYV9W`a34;=kK}r6`~}La0Bq8V|7-@(uB!!mP4(rsLMo6KL}IO*6|0h+=lNCUamp ziDVNQ_@tTZiqgNs;cyIqii5yL(QTZ$d@@wBur%S=gL&ORMcj59gkzZ8}UM%z+Q;vhjy>T~1FwFmDiXkckC>A5Mrqt4}!ffcga21O7m_8~) z1ab&Ks!V|}&R-JkVf&gNxsb}Q85&uW8o-@GMGr$<$T^25kAFzDvPPq(UnIZN(**Z9 z8T^OU7fXA8d%E(D;c&bVJD$DYLWoNk|BegRebd-gJU4`jxno#Qmftdw^iehj zAECPwr`Tp%oFN&nBb))Ft z5a|&BsfH!C1kGNA4^Vv6FZy?tmM1rq^bd)oHV)}v&bTVj>i)e<4x{ied&~6WcwX$c zS~}hG-7b7%-G5`594q3)F5XA+<YxCIx@kjwUT$Y<1M?CGaa`Qs)_^*nm0)!~; zr;Y1lpnptZ;|czC^_?_Aj&*G+E_N{{{NC)YxDVsa^gH=53+C>vy?U&1*_Wx6lD(td zXa*>qpM!+G0pD0A$D+7ae)>fW^K(1|sOClyfe`r}72(oM*?6z{`Pk%A7<_u%&>`G| zNPaH~8Yp8YVqQZ6i6SE{TPSae_qkhRh(f;jHLywb=oy#jdki@joHq{3LfRECz(=hDdL&25-fVufRPG`6s)J zmcQBW1KWU>*D=NXZ`{=-Z3V-TW5ngfvqx)v1Fm6UtDa} zOKUQcHr_15X+GNqGKH|EKeO&#E7nLu;i#SY0igAxm#1CjQ_(CV$g}S0imSUb29QmC zCOySkm+=0k+a?_#oDaZ=AS+pn$C$BY5|*Q zl7byTkajN4>Nnficvpvix@-=If;Y)a(9PBx`CkvCY26-Q1JDC@bZ(WLEy!UTU=JIT zZ)@Djj`XG2DIZm?hp^gsG^BF|dptpky*v$^YF%a3A$&DH}HSR128U$s1P8ODiHzv#a&iDd+C?D z)aCp|ae0q2_gtgdx62EY_HgdvvN3=fw#v?&^=?^>n}{w*-)w{PXdV3KHw4w6Byakodl(~UoQ3`G+or$iyd9nV)O5gAxe8X?{=gq(U zVyv(p_xrj02)4m~cnDV^I>)olv3BBT{f8uRg_h}XIM&0Wqrw5QriTC(CSoDP)ULx% z%7NK!Z@@xQ;+J8p4N-A%0;^PN)m4!X@|Bwc8G2J#w|iWIUuKB8xUb0t5zCa?F$G7q z@T`dbC!3)uz%#XlMAGl6k-9X)N=wro zD;{=c&viZi4G|EgXn7;`x_^PnXErJ4_#^FnY#AWsyH#h0q7eZQ2>I4Pq`nvd<^N`j zADiZ46UA<43g{k98`a;J;PAqwA3)H5H;gax(mFs_5I%3JD!;nSe^C0jdePJ&+Z&hT zm3UHcc^xKo@iPn`@c{IPFIR5}&7dlZOs3~iG^D77JIVlSbG!>TjhnLas>qs*-m=+#-5d^w<9@6+DEv14Kbe3#AXZnfp<`ej{pM*(jF!zN+u8c%lCIai3%@Ff$ zceuf=p=}5Mp zfbYV9t!wtUzk+=j#h>z__Hd8$K-i5MpBJv<>+O(M1t>r0IlR}9`T*H4<<#xC$({T7 z(6la0ndP*7_zc4@@BrAaeez|yWb_d~w=wmpHg#>6p&B0fg7gLdD_vSDh7GNcDQG|aHJMVHQTbgEw#pQNVVxE;0G9BXZfJra8Wor4&l;!&=}lV5aWrc(V%&^nL-KxUNYU zsyZurR+hX`I_|^Tt!>zbcuPl^9V#p?VEf4?@FH!)EA(EopE=#YY-jj51 zGYO##ieN7fb)si`Tqzb(E(Mu_-?4Df_E%Ri0b_*BgN>a4jgRto+YLTehT?h`a$_G@`7K`QhEyKVw$4?O2cMHLm~4L zMDyNn>E0r5$1PL6qYkSAF0YhU>i4yXIoY5jxkY}{yx5&v8x;@0F?V~mBa$$b7O!jq zf1x@^i0y)s?84NR!1?!Xp^D&;^2bBB>l^L3~tP+23_##6Mh%@4<`L<_zdh=48oUpc<}7=O*@{& z0=D4wab>(D8NVK_l;v7Pi~EZaTk!x4jeJSm&tFArD`0q9mq;oPFggqvJvGbh^`N_q zbU5+lt_f6B*`P4`3_!=emL7M23ES%7%a)gu@t-;_2Du;SxWMw!`q52 zqRSk)2F`^5naC1ZY#UuAmzG>5qh-AS!%3^R^YhZ|*aBew=OnfXkpN(iWoHW)!(V2- zpOrr{Z^~z8Bu;@%@F&pUp-uv$3QysyP430?nqGs>Nh{JxnWvvMW^ek&oyd|sW9TOK zo5IwWt-u+^Xft08j|`kQ;e4%pGk1FM_SWrq2+bz*o2|+!H3m~4sL=THDW72SxkbRX zK)}SDy;Hv`Xdix*C9$u8@Sx1>EXnRYF--$ik}J-zeqTW6O*?6lyLPJA5CQ(A*&c(p zs>nmy&@oE%MX(UW=pdA@Co&QxwmWNH-4D5DG12*D9cwO**3K%^pI2@R&Yfi%s^gpB zttw;2AXAAmK7=cF0b+p@LNf_Q#R{cDMAG*$UIz;LpS@=eMhuiy8Fwk}{oZ7p+_5t{WL#c^roMnQ< zJfMLhg1`8fcdrkl3fZ@cJ?7zJ2U@W7sO=$U@dc-PU8}=9&Yfyw=xZe_OSy;I`D_Y| zTPyQyA|7wrZ^Z93kAwKlR%J*gq%KS&epkw!H$~dDQ61%7ilr0Ry~Gbch5nho z9c#cxoBIz=PQM)*&v-%duciBzR($zFl@clh=*`NGRCNLgr1q7GBps6j;t%q`9%QbW zXt!4`m6V9uD^sidvQ*);uPuj^6h-yP@`H8bdb8AIU)3A&kZx7w{QIi}i=Gqlpq=&o zY;|0SL(Rk821oENmYD$;mgQT#aSa-cbm|%avxc&vbhms(zetf19be8xgVwiC2eX4b z81GU3r(T*EjTLj-dqYb9M1Vn~%sPO2GwePU1aqyI3suHy{Atlk(jtg)qo(B(i@+%p zuPL5Au`X|KtjBQIRPnAU$>DG~UW~69aF;2_)Lnq8(ng4Qz%8VDKZ$6zr>LQPgsMU) z-frc52n`aKsknpKu=si}uZIKl9F7rq>pFtBaE+V%YFMT$GZq0GmPqC5K=vS6^@+b>d=+1OQ9h5+KPaCkgFXK)JxvWU zmkbHy+6H7EtF%WDFg_UPSc?}!j#HXLaAL@tG{5;?4PyW9-JO8f@yCQ}yl=+c!{dpT z^&M^JL98a^ikL7yUopfl(uPkIE$xtF)mJuz z=l@dtj!+DaFe2{E!%nXvMuryI3AYvok=lygj^Ab;EFz39K9UVl$?n_-5;LRt=<|Wk zN50E;E82Duoh7Rm3VGQT3sTpD-6|Sw2_~6$Qy_f<$bNeDJe>E1F z3ZKJGHsQxj&mHKXu^|LL0K?)o_Qm~}q5zCoLO1N4^VOBe0X)v{Z-qMcL8$>*J>Y&J ziqT;hg|0(_FLyvGZ$P+4u4W*`t^GNvz%G=J$#gj(D;FhuE9OVF1qqw&KmBLCnG%dF z5)TPR?f9MBVt!NCIJ^^RcKfU_pEwTTlB)Zr?%{B}p*_EWMgi@3eL(@H9|XokmQN9q z5zuL+NdjUM9(Z{N_PI>JBF?vMIz!!mg4mkU;Lc@QG|Pze+t>Rs+5FGsX%sq*p?Uu6=GaXLgbE^fiF9% zem&$08dR1rH8IBojJCG3w!915qBn_Uu!zO?3fw2pyrDgJ(zuWiX#3Zn!%jb$8v+!9 zF#-f5_z#mNluyZc;#d`%`JVDN_K@x3h)hHVUHhVPskmdk)!87DvXPALNkHe0f^=P| z0a^MleF8}h5$lFAr=uuE_Oj{<#9l?pOvs*uNJvX_IEq?R*@%HnkplF)di8*iS#kCwSakN;#Kt&Vq)ZSn-! z_)1})%Y-C(hZvY>@2--o#B!6G9nV|PQMe2Z0018VWQy>o=*CHr*m4%aH!-p?Zs)JG zm85gY1*K{ifCYtbAcih|t-xv!!fLG<-FFuYaRbPwwY^7*yO zq#d;Y(jTO+;+eRY5?HS5^d9{$3f(oxC{WO;E>qU7?-us(P6tg?*U*E z(^j6px}LJ5^hA5=PftC^3P0p~nF`uW>qtoD5mo>p{KTQJ6EuN23x z;6jUD>vnoLeHS2+kwt^K%eGcngz(VqQE{BcNPAS4Y*bQxA>ZQ`Gh=01i8i@o8c-^` z9s15p_}kINM27gwqk1q|^rNc8y>jW_P5MX4yD~to-tv+Enbkp3-R%hRsQyNs2Yd#1 zyahh1+=4MSd!;yDhHTDbcY40M7b-YtmI9zGlQrod*oH973}5I*YjN%Vdt z&RR~?$DtA{EayvBqtQA!e$u+ww22MIlp>Kr?$(D%8`O-HLVrrQk()|GLIf{MSW5p{ z3q=+iBzE=5E|Ap1lPIqo9;KQQ(klwhzapu4s8??88oa21nJGx=RQ*+PkN3l|BIeb- z@>S1C^f;EVc3)0`OaG26NV3fFl6_P_&yun3EGtN-diQAa2*K&iq~IZWz-@$^y@ ztx9R_)n%`0nnt6%H8e`6KQH2iB(ZBjQC{9(lWd2>;cz%E!ONz-XA}TpQOzQ{n%{Jc zVzP-e=(AOowhYrE0FuGqTQyU(UK6CP?pvDjZYg%i(%)m2tPA5b6-|zE8nI!D?R~JK zCnRlxSXSZlYAM*#-kbxePmneT2I^oTmD*Ft%(;??C5)xN36t-4R>r)#U(AnmBRO>j zuEY?>7vrtt_qpL`sZuLp=Q$5R0$(AjMj{`W)`zl%ClNSHs!Y69VK8{-QcRs9Y>;u}>OL#u=xvgNoLyj43K8HGHflfhREQ%QkrxMYYKuN9aLo83b~ zD?A(li3qe4p@WY?&7C9tW0KU1-KgrmK5drIO%{>A2eA1{;#U6{IgIgaucQ-*l>w+T z*r93^&&1qW7^egQsHTAqr?fJZGp+cw91gas`D)EQ&3m0r^u<`3!%Gv_gty)47~$sy zydO()fo(tmK-oOq!u2F5$fA^v%asx8Y7J_wy>Vl?mhj^PVuJFs!0L~)C>TZMqg`yP z6t3B2e}%p_PD6iynBxg7(5mhsVbvx14o4rn?fx*<2m!(v<`D1T67%}+^$fljK1N$O zYFVBd)x*!SMZmw5ELoLGNue-OY7r{aI$u$_?G=8CYDobIFczz|9)NukPQ7k5?jkX< zKzX;QWBmr}VO)1&yuVY5jCq{+Yw@b$<#4$LhVLt=cvWpUF2z^0g*CeBcjM89qBB=P z+>3YsHVih#JNWt)oxC5Ii^Sg+Unm`yB|j%Azoy7|s>-!p+`q^K*A^{}MFJfO za-h1q#rs#u)9UvFx}?Q9iQ4cysc{XbzvtIz=|2^wo;?N@JxSZ1KX&E{=FNxocm zMjqRfJus;EHcEluJA64Z)I7~<$2Z^?T2Wa>Tq2J8>HL2VYgD^qNvH*lk2Dk(%h5tp z0ceUq6QD&X1PG^|uG_P&=E*7u*50Q(+!jJGJ%O?lh9{c7-OcVU#3oYvt?xcg@cZy}GREa? z;E6`|T~*}hgjf5Q;i|EtH^m#ru4I#Jh5+5x!ih@=%lE9s$vX*@avTphNxqs!SbXa@ zQCvk3!sk=6l#?&$*(G@Ig}YFtALScmEReysVl|AF`m;rEc^0j^%T&~R@Qo~U$F0NR zSQ3wp9XDp4ChEO40GHB)?7y7Z+T-`y)SW^SJGl;kxXJA?WZl}$GXcw=`BY#^X9jO+ zCo6bPjmphM35f57X=jd6jD9*M(`p@LiTJG9Q(};nqKN+I|B{iHULJ5cM}%9VV;#p> z?^&Qi9dogo^xv>%>^yWh9AAY6I{WP;EU*jEj@j7p1cI>6{-q>e*5xu{|AlmlX|()$ zfqr)hD8{qt`|<)6gQULzrEWl3OS6{~$lo_G*So93;cz${Z$T0ZmRST0pyQpNiGTgN zsM~&siog{8&lYIxEdfrJcu4*Oq#(ai_*^LisPYgGAqET?G+M9jm2IZ5O2nzQC`gJ^ zx?Rn`@&MV6OhJ`G)=MaDxb!Tp(g7AIn&Z3CY`Wd;`iCct-+))}yYQ;|x}8{_+h6U$ zt)Sw^Gj>I{Wz*jL6nN!#Slr8x z6i^7mmt())CX*tSAZg@J*7`CaUnBuJKnO{GV6~kbFBEmGHO^3WIDQ@85x*Q>!LPy^ zj`16DTzLOW2>{=m@J@(Dz{}TL-@?RKnYQhv7|ky>3x9E6g|drtg}dljN@c3hQ(wej zy^Y8O^=$qpAPSFiTcIG8=hyT*OZ|KO+1|u5cj$fIo!4ymlA}vQa;#jl3p^^^RA?mN^^_ z$2VYw328N~$&(+F{x>uVWy^Ev)&kpritF(O0AE?5-+^DL8YAKm`C{MQ&u!-i0#s!E zUtz4n;cz${jw9HUr>Rf??ldmyka4*zSP(_|K&g1kUTWz$iRHq}mk!$7qJ9L41X!xo zSoxp`8M5AAtwt`yx;4ED#yIpMelFe5pMrD5QN@HF^D`66kHQSV;A?#?55R4Mj+s&C z-Z3dy$eXZZ5ty5E8tt>Pv{?PzIzm`Y@R|Zs=Wbs`S9bbzV)Gpfws7b9lLoHpaHNNGNUzGapa(eGHg4Qb5iWuY2i};m17y4#zF<~LBc;2uBU`YR7yEnp_?Qryn9gZIK^^}^; z?rA)F4!~jTyM`ZhYCZ2yYh*u4+=xp{o_$66kJ!p`fPx48X_r;vK!Ff2oEH{|NqVn3 zK!YA-)dMg`(=IL?<`Vkz{0VZ+ENalTQ{KXyft#mu?#xD+y9D6;b)8T(V=%osP z!|`79_Iwly)UOY+4u`|xa5$!6M*(=P)bXI<<>svW?PS>)-*3n!Z1E4kr3dl^dMybjZ}jig?E7LOCqUtdQp`7bu)z832+{6qtv<2qWPhmGJz z{bfIkb$aTPxVXt*lYC17xV#TfZ#O^M5PK?WwE?+{o=0_nJM%0PMF4jCg+UWlpFDv@ z$Z$AjW09u42pJBCqr@wve`xOlbWpNc?v$eI@nn%ZGsecRn}F3HCTR4Ok{O+3lrbZD zjxOevt%}%B%J)~;DRBW39Iu8sfTqs!Z2MZFb+16f0A5C}!*LelO@2sdyr@Uv6>9)i z=>7D$&t$UdIYqJ9@gLGEVAr`lr%wZ1nT0mgdG+<_yIGL65_b^0f;-;v-J?C>LXX1XnI_aX1{;;7!w>V*m>bu%|r$!!nIk?DIYW6e}ZbTrET{ z-cJ`NZx@40f=5ymw{F-;sP(v!Jw=DWMrI)Y9KEwQ6MDFnMaD2P-rnx}VU$$2XV(Gd z!1?012agY5j}vegx(j+nNI(D}qE)zxPaFhRmVE*@lEX?4%|1|nA1>}Y7dDxbNheuf z3H{#4H;{Sx>u^>$91h1s93NB(vIO(I7C@&x06D2=%R>N`AHdg=t%}|DV%z#>iZeH^ zkUm289*2T6fB*pKt;;(KoN)0>8&_w#nV!X$Gzy2q;aCGF234ZXc$fDCp=WpUu6O|6 zy9JcbcyB=Go;W{TnccevAue$iz)U<_oG)Xh!{Kl^o`z}re|YZ3iU;7mli&{?L-s;o zM@79<1D%8(4$0TQ1dmty;{-Sy4u`{WF=%24(Bm+-lXlF&{-$^1yD;5dQ8jT|t^~em zx1p|VzO5-!uz`GAxnSX4A(ti0;rLm+Z%@0m@v>2Fi~L!k{x3NR_%-!#0gSVEe*^2U zwWv{5++UOYFThud{u@^A^efZma5x-4hh?I6O9kL``2Q+JdjesF$Nh8ewTm{oQpee6 zR29kJko37+y30Sns0C_v9)b>VD9bAw*95F7XRk?>!|}^ld?-hA~U z_UL28E;{LYn3U(7$C`QDw$?u9eSaV@-swc-4E8SWIFbmK_ByNH-RU(fRZ zc&on!KgH%FZT)@*EuncWL4<)b-mq26v^Jb;j?3{=)6fApe;gJli|}iV(_gd;(Brse zVfPx%<_;VjLvLo#DkJ?WbnM|sC;6Upxqbw5MnbRlMe#dx&@niF90m{;Y#JA=0k{wz z1>nedV{3>sFGl-q+x!fvsqvWxB`?3!4j+8vAHZGB<|tjaTsuA6AR zoh1)!53_@JDFAEF2V?8G9cQt2Yp4RlKP!=cA32R}5bSs7$df1WsBO?@2pS>hJjum=AB{j-~NP16{0F{JEev z2f}8vSS25WJRa*}yRXWDHAtdn#$-y`!gV4dLKOk%~sZuISc| zvP!4KCzgXv8RT!VOP}y%eGk56PF|(YErv&{_gmW56zn$8n^<+(&{{6IlRw=9;Hcxm z@q0?oyKx}%scZ^z5TrBIF%2%!I2?{k@bL+WH zh+^rC;K*G~_a383S849+sxwPm7HuTvm!j*aL82R=%>|EX0?aaraPk38y!W zt`XVwyE=dfkh%<)?XdZdj`lBdsYz<0A9kkcl6D7Q0Z_?0mcsRaFp{-hvRGTL_chf06sh{178H} zP`K3ic-j7si;X6?Eb0FxELOkcK=rr&#>1FI#v-M0I2`w5ulxJ(um;|u0K9!IMn5iF za5})h+N+Va!<#`ay-nx2z4Ya-sh8mdkykHep4mqWTBi~J$Vh^XUwu!GXFQbVqSAl8 z7{4R;(M1xJ;*XlvuRQI2;a#!|_VsdprO$^``Y? zy~+-lFqPKf%~i^Xok*Jso9`!bMM*9cpfJ)-3WTozz6H`TajHyv^q=gb`y0GYv5u`^ zfiYUfQJQubaxmo;n8Z=1XEjP4jx!i&&yDx)?iFhD;w5@ylL%!0-HR*oJi+g`C;-#2 zMB5aoQ*?VD9(@AvB|gimNJ3>{egaTlh_ znwNI?lycgmGH)4`_KcwX^TjRGp!{fIu9@J7-ppQy<2TUgqjz^-WO=SKbgV+h4LDKM zgB}1sT_OY7zvk0fEwRt)*(PTI#ipGvwz_gmW6&;M$FOFk1>98{;&c!|ItrTUZP#rl z<=D7gJEqOycpk4CS{;t%+AJMb0PYi_*2k`FG^^J8Ot6zhwVO7#xe>Q2ukYg7o-^v6 z(jXurvnOrAKgkb}u-It&WpF2eV_kej;Hl%+uwI)z9s;ypS)RiU(myZ*C_)T}u#Zx@ zPBQwEN~glRF*^eQIL57+lpUc$zn#-Ku$|JU%T&AFrAdGldl*cDjui9)Zp@8zt#n zrJf`I2@nYY5Y>nGET1hbN@XNcFClO5w1??`>8245#~jSi0WKNhzYlL>$-Hs#kl({S z01n3&AWkngjD1tASqB1&JSzRQa095raT4B%z7$VZta|`n1{Z=ZL)OJ#$mF|7KAumA z<{{|Wzz2<=G{s!f>3wKXGw@L0ON`(IWUoD{;~R?Ya6AgWj=(!q3vU`|=Mj1+CHDY0 z9N-(%&Y%(eTg|03Le3!R_EuaoHt1T6hXM1bx_Z~l z+hMZin)$A>p`BgYuNuuh*S z%&XY=G?_1A)^Z_0gIpVY-JYXn%v@{Mw%j|>!EjfF-NN}bTi;n2+wMGB&_$R$vq7De z{s91i=v$5rUZjQ{bK%u`9?rw>#J`g@J4e?EE}M|pm`OjI2ltkyy;u4_vT!lRTqNR7 z_{F|sdS|$IIQu0XV6yQ;?05To5%(#$n8x9z#Op)V4eA$<(vI9b2*rQ?n48I>p2{b8?nTY{5_$9CN3=6MM)E^>jCH~@@rbtzMv^FwYw7Ad?itE zh;#RkA~)y&F8wqS00b9B>+S%{lgZuJItw@XYu~*j`HUa7lyH>@UtdW??6YJd45dgcsxSq>HHmz zU&gyf`z2)5HZG*^+NA$LwvGo52nisWSBC1iEG$T86N{}J8v?JEx+6MheDn|5K|udYLf!!do#xLUrt6;H`p_WXzl z@DGbO9{|Q$<`O)I72ZP-V~22-Aj|j48UF0L-1e8(wJ2ab<-&4acs)OQ>gH&ybJBl{ z*uf%T6kbn|r9Zw!`X6ri2Ybps3V+q%H1OtDxQB&y!3&(}V9iZBz-GxY=n-|eScPUR zOW2C|HD2)Hin?5C5%7VQlQz1E@js^~*cB${ad6*>E&)XrS?v@n*N%gj z*nYms@Nqw!aXVO!K^=2fki)eosDU5;`9u&H{%%Ef2!Yh1zV567!< zpe`@1{&7JV7xMrxdH+mQ$8BEr&V2462V=qaTfhrL|KBulKH(ZvwK=||{z@!F$~3&E zOsiA6L{QXZd|{Cs4#(GFB?W-n`-fNcQTpcw*(*?Y@6tnxQO#q(%?3*RPX6~TGZjTs zu8oKFgJKOQ0np@?ozz?^s+!`qr2a9{isx%~k}6>scLNY_VCZdonUaw;HXF_{9P9X2 z_01uzUe5)k3wQVw&bgLl z@EkPD#shoee?bT&X7x{!(xBA@GquZ)qR5uK{Sy;WF-jH=WF&_}PMS zmow=ZX%UeXK?wW6IyMHo#xw1A}XsR_M279;&61po3BIQ32S_jXJ6bxe{_Skbv8a5lKx|~fJhhf zkLTpUM>F3jFwJP3x37|xBf_HQT#o#slp0@J#yalz!tflA=gy*`a-~>x*dT*7880oT|0;ZQjj;A~UOLPJq{XvxQ-0Fbp&N0nUuatiY}&US>Q&H)&KTrBJ(PeNxH6&4o`$ASp!J9tc6 zvA9|NOrs>mpLldzVaG+F;wTdJGtF&2Ksg+aZ^iMAI#B%`2La&ULgulwGPT3TD1LSu zjT#AFzyld+bM;Jy>|fYqCaX*sC8||wy$%*Ve(dXu&{31u@|H=s*ULw;0y?V0psJ_z zz5+M^03ZNKL_t&%?HBUW&=l+^pV+Cy47rV@MZpt&VYKQlujwXgNK(_>Srk({hR6vqdRk-U9Ux#J<4G zOyuizzI&wq-Rz1`PRA*%Gfu2S$ssH-ba-$0K?w04t$i}F5=gXQ%IBEr1Hb>-{pY1i`ib+uQ9WR`=NcwGH73Y6t32k8z`7#K+A zlVVE@_TA3WGcrTxSTq(tbD0pM2co7`BGlaroA`=Yhl%S@atJN*?;TcKKN;Ku3uuzDlO27Tf`;-7Gh z006k149NbgaFTc$sINj&ih@=u3!^jKaX;#5K1TT$2i^6Vej2Z6S_kpXWpk`Qp{$F8 z-J&vf699bx!s21!8#ua<0GChzRv0~0BNs8N1SkUup2P~wS_w<*08cHoUXmj*m?v0x zx9A;SeH4$aMhJ&g_mm^X03tBk|CWka57S5F5`DZ6J*3`SoZj4`#2@WfTu;OA)Cay< zi2B-sIRIeM+2j@I2`Z_6Rya-(!jfI}^xS~Cz%D>MLiZt8Jf^?tme_F#0O-Ve?OE`y zXaUc)9PVM8h%NqPIC5-4#>YQG;~p4K;^U!mvF?MAG-{qP0ff!h@~e5gi%!q2W2W$) zlq@j^LW%`a?^Hp3uQB@X=#5sb^cCePsmyLC=>bs)&Pw&PzQq41KYQ^ok&AQZ2Qjxn zEZ9S>F}QzRUZGR>$CYjK81X&Pr^w1gOLzbh9-OrFB(xKy>{taW^kfc7`xaq#jxRWV zo<~2=skxVvFaQG(p&=0_J)QDb!m3(qE1BMbB5RxSu{QLTReCX^dnbo=kBI4YD`KSkgPMdEJ<;fA<(0>5QWXMh#@uZ>tLQR% z91e%$4Ahur{o?n79FTwP|DDL;As?CiX@z#4#ip{-upjKxJXiczZU%ic_CwF(fU zx!#Tki!dc?(k996X5;-1dWhgJ1)ztAL;!!mZjHE%_h*!lT%cLmksdfPTK8=~3su+R zCz}fDo6kyymsNJdo6(OmtT~W31&wU;ux@p&Em#N#nRb{L%k)Q%^(fk~B(ofj4qWPd zPbQ~!#0SZdyB20n!gv*a{6SbDNBR>aqN5hBmDT_}1v?tmG*Iv$Sd2Lg&B zEE7dVH(o&|1x7+YAym2U`j+xVTB@4}$Qn21rzK9g;GV$()qFd4j~L&oJIMJpQdAtbuzx;82em?uV_aGM?G#H*)2JWApV~ z@8yO1P_?k30zW@cIUJ6=Fg_LazCJdR6q7#Y2inHZ{|FliQW@OCk_05RTQY%kwjLk) zepdm=5RqYW5<=5V)rPK&x6MnsuurQiyZOfelC==~dAYAmI9hHjq1#ax*CwRR<$GW~ z4#QK7T~9d#-s>MQ0^Ji-^Qe42R`i`#qaWLeH?p+CX)#*xRq{QxcCunO{o%dM!{KlY z;JR6HYz(oC8OCMx9g&6=8n7APf{Y__i!Xw>jEbP1?N#ec8D^KARWiFGApmUWf>9v2lEO(_9s=$zJ8GjP zSZXgvFQqsfu&>+>NAV5LZl*KliTgnA!RaGwH|uA{}-~-(vP1x3xB9WtZVrn#W2zK@F-g;QMf%Qll+44LR2@Ozkgy{M z*V!?NQ8~~>4wy*URyJxKn)cECaFnHtWKyvkSTUlwpF~O&V@=-j` zzI+%4TO{*o2VQ&-*wjYJEXt%*so;apHw#9u**%g>vL<=^z{)j1Gx?+Z zBKm+M0yX(6})XuUiC~YthcY;DT*l>bN z=KuuhnkTQNxTF3c=6=v>Nmcp>0FoP7Q<|pAk4y)L<5A4-;a?4B*8zM9(-2^9BM(Y{ zMvQW8JwZ(n)++#zV=v_^Jyf^?0H9`G1SmqT5D2=CTV8IX^5qCRkED^ME?3&u`*9_M zq722>l=B=rVmYSdfB*OP0Mu7d1Ze3wqZ-h`hiAae{?-v9TtiIOog_IEyPw|Qp8i2T zFp@7D;M+)?ptzt^tFrkTlfPRzOL=kX)O?#w;+^nH7=?4}0DgpNhi7x-SHKT@|?#BH(z{EmF6RI$!=CgK_FjQvWPvAI% z7&Th{$zcv5E}}HsM~x+)in>Scrj;H%=+uNAr6IoDf5ptp>IEv>@@;t&fE&xLe0pf3 z{bqPU&rrj#BvJTfb39B4XiG(A>h0Fh2?+k8eIE&v{axq)r)FBi;Ey27kSL17UU$);tQ;{my!5l@|eW9q`WJRv!VW zOR_-s0Mrphw33VTDc{~r$#D*4Tc&XPpoDR%R-}q3?s=XVxN2_3e}K7ffTPvO@B z2=YcLrsxmqX||#hI>|3Bxf@~m)Gx$JYzC>Xb`fp=MJp|m9>K1CV6>@KA`uN8$hb-+Tac18M4i6x!RE1)gMHcK-y5WmTa4W^Tg>0EE#` znkOYfPsJ59O6Pn15HNPD>0*~nQ~xve~G1^ZS3jh+}WN@a+nT3sc1Lcixfr}+hD|E zL~Dd~(5zh&rZ-LOWlI#@TicDe18-wTe>P4Ibj{>F6A2}vrr;qv{A-8q+u@E9M;jf@ z!w?lOXjE#1s}8q?(dH8fwt=% zY*fWu-jiec)V%KbzO;r|=wARKuh7Vq!o!)YZVoDoa?AgI-)IHXZ!u+Zv@?o7*M4j`M!ZJIh9 zS$gbYULTV093xnVjcVP3CG?4{eS3v@GX&Wv;)T=>MZHn2yvykG$R^?4z2^sTsJ}ZL z3aEY@A4yIdE)xxd;1cGP4uSetsQ~QyDW>6gPS?^H<{k=pP?1%1bqK(>1OeQ2(UVMQg@ju zFHj`}=%(&>Dx2$QR5sW88_$UTf&|AiXtFgHLOixO3Hyi;tW3I^o-U|b}ZDp zLf0*kXy?86;cG>IhvRC@7y`=vSEjlzNvgM*oW2e7JHbCJ<)dXP6@Xg@$ckRG$E=HJ zq?9=Vgk^XrbIU*JIrD!aC z7QzLiJpG$g0K!lNy>nVE3vb;2*}K+c$yE>xr)Cd#{~K-YkN5z@SE7mO_N%Eg>BJ~1 zA_AI?jg9qCT|ix0UQu#UE^C1CnU>rH+)}N)m--UeF`(=uCW=ck)SZKS!m`jCXxEbR zY2yX&XEZNEIwSxjktp5KUk%+xKtPJY7B0sSz0E@adm3lb;IYBol)@e|W;b&&hn`@P zxi~zEiU@z$j$kZuDm6LT;(9o0+R5?6MNgzp8@nNX*z4G68^Vf0p{`)(eQ+KuMkIYG z?#@juUEv0~@0Gb_KyaC|1p}rMbu4e*$m>tbr{Ne;p*=q?g!Z1eb&6ON(Ku55Xb(jR zY%#o^`QtkrVJ?Wqm|RkM|9nrq+5<2{t_TI?XkT*ot>V<}?GV_AVf~63*kE=s68UjU z+y?9-LSzn1sp~vxaTOj-Hj92al(pWJ6+s!MROCpvK#vEhWLZ*sNu#Ub*lUjIN&g1n zC5QO&;R3(>JBs^2Wz{kYKg3>3;^%e9H)9W;1a^}!p6(iPxx9-E$9Jg z!5q=T{osd|M$z_fr02c@sQJxDW9dcux|E$qQ=O3OPz>=Ka{yscS;&OQt6?A+i?2}u z;P~J`1)No;^o+%e#6NdMYINw|Ukk3vBUhij8%Icd<{cu8vV{ygdCdIqrnn4HJ>`we z3|Y~=Da(y-vL1?S5u@8`PAtDb^h$Ng81z`z96~IAj@*t(z1ITwhsAL%;wH- zatsA8e7Hs__qDVIyM6tHd9QGIuLoczV#lGFqW!ku>|1wnb#%YqSm+$Qz5;o$dW9&9 zurw(8i{jo+#c*-Es4YWlZ78k;qX=-lO6CU6@Nzu+4sXrr2X5L?d6}waHaBb_Mcw#V|w@(%akv|!UmwKKQsHtpK}mw z$AziSA=3i)Hq1*yfD%ZJ>m;OF<&0`_+Lm)~LHi#>53`0~wxH1;hK=DH!3W^t$m8hp z@lA0^k)+Y?jvUQv!LsY{>PsnOuLAzSaZ2D$({zMxJ&CEOh-b&YBSUdbK`JGp7Ij1f zfcVGXN^09Tfb2Eq-?3cG=TzzXcdh{*!PfpaF5~i~*~lc*m8d?Dphe8P{7<^TX{$%f zP>H)y4UmvQ-{S!o%_QDu&pNZuapj^&zNx}dB^K#A*7eCjT^BQ`cRej1BS1$i?>VxJ*RyRHhBMe3AwbW$4P(hGpj zHWfM)<Ui+GzEov){o{}=hH{5T{!~R6)&{uydL+ z{?lPLaFJ^!w>l%V7AYnJCiIcP z5P&a3#s3nVkJIIgCYr=64Fhql32S3x_hyYw*_6phKC1N{Oqh5+4a zdV3VTbB3@@%A18d;V_NUx(UY1M*KqWy$xkopoOFtN9(f zlf$g=Wm*`VjYag_NCd$vNmqOgFNGXG|wDq=uH+bAyfU;TRBe{K+qjCs|oQx zndagfF=QAWs&`^g56$3oYq`o#`rSpsr=I1ixb_MBG5hivUty^uYmwcwWA_b*1|eE2 zl2l4IAorQ%6kFbHY-}tACwRNewj}3jWD*E+e@eRW^e5p48TI^=;I{vxJ-p`zy!aXkx8s&9#DBcvYQ!8@U`r zf7pvYsnjA|3!3(ouv9(;x zxRFAMm?ZH(KRh9O%lEmXi8G|u{4r$;?OzHf3*``27645LXBowPGk&C+8ygEk2~+V4 za*A}2is{%TckuHu!QG&QGZL2F1iS!N@ zy@k2urm^is^|yQoYyzB~b5ZZZSx8{*$4o51l2rFYdKw%%Dbi2XA#ynoS{kZS8IL`_R%{4A&WG{)@vYf#Bigq` z{?TgUbKxS^jtQyuyV)RSe@_`2?x0`-=R!P~BKa&DwKjIv9*}H2mqK%I(s6gb6WV0BHoD@Ki)IXDy*0$Y*GjYVb!6LhA_2RHK$s7H%F!=7IB0DQMy+MChN%tRXtW9H<^ z{d{vuyo(ieXh$qNrCuYA8!uVHYV9tZOR%fy0?Z(E&7XbAtg?q&LK?_ezbr(GV56#YblgmJ3jI+Y| zMH`kTrAo1bo2f`jzSNhiQU*q73GHU$W+XZ+X7n)2AJ9=kCw+=-7**sg5HVM>*-SYJ zQai0P;K%I>29eU`nbLQB5X!q5oI#rubqz2_rB-||I_Jv88)f>cFe5(%?cbk(N`M$r zIaMCmRN>m<*i`U`LD7%R9*RTOm1Oqmk@fM3!$f~ij8zmm7kPn3rMXK7(uUW!3W%wf z^kS|@(JQcIUv4~%I#-Ak;|&ETd9s0KZv(ZCM7 zMwSpmDOF4_RMJVNRSF?ST^%Sj_)C*CT94A)Suo^bFemvuJh5`96rdkpbM`bs(u&;R z?>+`hi1s4TMBrJ!ZWK0tTo+Vvk1EA6AiU?+Yd_L zJKK00c3)1zEfQ@SnuPYPXi!k?55AfcZm_}xuPn`xY)yJ~*#jU_ivLDpaZX*FyeqiP z$@A?<0w>O+qfffKuRtdH$5}(L@k>XPn4cylzS?M}*OMAvH9t~|Fskhbj{`vzvcFcr z&RR+otJXP}*x%C_I4m2m zrRm1==ohsc6Ng3XJ=kqYEWdNwhtITHO>rg+X> zl$2jl@-v$r|Jm;Td$>nADJFy$jYqA0Ugm#$38B41??y!XYJtc$`h#pp*@ytbKF_4j zS_e*@G`R*~b;7^!jb4$RSOXxdgjI|vD%t$R^LDAzq{qH|ViE8gGZxSQ03ZNKL_t)p zQ9QwIkVGa2s`ewallotjm%gP+Bz>1yNY7D2FU(Ho`C&_tmpWN#fNL+ z_!bHxh0gz zxIZ+!PbeOfe>GV4Y4IAx#e_i>ieD9)PvctSl6iTVhIC5k$bs1Z$JZFbhsnVE9SG9T z>>``-h!VF0I(JR@iT!vmtiG*~%MHc=LtcpLYZ$zbOPcy1*A zGrY3^=htCftCpZ(sEd_Rqj3Eiyc9#mNS(#HnUIf^k_ozjeqll9gn0X^IaDh-wz(bT z4K$yAzz`3lY1JyL{BjkGMv41f{TH*)nYxuWO%x(tlJ8C-caGHRDP9vdM~qr#8E3wW zUcL=&>NEM1juHwaWcMbfZzejZPm^k{fb5gDz6iuLj-;iUnXr_( zxFXE0Wm)bSv(VfBWV_YKiuNeVn5IH!>7Cg|??BTOY!IRIpr&Qs+5BIPud2+(#yKps zvWbT{i@U~E?uPOD4A4KZXu4<-xlVCg4*hnujg2Qs z4|vMY7jILDL{lf^`xz)(E3u-G%M7=0ue79_qy9MGAQH6IYbDc|BFrjH=myF#w z!w>J6q*kYINxV%wyce%;X~c}`PJS_9nRs|A_TMDrKLmCIP6?pUcpDpY@tFRQW^%X` z4`nWB7fB4p5D*tUXY)_x8-J878r*hOB|5`aR7#FYxI~}%U=6j%Y`tU)1ORVpWbsz) zsrbKKUdC9?+ds{o(-RLQC6UOVMwDi46jvlOJFEHvSV=|h6%>wNU%p_HTAjWnv4(i~ z1-!nc!*>|{Z~iQi5INW8)Mij$0)9!88-mN6UtWo_i+khUDE6+fjf*G9Lup*VjN3Cb zOeYrQCG?mGF(+bg6CfhReaj(btUGUou-rf?5JNhy`o{w?uMZQ{`t-Pw*DsBdH$=Qm zSo8_vBE9i8n$>8lQ(RmM%F{r9ely2@M{l~rqmtu6NmVbQ62+N9imGCDuyf&REVHDm zO{Hq(l5d!cHa0e(RrF{avlWG@45ctlts&MEDR10)dHI;wJ`m(T1a=$pYR}0`UXSbt zH8;Kh-8?R&kJF?m*m}on|Ekn#GIEg~;pnL(ZSKIWq$ll=Y1?N`7?17Kl#M&8`K1vsC^8J4^L@T5`Dx7S9~%4 z6CQ=e0&jz@m|o0MV_xs)kRBuo;CsY_Y5#U6O`Vmm8ZVt#i5+}bF4^?J9TNEGDHJcZHbm-R=s`;<1Nre2Pa>tDn1b&QjOU_K z{FHCB{R<~@mMT&n=WIH^-r_2F=KH}YzEsB3^MX*lj*%_GZUM$I_!q8X^58Y%bv0mi zI~za9Eowk$jz8sWK>WigDEh1xUejl1cWp31pklwCr2aedAUuIynu*+RK?+s%;g zn>_w}bc)u-(wRWsq0Ds)RBXNKi<;vF`6S0zl}RyHhxpK@u>B)^$Se&&!V(8@iZZ2} zw<*Ky@WCKw}ht{X1irzgzEZjG4&5S`s!v3bIR zDgH-7_f2DO6lGnsD#Mb~$a!A*-01jlv*>8{l;2|g9=%22kF|nhF+ig7%4TmwTUk3- ziYv+FeKl8C(u=2GBqXQk8?)PIyw76e%~-_a6y596Zp9@{Ol<6oE4py610V7L%)n_u zOm32UNPs+7@&*7@m*tmH>R^fr)-Wbu_35Y@d4sde$)G-FicvtJH${tKh^Cn~CP|Ie zwa5f#5ohWn7RK-Jt|b-_bL!=WWUhI_0?Dte@-K)-Mk&QoMS7({Q_pU5Y=0&3Dg;U# z6PbtdSowM%h1#@o9a|<3z)f@8*R8=eE@3sNTxw(E1A|>Zp$mS^0^mxo<8&>sRQATB zm_6i59n4IeBl&>T|BWz6z(2PClFKajU$kq)vJf!bODLe+NUgR)IQ)@Yclb&m|LQPY zEu-cAL!b3WDJ3hYxCS|%>m!4$PHZNLYtV-OrwDuY>SV!eU5Xt{L?42b{MS6XSM&Q@jL}Dz(~f_9=P#yhorV~4KT83 z^H;qMk?HgpX-iG@M`{=EamYIN@h@^hgt&HY)2JNxu_V;DllPl^ycB9dtVrnZaMp0= zyNbV=?Fph_|BeT<8YU!?F+Wm`=lOG$KHN;%Q+TLNG`1NgKS^F>-{R3jt*y*fECWA^ zop|Dtd$lJU4!5oWHhvarDBfocs&L*Bm>7*#UJSZ`Ma$sPG_?(b;Q`nJZDTzQ=F0gq z##@Jxwx7iB10-~cO&`diV=|8WHBGId;V?P``f;)AhuD|0uZLroN{2@unsTWg zX8wAWAhI1aAW9$bD!18-bh!M=c4K2>!$G=d`FRG$M=gu)foaeSfc8Qs2<#_fpsFQ4 zLR15mBx)-1Mz~JAN&ENebu~w=-r2DrD3nV8$KQnf`&}`f-zC=xSh}QWJ7_&uw0=#O zVON`s)kOv*!_tRzJrmeEzxMnK5iQ!}AI$Sxn9@0iyO#@vlWy(_#$Snn-s_ z=qbj>#s`=ahOFRD;U~tDK9uN|N&5Fh{l-QYT4u<>D9S1Hg4=t={R?5&Qk;1~io_f1 zL8tcse3wXiUv1t;@eKS(E3}!!r@=5m16XPte`w$3x*(=fyG{E)XwjPMy(kI)KAMP< zbrB0Sihr#T8usFuk3+|KNTAz~u6zh-UED_u$U8SaItN7f>t*5FyPn(xe)3z-7Yo0+ zyp4^Gb5Qb+{7r4|0xup};@ffZ7|=PSKH^fX6}qIKcS)jd$KY0QOZ97WtrhBUGO7=Q zURNcn!w?-0SUeIcMPAd2##J4ut}1h6I<6T{5%finiFpdAzn*0R9RrgCrE49OR(jrK zebf*;=0Ak>AMF#4EUe^AbAc#SC zzC)rO_kwHuhd;#p2wLhQIMVx1Efi^{_$%A-TKfkuqPk?H zXoo)ah8u{OL0wS7G;CyklBh$6ilLZ`a#YF=jqilmRI5w$PyR77wNQy}Ea~@ogCZ?x z6rX>11NEn|cIDQlZUc4~v8fxK^FDQJO7YC@GW-pm^it5*dH^nj25hW|-qrA#)$_2? zmKJ_$F`s?I;O+*7r?OKKEh-U_yg9g}{bTs23CR;iKtw@*#Td;FMD$1S7o`(&^3HUV zL4{FSmPkM4=Q$vJq}SvGMX@pELWKNNlHoKwjsJx{xP~p>jK!T*x?6Oq59%sy9}61` z(!7J4BC+UW$`zcB?9X%HnGCm~>8~#QHf}LdE>Pyi@|esP?fPVxssP{vKnV1~PwLvm zMD@-%2`1Oa8N0-uOnyfrGw7Ns(Za;G~hLt4u%o3SxL^xpB z1rN&-2J((ZZ55$PEjQlBaH4~qvK6vMPJ>4sY7#ViD+I;0mfPMK^NX# z8g?&J)K$Y*$P$utv9hKZ-Zd)`-;3AC62=0P;)~)mjATp`k~1))Ukka28n)m_x?Qwz ziOC57d}zO9$Ruc|4OTIcW)R^($a;-apo<(JJ1zY<6L)v}-ps$|x)bkX>H|U;dE3*x1E!d#-o$T1>ymq zt|}z^o|)Gv_!f?)2o07vta*WLTtwUq0~z z{Eg=1Y^aKs9IB{uE0wJQeqU(2pkjVR$Lth-;@}xA9swar8~oQWrD_52UeQ zK)f5v_3c%BU4`zze@ zFU9UqiJC3-Vq?ibl6)CyF?3kan+f1aJ6ssOQ5Z?g3|ZI5??Vk8#cq$si;&TsBtN9( zt@|>u)r+DwWiH9IcO-$|w7Q=3T~436hb(1O_HFVo*C&Ops&ce1y3YE~F~mt1p@k*^ zF$AL}e|LU+>e(0uIruwAQ8bZw$rddt9{_;QN2doa9(&4aqz9S?$An`*>uZ2%!f8u` z2e7Rb5;f6rvAvpxc2<+|@}^O~Dd}{W4uH~C#tMumbG%hTxr@6{BGI3_fk<#!825RjC z*AjIM75?3s?Wt#DBuHQOxPzV9#0z4V0r3dTL>yk8!V2_2)A-OKKx%TS!*n#1{IU}U ztz}62HmvBx4p^76XK+sY&nQtTs!1}V7_I+eTK!f*2Q47hLc36n{FTxlQkWGWpW-jP zIM(aiEQ^b_6nnXNMi*>*;wkxuo@jf6Rk>p7$hOl@KU7J7=#tN`vPv1+>f=?GX?KCabpEg zi(JhZDfkwzj`D^>rv7;FP}X&eg{J$TK!nGB0I=Bu@SRBP7*-E z8CoceKt!9U4Xntn2n6L*zev!6lO>C8Ar`em>bsD~#UH{Svc@Dpe{OR~s67}p20}bO zKa=YrcOOM>$SNG^_}V4d*Q0x)0<&xknIx|GZlIr;9+v+@d9+19e8U=`BP+|xxz`07 zH$co${H_gq=ItLf7snZY9pUmGfXuSyfgxzdY;Em-=8{<; z7=H{X_z==ZX6Vw^xsBO)s@IpplMRtX#P-G*-Usw15OSV7?-Brr570%aBSilm0U#g| z^*RA4Iia8_@VXv>-Xz37(cTgxmyu#a@Ms?lAwbeabGVz2H`ECdD75h6SqudDM?jdw zu_o=|-4yI|5Ru~0JHS6`koHPj3nd}4wRbAx?3shL8?Xgs8M|>d9!0A}ccK^%16K6t zvYaX>;*4SSl0c~lo16!rCmcZt{D(XM55@y*0AxHczXCp5)@g_pXlMdInn;Dg99pLM zG%$h>ed!CE^c@qUj#}R@YnhG3i~r?MR+-e8L^3_GM=1%RC1sG5jEkUFk_E&4gv7|dQ$3&(Z)>pjKQ1xo2z zZUN9UggZ@YQ$Q&t8+W2lrTQ}P(PB5m6O8$yY54f$Ek%p6HzkujsQqxKro%uf_Dakz z6TPVKkae9&k|!YX%aC_*knbfDblQYrNUlB>5VDmk4gSQU2}Nq1AjvaZQI?h2tliw- zrX|0K!6SY_P@d`Xjg2MH%)DW$Dh=i~N!F#fng*6E4HY3d{5t^mZ@W^9t;g}R((k(` zwGNcraq6Ow#i{0ekok(LxJehWf9$dQCgKtBlUkIWSz7D^P-PRj&#wRhv4l#SC--qE zBtXi@5Etumjk`@5jXt#L_&OUV_WtnJpHRffAc%|>j>ab|uE&*Enmt^jqHJdqpO5Rc z3?dO~t(nTia=47UHatGY*x9taSUHX0EDSusIiD`~sjf z3rqrAge?&Wv;qwqYk(`J&f?p)LcTE3Jjj28i>_N%lx1By1e8jON{0%z8RCMxhX#wH z>{IqQRpr!Eo)upog-`U>1YP0)NPz5-aW)iB!j@*>R#qgFG}5DgY;CF&^BU~Mlh)>< zjWtmpREZz=))*FoF`IzJw+tSUBvnVu%~*((ZdjVt58+hxD=+b&lSBFYR%f>2%FBN; zxyg39e4AD`M4JAn_TM6qA22&^{4gjOar~T4N{}X!yn>k5lwpp>)q&w5KpPtyWwq+N zw3`QU#ODAQUkUj8GY%)n>YK?89&Xb{M<3ERR4|U#d;S2t5`ERkqDsnzmY~?t8IGRmcq>;E$$0tB%QRhWh z`^)HHP7M+OP#Po}1AYMbaYuwo8@C#vaSIm8%fPj)SrCq6LWP}6xQF=Y`16hzI=&EW zth5?Q+lzz^j)Hu+d!pFt#!E0;i3sxdw7W9SLC&uV!QI0!KF!wz`CEHE68JudkstNl7MFv3>jmZt;@e(WW z2zzd`cCDWlpVm};GmL;heRr&*bz;nDDB1sKHWZ=Ux)A%yE)<#H;3_aSpOdh}8x)CA z17Tx>*al#==Elax#x1x_kEl#!roY>1>|CN#F8Rgs8{Syd1JJdssU+)MA|=Sh$Zq^F zvP_l6WnhJcgkE?XZZ0)g)MH3X0eEH5g|6WibN>^GcTq6I^FH$WuKv6UCVksRWLf@D z`iOn_tR<5HJ&D}UkYw)5Hmb|xp^pErbCl5{8yg!Ni=uy1pO@LD=efDq%*|pRy2M2n z0PT}nJH-ScLf$W1V1Q>*#w6bSj6$y00 z1|rMy2PG9Tl)xZ_8MR?mf^AsNU7KB0k@O#_z?p^YJo$| z;H{{#u$opUoW#|+zU^HDSnszI9YWG$`=b!nTx16gn)QzOT(G-|ItZt^0eQrKnf0S3 zK3P3h1>#9Cg77%@G!T4zA5D2bL`0A%9Z|IFdAwOLe1mAa0n0SgGK6fbgFdD}NR9!` zsrJ+@5jBW^dE@Y^zKV{J5X=V`MYx1Tr@(`~~+7nFDanki}6 ze=uutE%hm@jAfVg4Xw6t_9O8YI?v+>HHj(_3#Ax>a9}0Rzm(p(X<07(y}Zp`jxTZE zrlM*HN1}6=X6e!CS&T~WmsJkG%^v_^G|%|@5^$SMR|SmAmgGIf^!P{;P&}qKS2xOh z>Ps$Mh}eOp%i&TRwHMHv{ukFxYw*Y#RBWsUgD>Qy7AHEx>Jf}ZWV>#KL-k1(Jh=zp z7v!o|uq0Ua6rhcbr!ZhfR%XM>BuX}I;Y}_98>TjX zE|SR8;FWJq48`?OPne2x8;B3BDU(f<$He{}ix5gQ<5l(B5v#arDiyAViEm}q)@i}; zv9_@>3Y#+@M=}qbjpFgCAMR6xmA?f1Rgj9tns@_^kHR!=nynV1|I?dB>RjgccLi6O zyLKmPNq9XHWQ=hH!Jlghs)-vShzJPaPo01XAx4OZ;BZz9p%Vtx`P?v;housk1bL6O z`qu9fJAMbYU^i}(oZl;;zqe+Wv74rdC7LJe6L!=kMBYblt$lEN05&4FoGGCkiytCJ z41=+ym#k=4w&Rexa8Etj!*DR12$bvtD2PQ?2LGJ!xD%XK!{LuY1VrL?eSdQeEq`6y z)H=Hpeh|CUi@3FU`s9Dx)~d;KO1XW$$OEu)^y#vMyb*t>001BWNkl+D)D^(brOA|BXyPHQpD}@JbN7j2WvG+B!-~FSwXMHKF3u{d^L)o@Pcg^$ zuo%sml=H`gO+DXB((HWESs_7WO>4qf;IoNeB5yz+Bc>fC%$984QG z;lf=1d}#Ss%(JgXp$F{#;iF#2eJgppw63Eko0#y6JOHi2b_?YVkHNga6eIKG`Ia0Q z28#cd1NpyjwxJLR#UV`SR_z_5+-2&!1|d z#qq`&|BW<%J5t9!@rzXN=b-_a#e)6dJb}HK;{mvN?Mh*SZ^8GA=50D?!pJuAvcc^G zhEw|{O_S~bq~`xjvUXSj;;Z413B(QNl~q~lrp=}HH4j@0iYu(fGILHDuqT&QD%3C4x(URh2YC@~L(acGpo2K=wZhNv+7J?ZF>_FCY)r*w z-dpjAlEZ~PfGoSD=(q`tv2I{Z~->&K9FAv4%e9urtqg1IydbsYFK)7pqHOV;XVAcvB5D}qHjn%pyUKe zpOuW|NKPwEWdS$goIL=0EIf({&Ht22a2LL(ez`c34yI_+{)>rxfv9xVVXWEHVF*Zo z7^8IjrT|odJKVJ^1hy>A+7G}VRv!@ZMs8{o0whNkaT*DV84%#v1xI$jLX+S7RFP}J z>f=Y{#P41gDhl0;TO1*ik zSlSKv&0|1U$J2pfDORFo66RE~yDNwEy$<3g>t>mVd`NjCZLMp7GFgT4de;C5M91Mw z#WtYuA3}QKrXY%hAZGzSS?f9In%265<;VWSySgM*elH)PsD{1^xjhW`iHB0K?f9aa z?%jqT5W-)F-Di{W@FukQ;YGL8%tG8f;G>BAjzQDeerJ8Q2Vi4kBSl`#y3dy|yd(rf z_(OL_Q~JSX|Al4(05m?Hph&~`gY>fotQi|nTD&}rC5YJA*jNeEjdCd0$Le%>Npc!Sok6?0@x?RV&=LGVt@7BA*hD9%7oUB6exE2J8~f5Z*}9@~zsBptCr%;2Am%NZp`o2OYSM!QO&x*F)+ zT2^1N@l6xnD_3CG@l9Q*v2xuWWVasQ^5O3dW~H!Y>)1$!Vgi|3nZCaK<`AH4V{d2P z#(dniMBOlC+{-}ca@doQf0Kp< zLuG$8Atk0vB<0fBW$SpLUhhrA7r%on%U4MO*3P6NL-S(!(%2j$?G(;G68j9h%8Fp&gf;Q(fGQN z?B_WD$Fci+;||=*XWim6IamTfety2B<3F;SAz1)K5AQdaS$<3|eMzr9j}b1>ALG5V zte5B6+!NcUmshci9Z?F&=TSV~5q*3+42{&Bf>>&ExJ(PNT>DQ*&b&!305wZQzEFf? z4|I{HbK3vPF$eeJYh?EB&+qBWHDPkt&^A{&_4u@%kzbkliH?X;Q2-@WdvTbH8y$tT z1;5z?u(7eR(TZ%GJ%A;&jb!0;QLIYw*^%s99oyL0*yw?6Tk3j02zI^(NTNsc;`wI5 zoh$&Nd23H0ufwQb+h&Z-{~f^M&-%+eLeh8=K;pk*(r}Lw*_#6q0TQ6l^HJtqiYjEb zdHm=Xt(VOW!ug@6!|Yr354eBF2j?@Sq{b-yWQ&6?^fea(;Wizg#!}6;_N=i~Q^6>D zCbYQ_hnRb&$aexZYy)PVV{uqqeJ;6`hqeb`Lt!;JvGD>lh_w=$d9M4rEDrTh8J0WK zUn(R0VUtHk?rGpoq?1YUa8qPT zMDDbQVkr#uI3ba?_`C0I_yB|tpDAq4zl2`txuxv|?8fWCYOOVv9zLaLJ5CQuZ#B$W z!b>eByq@&>aP93ZZtwsY?#*tG=XQ~PEv|I!kF&*+CIt<2s&%B)M@cTydx8c`9+WIX z002aQKtSL>Bi05?it9l~(SZEzpIXPZ^ zv5dV5cw=J_zG-g!rn;O2MjN>;rM)VDTU&_}OV``O;`AX6-H{1P*FNy(aDy3wKZWa(vod4p zL_p-t_81-=&Vlw8A|4HOrd2WHIYA?B8#T>Dyatn}i8nRHc-&k2-=6e)q{L5Rv9=LL zA`(Xit*ZSanjV1j4SPZR-`LpL5LiYuM5W*VycRCMOvSzudkwJha*%ns5wKXRaB^NH zACf%)m#CL7H#o;#c&#_I<)_tGHR{GYFhYnlMSxrl6KNy#&R`U~_^WSb_u~#Ir_?$W z;lgv~v5kw@)XTX*Z+Go8P1#E_gk1Qt^~z7CwpmYMYL zm#nD%-%xnAVG@QgXRfj{NOvl``| zF&uKdSGrQ}$0J^SU7l6nQu~zh8jh{-tcbf}ah4Qcua&GDbFdaeT%=~^DL^%0j{54_ zAxRq>_v7^T{lUP;Jpd~sX&o#)lc}r?8HSk>U3@?21w&%iF7}cAajx?)^0Mk%YM3-B7qotSl+Mwq)H9Sc@SpQq$%ExW@tzD$!fqotuSzdt=g4*j*7oYJUW z=F#|iMtC>%8^dv(Aw-JrV75#PyJ~!!)kLvU{DXZqsH85#zC;Zo9(OZtU)u<+a`ojyop#jg22ciRm*Q z=M&@P%Fv?51;Er9Irzv4fC%H3yUtAR!D3qH8%#?Ru~=^yXz8FN90Tni9hnRO6@Lx@ zCiQ0jL8k7R2I)02n%$D!eTec@H!C*)Bp^bFdUh;>D3B-|1}OmqtfcDt%hftxbKj`(sg5FW8*H|w)^jNSvYkQa68zf zIXsm4yD_k_7TVbIMQCZ#Xc8t+nqs%DWJWJ0`&hd{KA--VT5eY8Guos;ijh?|cRcLe zJ_-nqz#EAAyS3f+*y{3~VLfKOm!kFRKLwUpno{-CnYM-i&Bl;D6&shaTk&BG5f5W~@$JHT zDo>};Jd{4Q-Z7JrpD_v^-kb;ETs31UP45qG%Qn_(2vFMC*w{FWXGO?^r6aE70XVH{ zyj@3G1G^O;#uHZd)@(20McaDYvJ{$s2-k@wbG99rfB-St;E@1OeK;%%z_2`!30zhm zKs2o8A5IgwG$rFY=M@4#{b@4QXyj|4$+`ecsK}&h$mlz;{TLe?8#f?`8d}c-zynyj zuq{Dju-*=(4GW^5ru5hwwl3ZSi~;n`A(t-6u?`4^d#j@op8($ojeju}{uye0Zi@ls z2C}+Ys|v9Ir(#AOFgJJqG`cp5Y;0^?hnJ8~37=<%yAU;NEC4vp?P=K7lVRBH_!^+P z8sBwWBLM)R{u-K^v)q$7SI4JwLHlC)pqdpiJ^tZXa)g_QHcuZ(h0hWtE0A|eP|vw? zxs+xFlIuQfBZJ1Q0lcxXk-?Z4#FKbTWfh|4wh*A60EHw~{pIORIVr$mP5ekTmq8&4 zBLApkU+YPFn04gG)HS2h;Tydqjp3w3Il7eqfHSXK*+BQ z%w)_0MC>Rc^lwh+`cjrV_+?{b<3TL226+Yq|887`RcAZ(JFd$f?V!mmw8Apj!Vaps z507a7g-xQAxqbnLv27ZYe`w+QAtJj$?nqA5>j19ECvPjyC8XI2ELQ` zHhu_?3!04=pix#o%1r-OmBusa>RY@|ZlT*cpr_WWa>d3V%oIA$*~ZQmTX2Q|0Dnj! z;77g{uaRvFh_?Woab6w(niO4YyXuF4?O&XXc;y`%f9|Vf@hs4J`%A+5=%Up>P_#uA z$MSaRwW({xchusgXy)F5JRxPy60B9>e>F zR|tu(l5RvsQRXdV;XYv?u%ya6OqX@y^N8OhzLkX2h21O4-h}s!y^W1NOyTiKk|d-3 zuOqvN=q(F?aSgUc)87remF<4BjW^(pUEi*JtGYQQo{~gFF%;jG0NNppa)EIBoFKP2 z^e;fJ5qxDDf1-;THQc<>)bJSxrpCLR0mQ+P)czJ2I?JKn)XOQWF)F%E=y zSvjPJbegzvmUxCNwuT`7tCHF<0~A7kIw0$UqBYcpfaF?c!`~PH>=REvDasm|X<@vC z%va)f+V(v)y_w8Y4YTYf;FsYir=*R+*j#iCeVeYDr6v2E7LiteMV!Bo!7Bgo%vu>x z%%gzZGN5&N5SBj40i<0E48w|b9WR;GAI1CS!~1KnD1N75Z?EZj$&|==(~2~(Lj76& zdo$+@4>doTVLt_=jE^twgpEO1lLt=o=R=OoY?&e|-`~=Aav3`HUWA_qmEXz*i6>w% zzPN>l!+_j1fQTT9@8^Sb!l9z|7Dx6s$ss;Es#MnWhYQ{%v5bH&kgx!C0+}{Loe1-3 zm%=+j&R#&`AavAp0DEa!EHcx##P6Wv5dx|SBifZ{kRAS1CASA)V`F2ZhKkwyNB508c7uU#TE&Y@ERaxn~Agj>|R??I;Di1s!Rhf0UFemIO)R-Zenv zV~0B9_!U9vt7EnuZ@d(Z<1^V31ACr(1$HN0LLwc@=Ad=)Y7c-w!+Q4N#a6BOpIDK9 zCB}~T8M}j?#vSsp(pLh??CHE%?IXerL5Cs#$eG)REXv8a>Om&9 z$lv)Q?%U`_3rlflwqX(7SQxvX&chOoR(lfP3l?sP$3V<)Aa;h{)Ine30Z7BF-iG(r z;Hy9n^aU}4n!hm|_zKxyYW`DQ(;ID>bORxOP$z)5GZ*hcQKIR zdV-%VtU^aS-beAq#>P!B#6yUT!>Sk6^qbwP3Vz7~V1eBf7xDfYd=(zjlkFJ7k$8tP zQ)>QGtmuHP3-{Llb83M!}0-BhMr! z7l2Ob-9p8CTgJrT=8DvGP}f&Fu^qdma>9eIz%8~0fUpKYB;W!6Nk)_e6dBP;M5#D& zL=Nf7Yj~xMdnM5u3t@qgcM|WVd?1RAKu+3naULx?X8dS66`_#q!`nMwfiLj@Y;0UY z?}%H>kZzLG8cpeON*-+1S{)2d@!ja$XQ(|Ew8rCcbq6kax&0 zv>onwJU*-*>Wy`oAfc?Ui|(q`tqpjEOOt)Fy+8m=)OX}|oznJTD~{i^-{=4%mM5R>O*O)^Y^B7Lx@Ob#c!sqH++L4BoSW$MHS|N4RGg1 zYi;cL);$2LVa1tqMVj7;nWDC+cqaHhp)XEHco;!a>t^QKIjX(7wd_J#Qk7+A!jk(g z0Kbob`9iRHTA}Pu?t%D5&f0hZ))@HrV}RKE)utN{Z4$8)SvG!Romh$QC+D-h7bh10 zGuAA3u7fsK#O8pdaG^W8x84@ZY9v7wdSUx7M`HRxts19q9HO4M0xzlZ+kJIp(Q)(0 z_QP%O718yh3h!Oty8_e7{*HQHJ_ z!x44)Cc$(v1ZYx&uhNejk6?HIYPcS0IJuy5p@Svyp;8n0c$jGGPYOC#0K~Tnq$x1* z5GM)zT?F)jNb(gk_vAE*Oha61A53jpoxNE1PUH!E(4g;B`5mDI~$~7_2HCJogn}9bqHa0pCZSP!U zrx%AJpHm{@CO={V8rg-4WirZVe*q2$0hVk|TW{Xj*!WhMQTWdQrFd3nJ>*__0Nexc zMXSo-zNW zc}S$%u{XfSA*IA8LJ(W#NWG7)hp^2y4h0Uxpq6r&l z(63T4M^Q96y}!vqc5X7c5i8KJF&9}zUBt#)!%N7l;7zq?l?v1A#0Y8Ii{+on$6a)u zt<+Z>1Nyd=>c+-~jYkG@p-}xuZV8AR7ci4P+zLVdKx}WA-u7EUV)ym|LoD>wyBj2d z#?}Ul%G?S@*wuzjpWBT8Ud*0x3nt4~;3Z^M@UmJEc+-K4%Jx6$wkZZZE6ttA)C$#prjCmg@L!e`$REePAzYV=Lrvp zfGEx$#G;bo#)RZtAXT7D-uUPOD7omwmiZTOZH(oD95yzd05_aJxCbDHV*10{qU4tl z;hu>gOZ~j%z@cmSiUq*N#?9E%-$XpB+*JkgfhG-># zxNXwsb3?jAf0FB9vpA#~$17H3UNPyZzG z_-1ktC?jiyA?U**L4yqb12FA8sYiDhz1stD1u2C(bIJ@NdAmuc&Lkxl{Yi(QCw5=v zpq&Cd%eZ9#0SMz4z#ulAs}8YV;zJ4$`F9o63$f!&;CY$5y%Mr%x6 z=u7*Wdv6~spV|{l!pD#@zF6NfaJq8L_l~<4DP(RB%oj959w2tl99nL z6xfCZ{y)n^PG(y`Yz#q;Ar-a+-pB!st6Z91K57+nLWUpGR9N*fP8VF#O6iX>tK9rk z95KBWoDc#;=4IcD&1X+6IuEsyzp?Q`tZ>}IH8l8HErzm*78M^&TjD z+s5LfmrlwX8<+9Lvh^W|kV1k#^ix}iMPwF{!39t2N*Ci3_kiisq`!HC2|Pbf5MHUx$HdSUhV*0^kUk7re#_vQU;;3;q`9iaP8p!=J6g}8(%%L-ia^q z%iPRdy{+~QO*{|Xoku}-q5F4a5o2Shy7MUK1+U@SfTzax8NW8+7G zK0wBQk08*Vf(s=`5}Po4^gEC4bzwg#{+*WE>DMPa)2H8Cna&9*T-*Y&#N z9KNCwHDD&(d>l?QE@|t1Pd1$~@Q+|3c_c4#HvS=cfAe@>ygN=}(JFOD^4f0cvvqr{ zO>UlhzLTS$LU-q(GWN6Xh|!XjEORF%aE$NcmU<$Ft-nO(3uc^*=~UJ=AUwV0OTRZ{ z0U(Jc|FN2CGrh&|PjXiZWgfXZw~_T+i5n|mVPnZ=$*bUQV${3HHiqF#8rEJQ4$Em{ zV>~eVIes)g$af~0ISMkuis+~P$Tuo zEd!2!H(N2j#Q{-q=_b zy<^Cq2gLEX-hKgGRHAQ;N^_u3Q!|zg6;0DO0jC|CzA&DKiwL2&-uX@dKqNllle-SC zfa_SVVKz2yfYj2`hdBgy>4l-QvgTK{^Ufx|yIFGtJ!acL@xK{{n|-pevC)FwG4yR? zj_dIJ(=Hw*n>bdM0ArhJjt4;cbF!xbsl9HC^glnAo2l~2MhtdCEck*RGH8q5#>Njp z4V*-DkabhMetFQGP)%DD+TluXt*I&y^jO4^{5MSd@5^HNLIKtP`4mfHZ z9{RPhvEfk`1doe}JZ>g!WN~?0c>ei4*fLaNx5vh_ScU^H$9t{~yIxHvLZEqR;MxKp z7w8g==EddA0ZcA#2N@^rX=+GbQ!cIY25fX;x7c~~2F$F9D#4wf8CeG-?3N{|bRsWQ zzcXo0k!@y=Nt$XVD`M}?8j4;P`}OAk=F0cf?csCq+St$v2)8Kq0q0TVCNmxOoClY& zODkMh0Qe2EMk^fK0NyR#N! z%8G1ktblJ8?ag(gwO4{X1V%)znvyT5`)Q3r`tkLxEda_E{A{oc0Rm9Vj)oA6C=xy3-q%S8lFH`Zjr)0kZsyPMzI`Oo9a*iWFVZmBo;PNu2}eS~;uq)Q*(!zj?h zO$es|WwPf_2cftCpv?6FWQ3ZJ8cBUz4)AFzZ?Ko{Z1i7xL)UXUD`akirfnOK;Va|l zbfvnKjTXjz*7>;cG}^6HX7XOgV9IVSF4lH>@+mjI9J3`^W&oIXTk*{r@J2Hbg!bib zEdzt+(JflsBlOMz_T?`~W(Q+`=`iWs90F8mST~k04Cco{S^CqR0SGRx3lWSHPu0d0 zLZG!j7GvK4UjH^77UWkZ3}>MVSS|BGIqNQ3H{MLQ`f)CgZ5{G z7sTyT{bLp!GhD5aS2WR=JCrXwUlA&{Q9_&ZuyC&<`%41|1<#lGKddtPcs) z*;A9<<(=xzl6TOtUa)tK+J~44P;7`sxEVbPJpkWJRI+Oa3SwG7_XfwoVvBXVn8xY9tog zZiUcbSn`NK`CF#Ru7$a&hegyDidijRt^cw=eiM_Lfbt8{Jlc{Dq`1ISc@CQGJzL$c zzB+wFPGYzAzYwVS^Fa(_s_EGL+zu(F8z;J!^i~$ke|{*Lo&7OQ z8O5lDctbhihg8#qt3PygamxW&jYPGkZi$?kDe%fMphu&pt1go?TG&@+9n_j8(l^2x zw1{y}u${&w+*ksO$ZTuP-0;@g8_FNRZjP_P?#dbHTkPEhVt+R_&Os_&v__nT5k;OD z_R;@$=#8Wn2FlVu?bA1P4?y}x1Okvh@P}f!XdoVuSlZW(^@Lz^Sw=trAF*^3ZDfDC zVF5OsiszPl$O4zMDVmmit;L;u?XN*vMGsr>o}ICC)Ik8Wd_1d7-w2Y&RJ%J){&JGr zd?G^{sG5nDpkfQ_!ILx4I=;InTH#`u!=+MUQN5dhFNT!Ty>rUNy-jQGwDfwh*9E;x z0Q?_g0F(I7H%bg{7{ikN9stXnKpB$am%`T8{!Qb(@0140St>-raI}+CG;!(5|0JBp zW>98Ba^b9&O0jt4F1jL@lypyEkZLuc7iXvmH>)1=?6Mas;>j7n@(-^8R=`8btX=yN ztKf4W<7(sO7&)zv0Vb-k`}tw2u?nIgmyDQdI?V&{Z&*%XnYvN^za+HP-r>(Zv}31y z$52?;i8lCiPM=KP-;PJCOgHjddqpc$ITlJ{1SxsXan{f(EuyzcPA5OGjCr8c#qe{&@5hh}?ihiNp~Dsj z+)_Z{Pb*FNbXhI5YXJ}<-PtV_-Xscre*Eazs*+Q@l1aToWByjm#>Od}&=gi)1C)p( zKjKC9K1NVP2i-a`{~Z5TTer@XSArh8z!bHx^(YtASR#ek#Y@z__6B{%e17SDJ##&P zm$1QH{G9N6IYuZ81N%IVWO2xb7qZGPfZ{H?BmbC=P3r&aRCg@^<{Ge`K{E}-)zy&| z4Ln|E3!q5)9ayztrlHl}G!);% zgtydW)rR8e6m0yxr|<~tU#V~T-Sas&H^JlLxdUs6TD1Qz`mByJjq7+xsk26U1~wv9h?1XX&9%iFLGSsRa|ApnnbloX4J z|24c@;=BNqT$n$@%}GqS`*~x7VOadd<$Uo05ag!DP#@&} z?I_*7 zeQG42ZA2e7{UbwFMeqh!s<@bc1{i ze%P?uf>W(?_sp0favANPAajmR5$X+8+Su>m;&j-=A8*5ep{C|hWdBq#><*17dk}to zH4?E@Gh~T*TYt6Bfl>WrhSv*JMfCu(L@#o%_D}pbA@K5v>BV%pZ~8x_QJXr+;)taS;I`1&f)pQ zhzn^sU(uOkuue;qC|QTfHnh)zu4c>j!l0K$Lx5ER!}mv77AhX7&xXO!I5 z8rJOmJWfm==;OLJHa6Bp>bz?lvoDL>@W9u|q;wK_x3l!s#OL5E)%U&2ukwd%EP)tH z!|nvUkKGu>*h2j<@pAb?U~~lG{dvbacF&bltMYM;9eTc{SR(Ff}(`8#1mBMOXSC><$qC zh%YKCG7GVkQ*d1ZkssU0eh$q4e&ng`>l#17Bi$p9uL&=U#9rT3#T$Z+Ne7mCI_Ydo zp+mbg@4#8sKBO=gkmj1kch04W02%4Xcet8yx7D0r8J@&Mr-uw}_J)D=l+Ito zBFtoAVbU17HuGHP`8{gh4>EqV_A8OTcoQi3`;I|=H|Dp>BHU9XgIW@uDX%HRMOtWM z3G{jZlC`6@Xp(%!UrE-!ATukhOGhnP`|=?{I|r(YaC_AXqJNV|AL`O|F28MO0s3mqpIQ+51|m zhHf&Qj};oaNCVS_o}qPx78-$^v+WL%Ji3GtnVri+dH}8rQ6b9H1!-~zSs)jGLI9ss z;l4mvdp;^yQMdvM?=tVl66ml7EC7;y{}!@0eiEq=_>%clMb!3!Y%yr$C(T6^0?OU% z`aFr;$rFoW;zxWQsk|%n=pz*Y8@i@a?T5bDOev!rb|fQmm0(1m)Mkr9Ocs2`G~FSKRt;#__| zmU5nKZ2TZD&T1&cAQO*qNE3?`B?2PUQj`FZKAsZyf9g_R8FN1Y`9S@TZbI}2U5H2S zqEh8+tkqZNXE~%@ak;4CSoy)zwf_~2YwH$Gb#kA|5TI_)1{scH?bQvZZfAYx$8#M? zbh_qP{Mq%c3}sD%pThsEjl9+9DIo2wbWu3AtnR63NA-R)IwBeF!fcZ4agZGseZwXR z+F|iP;TC#{DuXPE0Fg+o0S>7^!Vq(gwgu5FT<&2|K@JgyyC@&^F=t=@=q70`YK0;E z91Sbf{$|{LR6xL>LK`*JnN|D)=o+5PSSw63!9sxU>|hA?o{SfRe54S%U*iqI1E+501B+FwdHCo*{N`e=Vxt{(A(=kkm>CNgKbNlZ@vi1PIBS|Gkl4z3xuTRM!8CK~HF2Udavv zu?;Dgz~dVdI{Pq5j)iA6l>6aK%dFC^Q?OR$z9h2JLWg|lRd#!;Lf))Ctn)3;DK`K` zA&=s%Xkj+#ByJ=!6P85BSWM!Vg{BRFlpJ~FKO)*AXXx_mQeF$hxDPLX@JKBWx)&kC zbFvFE=JAt2nlPRrsetpc`c^Ims4Oh zyPL1NYKNsZw7TaSI-9+eyt@aN9pB@d*+4hXuhm?4twnAu=LY#OrZ!pr6nBFdadG@y zAq+V%I}Rcdp_AchmOi@NO%$l_r7=YXb5cU=Fs!vk&SIp9p9 z@-!b7_(SrqdcC7o`o(EniPdRnHk8G!1x0_^0%G&Kabq*DrPBW~KHu6uJ;S`4M;oX=p^1zH zWyVSeyH4fLo`%6hNt-=rh(?3}DKh!-z_A-BNrO_4<_=pVJ0Tm4V z1PBC(OyCBxxdHt`%jO4+TJ8+-07wLfZ23rn5s5_Cj&{Q&eyfC^|%aPAb~PREOKhYi)o`2+#%R zL#|}k76h*1B;N2*pX&YawMhR$+Zuq3dqomwg!Igs{K@^3+;c8aY62Dydzb{*De`;R z19R@cL$?1b=89W!GnEquLu8GCg`AoG!bLdt%}>dQM;wq2Z?*lthp9))HAa=6MUS!e zH(-}VX?Qgcy>~Ev9;ANo-|>8>T(tFUP|^I?lf|-Fjkqd3YW&_zzsU;cX)yJ{?i`fj z>Tcr)d|Xqu9NTy)PV(tc!xgf<^0^=!XPqWwJEC0D zcIVp#s*x$%kP88_4KyWkGP%U3?k^tkKZn&Hqvbkv?D+Qau3q8d$(PnZzZqrZ7IE19 zC50Sj8RU`ui(v@C_TlO{=mo&Zj`Yh3 zdgLWX^w@Arz%-VpcMV1#HVyx3OEM{|9+z5SFrr&+8KS@b^aR=bWV6AKwvCtg0E z$5@OKS7Sl+@rErQ5u`}u-d?WWIJa>8*IzZ|h`XXe7U$#V&`QC80rXk#TG0<>#7_iRub;uNQ-BT;uR?%IU!IDUAfaR; zcuxxX$Hv#eG|~<%5?Xs0rlnr#$E%DJHdtqINlY6RB|tiAB6g%*x)6|6!Q&)^VN z$~pBPKob!cs~mdAbJw#qUyR2C?jdT)s=p5eoS_|*wpSSD#?5%^P}-fO`dF?=K7&Y+ zL_tWV#(q<^?$lB9iH9nwK}<_~PVKEEld$pV@B>5(&b^K>$SeXWy_6|1JbP5pYjZ(Z z3rNC0{})4by6Qr~$Mr>Ms8496;OkQN;mg|Om%sxN5h;8S7an!@U9td`kg=RM7}V3v zFwPo+LVDUrMj3i}8XCN7#l=0)=kbGs76&!m08HcYjSE;}e(xe8u(EUlh#Z7VwKaF1 z4Y413UN{1MK8h#=K*|-xmjo<+9@;4rx`!IgGmZh}p*xMjL#aoYk@D7}>V8;$7y$0F z39hC2vQvC*O`>g@w1hlH7N%2^?!l)E%p9Z9qxz`(aZR7^vW-RzZ$Nk2SYNhFF!(er zEz=gwO>_v2Fq0xik%<0WAmh}mob4^S-$=+MaMqO$b7u=>5$e*;$Ok4`#b zSRf{x8a_cvM_wFq4xH5bC0g6LXZt$)Uf|>o|&2X+>~|RaaCP zkM#{nt8+}7R$|^Vl<8{pamAnzh|B>*lB-m!)*AVAC*WUHwWD%Lq9Ztw);X2NN`?++ zmbneCi@a;EuLQY6r@zCv!59bZJz5D*+k(u-w1_Ga+HSCLsa?_G(^OBPbCeYuK|JhQ z1F$zq&2jOq;L9Zf`iSW*A`wVtk=V?2SGE6x0&4}b=pa5%ne2YQNs;`t@|-+Z#=j?; z{?0->^@peM{QN$O0+EkDd7jWVy*QLWe0m~zq1a&V@H)acLvCl-2MSr;d}vi~)y zVMAw|-wAUnTY3Z!A^%d z%p4?iDzmIEC<&R2*8q>m$n%{j1`SvH)1#aUO`kq$X@pJqraM@et5r`&q-Q%SW1Lo@DX{<8w{;$j7F0Z#>r%q1{{nJ z&Kl;INxTr0+XK=%X$x5)X?Sp<(bd`b^e2@K#j^_X6hu0s?0%K-nD|!;u#$@~0Q^LL(&KP5uCT2-X+B%_|Ct zX={M?eIvaK-+}gTqR?E-GDSf{Z?iP;H0>#`;OI3wU^l&YvjA+;?#7y7wmU0_rPcsJ z#WWVoNy@Q!-0U}Sf;Ug=rjIXx*r`G81x|w|A)WzRINT>gy?q0Drn;cZJv%1^C|)b& zIn!g@k&!nl_`Mmtq)F!z#Kz^OWNQUN`U0cTh`@i!09d_Z$`PWLYnMD^eoV;(;^OIU{GvV1^JeOISrv1^J7 zmRJ3W#J`Z!QPL#aXBf`q1khPJ`FDABR0UO`^$L0c7*0y~5M%$w1}YlK1WDIhTz+{5 zv?M`x=YG?6S(IUzJm-;RvcZMy2IX@L^f>`fFO3Sla3^i^_^s>El;Je+2x?&BQRtaM zRz&$A#t8qkEoU1{mJ_TR@^&2Bp}H}jVPBsd^(9~l@@I!3^8&lTsbfCnD!+3%VoVd^ z1Ty&l4BrAvXZ>!VmaU-=>y_K^;J6S8gsE-5 z{4Xyh^*@AeONe&7GQs{4&7X&U&+dn!4`SkCwArYGJ&C^?&OA!KK|Fg4TWQKF6q7;d z6!KZYv0S{V3a^_pI^Y}MNm6#lzE*e43?b=IdDB}oj8d{q{p1QPy+!~Z2Oqv>z*`bx zWy3VcRdDjsQpKsp36l!AJlP0_k_?}Q_Nxy+rCN2tU~Lk)$!7}mFDJg zR85FXoTR%~*ajV+Daq}#fkq`D#Ucb+A{{w#rfXALqjOo3K?ABt8(A*lpzc_3-Aab=b zx?jRmaAcC2U7T{y7jDS{+|}rq7^$|&{U#JltAzOk)lAD(bL`5sb*@18jtG5AAnh4` zJbl2&jsrzUO}~w_rsvq{HTWpMVoI>`yAQtCUFp6f$lp4<{0_M!1tuAC!By$aHP!&= z_|{1?djO!9VA5+V)&~9(iFh6q2g~IO%WQ&7wS`e~lf2*}V%>s%2^VglU+1vp0rzI- ziDPRWPUt!0X1fun(q~GQt3u{sWGbDf^!ek{8hzTJxe0~XXNzoPOz0(*P0z?H%Pm$6pPn0|TL<0zm z9*Gggm5I>%akn3%iA1kv>?9aDz}?7@+ah!lp^(i}#i*FRstP@U#VEP?MHo_{IMUJR zM`CFpu!-ouFKg825uB>wBrf(008*tUGyXE8hSZn}aWb#!$jG;T^(^>S8xh!xkdbu| zTWoeq5ToBLD;2r=Tn;vDQQibL857(n^yVCE@fMINId3obaZp@$3*;8*;jN`=!C_L) z#AgTiTi2^x&Oy`6s$mBI1WSr(H4yrJkV~G+kr6}*>#GLDn6|kx21*Nn?uO+)UvY)W zZPhO9y2aSws!83NlV71FrX*l33J6HSrprsSY9ca0|DUjs#jc~(&n5q#a_B(6QA z3Y1QRX<5mdAyjH1Er()jpIZ$ZJlj(^SRCY5_?~ePP;*H1B=OApi0>pglRsvz&qA$; zr$biD*-8kVg6^qFtu@&!1ejWQD2q(H729cigbb4#008irb<$cJlB#jxN67N4a>$=x8~u=w*V>e(oTz|s$x3Z z5&IkI(1&A+7r4yrQe}8qUGXSPSBx~e-r%hZvH6cZZKOEKd&AM6_6q)!>ET~2BmOq$ zlM`xZIo^-#m48!Xc72|1uSt;A3R429zCbpws(H_; zkPR#@6-^O4?w|5V(0gWA0!#SBht{Q^R}cX(hN3|r*`l1(RhglxbtmA`)#Zo$VdgDW z4vK4UxhNg2_4(vO!Y+MRAV*^d#2TU_|2K^87tnZ4D;ZpN>Cqr9V$92z3u-GpDBb`C zwcaOWAy`Qt3rVRQHcHJE4|HN4-c$&ePjV@xTB6 zJM&%{1}S0Xa?Fw8yd9RHXr&X`-=!`#VJTt?DEDoycjC%T*OTN~ zLeky>(iCJom(pn!Um250kTw=2lTkSr_rv`hUBO<)^L3*5VGY(z_58`b?A~O!x$C$z zm_fsnBf3Wdt9Dpw0NqngX--Ln5}QIEoJ3m6O%;;U6JM?wKuUGAUV(nr%5IS|fl0aP zke2GD_~``~uOss`%QP%;M;pd=AAJgt*g;!NX(p@AKni_)BUedr_9FjBtrsb#^xc3w zqn!W2E%T7Pfz7?(?1cd2x8qXopWJVdF7G%W6X3DkTrU&Z9b%cpB4nXPMacXqljmNx zkn~s2%lV{KcuL7dlCqBo3n>4YkB*YkZYmK!0gaWNKZ}$IY3~tfVM#|2v%0XhCUs5}4uF2Y_UH0-#SHADhi%x0%%=KmhDZv&c zCW)yUBp>)282=Y51B^+JxBQpW6TT1fEj;9#nq(<$h^dDz0I)oINj662p!#zDEhuG( zc7ixVkQix#OTxYlbe|;4hQ}bHkNXy7g*At@6(A(x(w|Lodf-Exl8vFRUXcypu9P8D zA#D?uUL+^^m-Bzx)CPN7Fgwv8vYJsyDaW3A@ycYwdrI^KiPlymlI-h?H1txt2C}rA zXbr*baZ(J*Am|GP%8(TL2{80iQ2j}jD~T~Dc)QqSsv81NfEQ6lo4VFQCZ6NqmFYRD zVS50vb}(m?LR~1|%eFX^37CWl!ThW{RC>}aOsvo2)M}TOB{J8=)Yzd7#WXQPjp8Rq zeL6fONU~P?>P*C8!Dm&}NrsW4q5IE{4 ze+@B;6Rsvh@(Rz>z0Ho$5p%t@WwhQ*7*#x!??{;;G7a4aK^9r(2L^(n6#o+C+W|A> zsq-1fo&p2_l7sn5k54ju${~mqs&!( zS4{woDDXhbi&dmNGZfZ&Np0Ybrg{W`E#Sj&PBP$P*&qyL|gt#oR)vF^L1M3WY?^a52mOdH5uWgGmPt1R!X6ZLIG zYNavCI$Ji+DktjEPtb1GOGgT2E^_nhp*)c@zO5`M(6;byw4qmP`x*y6a zpag6}B+A6;qm;mO-uERZlqdbDNHt%}<;H0MD?zRzJb`($`l2RJw&W)vMX?Om^Elyh zvyLF6Wv2f=*^irRj1kgYKyD_M_uag}rU$gT6%#sHu5k-)OXIXx1&igT zDS=f{sYS#p2rMygCskZwfOk=1Ws?2AKq^?&0E}6qOwC>k&rP9`=2WN*`M*`&Bgd)@ z6X{pMWTzRWDAon*`Xb8AV?U@CUzjzSfLe<~@*T-#Dl!R^_70-Xh7XxSeWL_!Zj?}B zl?CJ4UIl|>-r@>sK2;lS7vSIi*RgIWX5@YxVvZ@;cE0iWyzsMhWB+)uSo+}DmlNI6(Btz(d5TJb=D_%T_DW@|osb@V1+03Z28 zaTewEz|g}KjjV0aOSbNcxd#c5{Z$W)0mHOUH`QleY(kX>6$Qwwf?PK_@;N@asY#_+ zif`EXR1z9<$`DeJAZb24arUhw$6R+%@-N$Q&2*|lbC2vIi~@wRXk?pHFa4I(w8s>K zbyeyb<`k9Tx?CeS=9gxr^0da8;t_KwlI+ZE$A;`a>@g*&(-D+%by6F^T|aCfULnpk%Lw z5|gS7wMr{#X= z4vY^gt48`o5%-9O0KhnqYz`G@rxK5kfCZZqK{BBf)a?J;yRtS}S`-c0-(~mQ_W%E% zGsRql;>)6;vE)*foP6rUqJW5iODGzo0c;B1hHY94vKXbMAD6)I@R8xGSko;tY)TwV zbSR{*H!>DLAZ4A~VmBqluv-V= zscV=|s27HdW*gC>0V`}`26pO=V#%xrCoUtTjuvSJpe2GRnTYCa1qaSFh$_ZGttc#$ zsHc>G^_klN-N^FvP9_LOr0%xn?dP=s` zk$}7Du|gz7KX!oE^45|Kk+p^-;1pf04tT-VBle>HG;o=BU0E>VdlBt96ZOsxt1LMS zCBQ72k~A5Xa;ABY1$H18C(*e^^7!90UQm_{`ELWKfqb-%3GU^!^rtq`ebg|eEaAuIc$Q$=}t<@P|$$xLF#t1xO};sj~e2EDZ@M{CwJ zHS=HfBS~)(u9Lb(RnyAm(xV{A5@VhOvf!%sf!K`q)A}cj-b%y zav)@kbD|7XU2)oP2zWBTJnp$BO@7cNIA{n$r*y!x-}QCf1Z#QS@{*722|(rT>MWVY z?wgc*i&>&wlQx*(b210}7(~q2)__u*Rc991cntY;%R}qmXxOUDw_LD&OEAhcu%E8H zvH6%>VR8SKu5H)#XnBd8xYSnGN^R-vEK9$#dpgkDi65Eq_@Ra^K^B71#b`||x|zn6 zjA{YB8TB@)`)}MNvx@`9_HYfJXj7tmf`c4o?7f*pYK7?xY-pn-rhPWY>RoDnr;8cTBIw^U}4gF0sh9}rMiz?MN9VfDN0N> zqn6yUnd_0y(GEcBn3=Y39gK+7FQUIB@QOyf!5JqFgVW2+d^$Hb;$Jx-XQZrssxg__ z?8j7{cdwn3|_FP1htvx3k4qKS?&#f%HQ$0hEjI8ZRJWeF&GP zl!J@Vu$7lKV$0C4ouZRJ6b>6f38Fd{V_%z{GvD43nd1}nWq&f&a5@>*xG-f9Wx{uj zjhFK-~!9`D9^p^pbnQEP~+BpoqpS284;h>I**_Bilp&OYJ^u< z?E?0oJfnL}55!J=b~s#o3hb6>2E&0;XR&c!;S2boGPT~q8*__KqCF?%XTZcjQNf^b zee&AS-$8CjJ7V`Tv02kD1Vl<=QfsO;LHN{MckdwBlpGU{tP|V%1=sUnks8E{Zl_+% zsR$7>@9g)Gg+6U4C@pn;2rthq0dme2+Cwq0O!TlVfiVU7T5CH!g`F;4;`G_JxJuPX zejow0TPV zRP})<`_d=mE6T%0*iD!_yrpceL2A}F3HR#1OG^2cVF+w5T@*ONzXLCJ1YU;l+*NA? zA?ocaY}0sh(d>Bq(6BKQO)QV)A8kwItY3=mTg}LU)xf!=y2tj~{RmXZABh!0Bmq@V zBH|LlBkTxx4>W^yE?LyPc`Rwisfzv3$v*E0u39;3H4&Q0 zgtNRSfrGLQ@Gn5M554$xrkN8ezpL~ySZ!(j{;Dl%j$W=f5*l0!W?)7jsy|u=2^i2y zYaX-dGq*R4nP*|&fm6^fvaGrYs%7Dp{-+jX3;q3JO8(%lSw?yGwO;an|NGw&nI#Y^ zyU3Y}(N~xf<}cc-O((p+YN!OBNBtmZMBUA{0C#YF@ETwAlDU))xcy(mqS^O7f)2HL zf<3w$TE=@PMjA?_W6qfDN4`TesW3Ra%_T35f9-a0wQ}37UPHf(#16*}Va76dvr&*J z$f02N1nT|PW0Y-wO3(nQ$Eu-X^kv)7FPC8rhKh1CJ#Q%BdY>m}j8j_HGzq$4GkAt? zVvZLPgC*1+q{8eWK_#uM)Vb7XC;@xIn6!e`cWA^N0++no zJa_9|qBPtids5HlbUneeu#SBE9-vn}OMs5qw(@KT(_VgXkC$-u;gGh_gFYa^99I;! zT6n<12hEZ?}k zYg6e9{s`;N@GKdR2U=%Zw1lD>z?sJPRPX`L8R!64QP<>8hOa;)SLI}ZSc1HN^7&0)B7oX zCGgHMIthcsOU}6S3@asax`*RQ&>C;>r(>S)<0oyKm)Os=g~p4t2a@_k!_}ZYggEh* zsP{BraiTAag&SM=Xq`-AjSOY3kt{)nCs&Y^{}?Hy=6BcnEipENoXq(dfNH{VfoOSV zWsrL&A!0}zcfB3QdsDMtbmR zd5)r{s52y5CVl|^=yB6=0sbd0y;--v2fo9o?{0Z$Jv_w>oU^5iS z$-1GjiDc&L`QLKAq664)K#}M7%xVA0rys3xL^a-8U=8f?h=-BfT}^967P@8zzy+ha z$64Gif=xDJu#9D?cl8|X(h&{jLM4p0Ru&p^vcfm^SKx^S2K=URItD5VraA;7jfePa zXzC5`odd=0DVu9og7#UO*2tpJWmuP=L2N;@{j#)|z@*iR6}=7vyP>m5ze?V=T0XActu8H0Z}yF2uSl`X{3E(fm1eK9$Gs^y*ciOo69K#Twv|BJeHJ+DrTEG78*c7Y2F--^GHWAj^dk2-!(r~aQhvJBaC^hGd69BmoY*t`&fSrLNRkS zX@=Cg_e70GGMZ2dDnWe>F)1NwVxf~_C)zD^>A3F&sJc$}%?#Jc7Gp8(+4em)TEeJf zSt^2H!74+R?^Tjdt6oxVznboAm2HZFo4K4uFCxt6X8@F{3sPsCM%&twbgWva?vy$% zM+*iu`qvB7AM}e7WAqP+J4Moh^;iizHjH?OA+*%@gybd-hl}k7OKAGa_49ygJHqbX zDxV)mV~5^$a+tS6Gcs=HJ6+1Mm6nlhw4@nwhQFP}+-}nRi+4XVN3+YgVHe$;7VIj<$%oOijY1g+)WSqN1HPo-nwdAPP-@rJeRG zXlK20x?H=pgE+a@g!XvuiL#VHGokl!C~33{!1 z;;Db*dIHghK*h?YCfiNos)v;@fS%#SP%rCX7-ks~JD51C!_<(Tinck&GJV> zu6L{2=xU_rZ({4v8lRkRjov*fs$@U3F|<-NL@tosM6podMC+`fi;_W6Bx0~DS|a~3 z4q;9i=>QMz60nWSw- z(fvxd`35!gsfb;Xq_+QxO{bovG7y_$Fy!*XR7-2OsiU@f2L;i@%k4q}=43cQinJtP z@?x?DC0i4<^sGEeOHSWetvhmp4vaCF|0g7<#1GEJ^wH6+bO*>QumnY$g^@1T# znF947FRcf_03Yya?NDH*UZYU^9K!nPTTJ<+fL3U`C02oRrXX;xi`H^FeMMQ7i4SDq zdBnC=jEJddf*K#=kDfk)%0WmTji#XzdD|`cwh4jAsP^)~pT_bQk}&Cc*qvAue2-e> zK+!rV36FccWC<8$;vGV?mVuktHk-wPSB-|&&~PbmeWjlU$K}}!3Q@n@%B-ff;hjaA z7n*|$P+i8&{Z{S>g*2>i^^0a1;KuE;4GZ!9UMH ztWaw%wyI?OYN0L$2{i>xEUxt}ddE~{=pKe@kWd0{KS5rc8&j^)ox4*%MBpvgo&%E1 z*3Y{pB=BQ+&P_1-MDT5A;v_l5xjyOIrCMI5OpNRwG)g~8GSjJ0=w`OqmN62DMfeE` z3d-KA0ssIY07*naR0eCrF$>!tg@le_v~(#~SHcabqve3O}|1Z1me;b`&=d`{9;e zNeY!NbSnyAFfs^-XDfvZqd{OSf%G|dco55fH}B5abIzndM_BMh3xV>z7Lq{6P;jw>OC^r!(=(O#4^|8?dJB%NJ9j8F$>0lpsHl1fb{fD zG$liZjq50hR}5rl#z4gIZ2V81LKJ*rbtB~a6##Oz5yTT?w4S4~pp)|t9SLf6BsI3c zhvrp+u+zq2(+ft*^RTpcrC3!*!sGP4CnX%MrEq18x1SDYVyDR#-SsKmz$s~0_T|D> z+c|&k;qVOO(l)fTW;MFaCay^^{32}*nQh(}4F_By3owddI-*a_g=BwG_-Q;51IC%n zc}$cbvWc`wg%i=Tz3uUT7)p_KHCq({XLYE|;PbJXu`RXFWv68)8>FiUR^@EugeWsE9BOvbk)xtiY^VmboF>-+$71)I42Vj1reEP^PaRn8B zY*ytjNaUR&`?aRuvSmu;aXF>g%FZDr`b@SnFfJrr<+O%bP+ygCv8gg^>rN;)3E(-C z)pPwu3D(o2#dBwkl~=`o?rzna$aqOA{W6*1YIC@I$b+*Ix-GJ2s#dpm)m9n@K(~`_ zZ3@R_>qw};#?z5pPs(ZQ-T`Tf)~qp6R|5L#kugS1X&qY!+v-bTpl5Fny++UdL3V*~ zA~z;*8-rlZQucVeK?g=yn>9-`aMxZH>~xat6UCll@gVAHu58NN8*)ydKLe0+bEpBA zm6YvxDk35g7P13EHW1dRj=!c0R$kBtZ^G;9(xpzK%(4M$!o}t%d`$!V{ZRr;4Zf4#G+FW4AC?DDzMV6J%@>C zz&KXqO=gSM7{)9=E^wDJSnF~!3t8iD^cM#3LYg9&o?^VzOByZSNjedW`)9VaX5TGr zUA8MAZAtqM4>O=6b5xZ!Zs*PRk+vGKHEXhvEn23T*mg`RseJ?g#VuS`(n=l19laF{ zWd=)VwSDY$%!0aVo_b50#2H@Q8m`)X;co0ZtjB@vY}EbabBq4%;i z-@a?qQ(DxcRh8fnLpEy(h8nsyjjfM~{x{fT_iZ}}>|3xx|8yGgc|K+cw}XO5nGLWV zgI@Q>-Lyze9azXBSr#l~OmLjzqlLfs?4ud30{`?2p#r9HxGYF#(0#)3-2`bQT_IX{6>0`h>)0l30ZWyFA48Rb>uGO3(wj#uM=+O1#` zGo{tCL#$8EaO>v;irHiW;Up~A2*H**rLO|Oj4t}rkc(sb0f_lOt^=+(i{PckEj1<7 zmdRDvsj|_*xiSOb)W9wWH#Luv+>aM(Lakh|)mTo%Yf)}Y_E2+vJ2~+1Qm5W=b7|5} zs*~d@Ht!TayW|>6s)^NJIV@rfgu{|s-YapS= zm1SRyd=s;&#$XTCDdl&pLg$W$#MRp9tpGL?^eAqDyrDa_8GL4Ds@AMuurhI>Mlh5n z_L?>ud(|;M?*j`i=@k&1aBPk38rx0`gdDcq_4nm~3C_#PD0T}RI6NF>+#dA02Cn(x z^4A2wC`k}t%f^uYm=sQ^TAp>XJ}m!}!!a&*@;rMnETY{8G}D8exURL(+D2;?u{D<} zv{_>oQOgXg<*ESf@xZQxl2&{gS^J{-UDq&23|s_WQFRPa6&d_QqYsN-9z?<<;j5g6 zu*-0{L1Q5(Z6byhVA!#Y@=tGP^73pw+*c!CNjdW?- zrJxF`Ew00f+-yXjw^kx-x=X^70qasu8}=fjJ zKV)2Rk94BMVNd<5K!d3?@~Hm0U4X~;yd`)`S#V2-25oAHj3}3we+y^Xfz{~WWf?T~ zmTY2;yw7TyFxFlPA(?9z4-8PxA`ua>=m#OVZX`(vQJoqU1|@8KSSSp+7d7XJDHqY9 z@#wa<9mb?atd7sN>Lwvwrb+!IFvLT*0W+JgYg(kjY}%{_*mB>3IH$xT<7=4%gl%o)z@qoHj|yY$8G_Y-DK?F@JVJM-$n_oa`4PCeATP44V@qQIvu!K1pBe^ zvFO>T8g$jLQ#1w>HlbIxY0P}O?F&N)riQdy+K$29cZ#;&K{}%2b-UnP*;#xjv4%nxnv&wZTT*Xj0Aq9fbwhbk|m-=28*6&6&0m^u++N+KVC;7H? zX@6!V4z8ulXCAh;<3E{ST4^?70qU+9y-sI0`E1`5voa~hehz8-L^tX-pk{7c8Mw)3 z(^Cw2{mjp@vNh~%dk)CM2;Q#o|27DdUF|u#p0dn=NL8Tavxi0AJB@Q4ApfylGH%78 zPsKEWX2Gh%(sS;w*VsF7-UL~j#d%BbL8>I@X8?xKUjjs9>mx*V7SdF9O+qfla@eyb ztrKhP8y+VZ0U-KN!*mM(>Lg~nlOSt5hhN`&QTe*>uz=xok;a+?+DuJ%f@7r zXDxw;7}&iLUFZ9OpK5n;fWp**_sCzk4_v?#)dL2|)Ne*7C0eN;5u-+Z3+k#-fh2Y* z3n1Na%^gzs0LhLZUF(6bdNTm)5kmhUuom$^?6Xq@intl9t8AYHb`cyA8yLAcpS9btP5W#2^7+~KT~Oa@8t(Kbzg20RLit`kTG6I*YZ_4RlrOl$X$%G99Gh(4=@S- zzW|j`$XXs~fbyHV1Ou%-F`#1Jh8sZ7b=THG!=~%dPTZ2MpS%r}{+TstLYBJssUoP3;4#$-eiZ;9A8_hT;2cC_){$ z3Gq1o9KzZ=OU6Qaph~6pTzN3Ny-2Ns-vYb3zuJc~d8PgBK=b53^(%GM-d=`M^-vdw zr)!FR=;y))XWB2|n5QmXWa_6Ub~sc-!iIDh%x5NT?SGugw62Q3$GvsBh|p)b2r>;UX9acjv`8 zUb*SF4pDHwEM~!IZw4T;?^1FRrF5*Jban?)r|ilx)B2)=Y!)EDEMq!Q)R{Ji^VGaIdOBANbFAud)6S7&pM*Mq(5#NR449(7YFtv)u2@Xv8y&53v8{(~qIni+^m3 zsW;m?0r|mo3*wYigzCUPt~e{$c7$*CBP)lHww^$Hm02e2yRuoo(Mr_vRUK)$p}NC{ zeWSp@+TU{31lE}|U>putm!Koe0~Ld}yUS*by7ZIX-5R&THV?`~;)hll zN^WC&qNooehLe-ox&1HxIl~3acbU*%ga6cbOSrIPqF;A>JhTb8r$52SVqDUC=Uufv z53e%RchEJCxfi8%+TRI&`ldPso3>ZGMQwE*+a1xrBYzA(8$$=ruVFW>DHm*0JqwtS z7u)@7w~q|xNoIGAcCAVE1%^G{u~aH9_WW;orMfv3`SY9bXGV8_9VTmyowZrlun&#? z>26;;$3VHbtYQB%(W?o;FPp&>d)3mFh^Yj6+%8DXS>00e$8I-CwLj2e=o$%@T)Jwg z$9|YM(CAVEErK9CDR)3FVF^Bt-!}Z*B-4!=yHq=1yq39*W6YVr5&yom-@b{I)u5j6flGJ;l+&h+Mw9~jl1GD@WiBJ>E%KDtl2QT zqFB*(sITgqJe8FQ>DdfrZLKe)5EduWR|aZH2Z=9-CmM|t{^*I2dX4vC`UpP^+1{rl zXJJYb=ZmXkPQ_#WoQr7f%qE%%Nimfa(mwm(VCalD=bZx*mC_-dJ(L68^oG6k;^m}{Gi%S81e z9LTsQ)N_i}&*&D5?hY0(_f)?;G+(@QaQ+r}b(=g2@5cAL@$*OECb2J~T{#F$$0GeQ z3z&Q)GT{o0v0y;Um{c03=ttCxui?j=O@cEA6D@(p*r`gb+^MwAfYc*!1`44_T_O|en#slNn7xh4%zy7uePUmu0zsVjzZ_#{P zzc*XdsoFg?VmHGYwRHhigZ2eVS1~HSteh4;^V<(|(sBr}i$gx)7dJBs4y289eal zC8SxRa>%}qX8`u2r=mU&UjbDEx=+c3=f{rvlxBdPx*sUBGg`TU%YXbaJRQ6zc2~dw> zO5N?aSN_wmewydDsTmG(gyle@XXw=6Nyk~kXv+IEz-KVBpsXJcM@yNi<6abQy6_U3 zMDG<6CGr;K&d~o>%wM<=eCH7@-bYp8Dzn%V@cRTKLXeI*d85;cFM)oK{$eohGJ?)J z4v&pvup}e4KT4ed-YxXspx@K|%=Y_oSY6X{xP{8xnEVD;)!}<|2FD$M{*2ZU)_aTZ zIUDpScY07$dl$clO0?wWSn5;Y&q~0##gQClWfVG77{2##2IOTG8^(9bl~kSo%WL;9 z^)H_ZUZTHV!d8*mm+_BV~VpOL#_RPH^Z{|)A+PX7pe zZO=L+$9JE@=kCqm(IwLZLw4in!#p*g9^02xC#Rln~b@32nI{`H$*_}dWT&1X;?G`;73;BrL=V9an^ zpMy_eF%a8iE~idnGKhw4+H7_9FYT`W4Y;fFo~#$2tA=Yq!G{*o!9{`49hLq&1e|~y zu)YhtTe&CZ?R~YoL@i6t?wAowt?PVJCd`^2d#?HORvEk&KGz6;;VB?7`0TXUvu2~_ z*Y9?iLTjY@;%23-1P|>3v;+|9!;?C}fiZn@;Gu4>o{K~0M8EKbFI)}Tq;BZ|)G3ZZ zk*o;XipC5&X#6ui-$nbv7rsD$GhBGrGUNQ_uQG7Isxb5%1**|}8AJnU^XmFU2R0eD z*O>Tv;kQ-H7jA}M6?)y*jI$+t9B!8n^gRHL@D)pdEWqSOx@NJr@+q606tQ0~%}{+Y zq?0!66k`sJ0u{_dBTcMN~L{J8r6(LR&IZvb=~rQTNr4j=8O z`odG;{dN3!=(St6lZD^O-d<1kUasooBzUU-q9=R1E*23JMqFYak;kBw<@2~c-}ka3h@Fln8i?5K&{ z(x`N$l&<+_&&R&DJZXXx2|Q~~HKp_BmZJ}*G|v!WkH#+5Hx=<&ncXe(Mf@RoH-8W1 zZ&=%qaX(w4_bUG~H+hED;ygtNj>ug!-5T2M>Zh$RCL($e39}H9l#xDQt8^8>zruF} z>-@f#g53_|;$A3>OOVX*lct)=y2xb3ITI)yDSw7Phpla_bpS4$2Z(L(Nw5(XCSIBW zkmIHAWfgeK?kSmbOvqp`$llxRyf=663eT0=w~hkbEs{n2C&#|O75s%)!4q^(yaz4& zYwNn8d~E2#$m5SSu+JJ9nhV^X$#S4|G4bWWg^Q8S(|y?juZ{3E9|5P+iFWLt%69%K z7gDiAX|!!XxpkV{cM>jFV%!9l89f!AMe?oe&1uNHcbD{)yGU{gO8qZgnYXEQqO{t_ zrmA@9bXI4)g- za$NvV5rSK7FO9G*nz%GM_(8|cd0x1Nwk7^C^W-9%imQ(8oMqRV?W zU4F*J{Yo-wylk| zDcfnmtT|sH^{e{;&xLp6XASP?75z3?tl?vQfcI0Q1K$7~g3Ua+@-w_j(U%QV+1wr_ ze;oRg2l(bSQw$@R=ji=-_i#zO86inUa854o*W9lH&i%zd1)`S3jrH-3HTSx%Oq^(;OcYiSxpj!@C*rWxaW~0=y4QnfI70 ztAQC*?^hAm?*cS}bP0qmP@7w+7BJkrp}~sBdcXRe;fUeyAB9u|S4iX=7dE(2!}w0@ zJDC4;!>Mp<1ssMqV`e&_h&#}#vpfMmQ+MtOh=^R+ye~67W6` z+4Ta3o2A|l;leEJyTK$!FZ)2^eIOOVX^DK8J-8cg)Uf+d?_>Vc4X46;3gOMT^6X5z zmOlc+&#-#0{+jptYvsKW4hk`=fsd_~S9bscq|4Rj*05c?(rp3Vb(9OHJ%pi1ndi8!_++_hPV4^a5pXx5u;HOvlJls;!Oyi!fg(r(9M9*FVlme~-+KO{3aUk!76`zLwOH^K=gtszl>4>}9}B;@q*oN}(is5k!bT8C-~vGV#4qaM5ZC9Z^l%f8 zm+jL5kB00-n)ReUQ$7|xfpB%k>GFo)5uWG+th~D-{ju!*Wb;b3NYW8lr?ZBCE%`}I zrxh|Hm?3^Zw=N$&XBB z1XW2yK~zCHyXk-77r<|>+>Z*7zVHzsU+?sVFI)v*`+N{=2S9AUW7R?})j}k3n@yC? z^=siIC+|~`eQ?{kz5p_XzE0mx)J4ifcqpgo>~e7uV3+aN!5zdushypHPB|AE$^192 z_rbX~{X~uvE?=f;AEn|KFnj9b&r67Z!V>&9*9wU@%kq5dBHqGW&|&)xz%w-x7aq!+ z*Tvhz-Fu-ffim(wEcM{U45sAYUT9zVEAWx3_>oM1;UnOyTW<>A2yz0>;^zI}$a3~j@mC6&fyz|~528w2`b4JR4R^#puN2x9 zwEK|-6KUA|I2k^Vlu>ND-mBWYezv|q_&jDPj2ogQhQD_Z9OHj0NVj9cIvRhda!uuQ zv8O26}Y$t(gy^W3VwOkC%(y$oL6ypG6!C(zz0O#0Q+v=|Q6?}Ctz`R0j5gVT)P zZP3@Car45K^*YkKl$YCYrv4oxyjE-`X5u}DE*9kwUE0$3kR3LNZ)y1tTG7??R%r8> zuaMbEd$nKb0`DGB#)GiGcSQ6`*{^sC_oK`A_S}QrX@^S|?|;OE6=%1of#bDz*Oak~ zWflEe`aJbM4p+S|S_r-P;s~-gg;zJP(VS%O#gROD3a57yVmKtJ1tA|>2e{?h%R7g9 z%oa^I#IO$P`0YigJi6ZRvaI<p-D-GFR0vE<* z`&A0+G>`nWHXOHCtQmKiC`V1vzy9-|{~;#&5u$A$4;fePIONN72#n>FH9s7AWOvD) zSRgG#B*J9T6A>R^a|mbA_498&j$KHNaD?g+eoGz!70}&#HWszs8q=UHBE(!OTQbZC z%CQD1odNNi`9dfEMysLvuqY1^AtH7~^GHw?xR=nkf@#>X5cfbvW>t1;$ zUBu04j`*X6wvpSa&G9J-*SYxe(;%aOI7{Yrd z5|PK_AwvKBpZxDO&n254pE1J&COl8JtM1c7$8!Ypy}=zs8p*cMw}X^zu1Rj53#S<= zieKmMRVCCyHzfgSp|Y|;WO=*QZrqLk47@XMZvlg?M3Vu77r~H?#VY;)jYu7!dIwhk zv1z8tc44(173Z;hx$EkubnXRxPA}t@cGnl5Q6src3r~d*X?xEZmBG7JFj0W`?)G^C zDUun?lhm)QN{@((M3@N&_;#f;ZYQxN#J2-Hmx8CT#X$Z+OX;qishsAwMM)YsrMiy{ qc>LZLb5mcBX!ElC5TeJw9{&$}`qhfaIH-*P00005C{Y? z0#D#@8S=tdSN9@`Y++!0Rv)|p0FXfdJYc5)ARzE^2-%P*WbbfJ=;&Jj0-palT--u0 z{kQageFvrX=Kd@DT;~5O@&A31#oZ&+4HVf1Ut%F(<6xiAU>WW8-!krB+4aBWGylrh zE?>F~%8>q*L#)ZVVA&lkj(?+L^$4`F0za9- z7e5dRkO4!0_;38+ckl?J1HkEB063EVKi6FI0N_a+032WZpKD?z0KgFo08JDBbM1fT z%YUkaf$vaHPXPFK4*=L40N~gp03go)=N|a>|I#-h@D@MVuORUB0{j6FKnO4f z0s%Kb7Az?MrvQ0C~) zTs&Ot9NhfeJiNRoPMkoYPYRyo6Fkm$g704?5EvZJ1ZQGBdX$xqlY^7*|Mzj&4RA8U z02putA_71;AxAhNhrQqc{wX2!2;_ec7My=5oaqScC^L8$1K#{U?);O1Ko1uIR!|;_ zI)Vbf{?sG`3{zuoF=bQ}iKZ`v5H>}j7=Sg9Ln8Aj07xX-GZyNtXo@yHdmh1Dimpq< zW5_~g#CkJhHgO7`#=x_9z;Ik-KP4z0Ax3wcrZAeAnHfT_=@0^q03c;JiEN%^>UkDu zpV*8@Y?(TMX2t**7^50NB{>k|2v!OdDWozKHX}A8M(@NqPR~e@0Fgu@pc7g`it$jO z`&!DfK}oe|$J|F>oyk?I>tsN1=xihji-pIy%cMiCmC;!alE%sz&JQ3+9I9rLI0CR3 zlso`1P)l5{612pFh@hD=my{4+ZPZa<%K4l~GzFKagV42wuG&j^53kNJdC%3BkWECo zW1NpTAZRoo86JbjK)r{pysCD*mJE`6UkrBa%+4WoDQW2$rElOXufG0F=eKN)k?s!;%3cIvWB_EC;fY0F8k`P!O~_ z1cgy+tb;R!LJ*M55B~N*I>vok*AzbZ$}(Td(gRCqFRV4&Rq0}4T7S%_>{As~xX zYebB3ZUVK%IUA0kz`z9nXUTE86Cid9O+k>(B~WWDBR~C!Eh)VmLpIexP)in>88fse zN+p?bWV|AQ1$-KtUIkPk5zHiFdO263bBR5g#n^*|fQ2H`s|kRfOnNnuM4XW&TH~aZ z>SF2kI4LNUbd$twtc-wKh8injsUOJtSRyT-T7gm)YJrtNj6o$K;V5Q0L|+z?H7~se zu!m!*eK08`z(T4ffXgYPNJQbK$N<1X^rrZUln5~pLX!G4F(q0y5-UT+E73p+Xu3U+ zgV1p%5gdqQdzcb6z1~3zh8Qei;C1yRvy3nZnouhR}0S2S$|?650YMBVg#hpfVjq^+i{m7~5Q+p)MrD(8DrGMqxE&=@i?%21?d$_KK89uY5vpslriuKyxnp}X;VUHi<(oq6>2 z>l3d|KVMbdy%M6nK3+x2F1&afs>+IQ{&U_k+RrKb>-=pP6@z3d{?B>3LtI`Z@h~ z^}yebkK8{?cbDQWM5o4LEHQvcQpr$Nd5qd!0f9GYBjf zY)`_n_+VIw_IM0D$rR48hjVq293+kW9Ht83F&>mSVP^utD6YRWuPU!#%tG~+p!osE z`XQinJtgYRMtHj?KJwMPz1_7U-8?n_*d;@@?}tFm>hGz!L%?Zw@%Q+_;|b~1Bs@|Q zVG1oV5wds?RVi3;UH)ZzQSREcmwz>#QjW^XsKSsTL{g3=9s~oCE@vE# zg}^r^R$3*i>&=Zs$B96ZvL-asOtiijV|3}PDt`Q0mcT%=#Ph#5e?D8v-4S@I9X2AO zI=U_T%qefQa2iI-&Z_+V{_}_5dD>P{i|u-Ar=RA)sU@|>yfBHyzmgU+O9IapPW|MV zxM6uEVqfz|+er};lnOzBo&f;m>bg6zfC(1Bg9Zs;rIl(CY>pcQ1~VQ;96>O%c!(q_ zXX3Gp5z=^6#+mSM!(YGswzX)ydSk4pSoM=)%Ib2roMN}`v+?Y4{wbJFnmF5Kr)}*s zSLEiRJv-Dj1`MWS@LVZlMB;?sj^KNNF1ZcUkKx;2e@AYWeP?PP`}(@oPMw8li8BF& zsu4(`CP0deM}im*hcQ4WF9qOaXku^}03Afa%9M#+`Mh+TK_U*E7_+RtVp%_Jou50} zdVX&&T8@3nx_(;dd*~nMYeUbU;UmebwV6Z6?(d?@7q$O5%zyk|{`sV;nNTu|u0qYh zwdq4Z@o&u7`@4eTb}6gL+w8}71_rLEoAuxCbew`xbevHo_l3|R6s|6J5N@lKL8L)R zk=U$7ys;t)WD|f=C2Z`VjO$}Ap)o|da6P2)Yxu7d;^srUaByJKqbdGv}-;GGn=Mu&VQtItB1K7dkgi!9lMi2VD+vA(5ERL#uLNbP&P-2%b)g z;p2ssqEQ$Y7amb9qq}OWV{V1-T=ouu8*eY_jeUWNAcum_Yg9h|W^+yBzL) zDcY+!g8S>EjswA%$0_D(&ub=I%zKc5-nuB2-V2*E`XNe;%&_FUcn;0;Q~b0w0>5n_{L ztYbZDi=%EMSp^5Vy-^uIqILsk3xM&`(eG^%FEvaDTsxC9KKwfMHhAo-MDlfPa8zaK zYQIj#r;sR~d^LNnu8&a~Uz`xX*WaJk#6vs(X^A8P3VLb>0$^%XLVYzoL`RiWfNSGm z?2jercz|&vh^1sywXug7qlo|jG)2{{V?zbygX?H+_B+EfJJBy{IRtzDZZ1C_HxH#wznZ2XD4;6>T@4-& zAzDHy(8NG9f|05-822#%eIcME2ZCyrGO-}x1oRMZC1^lmixaU?HCv zVXI;9gcw{_;(k$S=(O`Ihd{{Yl}Y~w6YG*& z6dD%FEr~CI5BZm{xDenueD)Y`9>5zD^@XSmqDF-8ozm>`7eD(92Z~VpH z6FQ&1esMmry}GmisJp&0_@a@ZaEH@MT3&n1in`$Q@1OJcG_6~+cmB}p&3NUo{i1cJ z?~1vpu1wUU$nq*z#>Q-8z_+NGmV;5%crL;|pIB zKU%M823bd{&P_ci;+7zNs7nZdOgJsQ+72D z+U3EF8T5gh01!P%Je}#$Wm9J+|1u?PTntGHu;#|mh?zJB#JxN}28hdH(aXQ(nd2IG ztZ5e)ZK#QSYFN9zZS}IfnD#xL1PzZOt$r!{Y)Z!r`n}p|2>D{SK>d1TMN6BVY7=<~ zM5Nt`&aEGPB9;s-muJ?+B~XAL<;SRs1cq9f(4*^mE4Pm z0C)l-ea;#yOuz#eGOrQ^k)CbDqJt(RDU_+bs>k%SgkF??&;GW5?B^fr$O(%VXYv>& zcY~PMB&t7kuRm-#u^RSR{!^6UosZV&_pLW7z70s_Ik*_vY94#J+lsR05m|8%ug_X8 zQrtNNdX+Xey-R2`G=O@d1a<-S0?&W~Ffd<(I_Q8PMu*^$NGJesCDz0ckx(;Mv#kD^ z$6il&*oyU9y~L~&-|sbl8u>ix@3;}^^iYj0EGnJx^sUCx!Q1L1WfO0I(XO#aoT_81 zH;fl3tr4yos)}pD7&$6j#B4_$x%KN1=v1oq?PTB(LOkjKDI1Abb}r{p$^j7rg0lyp zcy0tZE1(sZ5a>`erCN_}B7Tk4Y((*8#9fQBW^;c|PzgAqKl~zZ@coG95dM_#?z+pO zdf)wfng@~ZZ|D!dcSy93crt@cpP|}=S;VnZu5YW44z)k*pMU>xWhp<&9?4V!*ps+& z>@hqfh%=S~W+L{?BxZXI07b(9DU2k*9##N~r~^9giV_p$zHq85eYvjtzWqy71c?DU$hR*mnpJ2d;#* z@;D%CH?FHUz&MFie4~##9Up0^n5zCblc1{a= zJ~g;|yKipoL&SK_^`zgQ4rJA;#n0uH3R{UkzRjU~8h?}Q{>?(L+Ud`7l$Y}9$C85< z=f`D+R(^j!5d7X3-k3UDM?-K`5 zDTYBqbGbJ$kR$x*Y-3wajeKeeJj?Ot5?3B z_A*X*@(@eGz#AY35>k`bMuMmmh<1FkEBV6K0#hHQb6JKs`B@zRtK=h!)1Z$8D z!f@ka2;c{d4slT|E&PcM`@R<6F|qUe-lV$VGY(69{g$B68pk8QX~T|UqsZ&pOlIkI zBx1Sp=KC&>7+2KL!0#Wgb_2rYo14fqbPgh4q`MCb0Fzvu%nVZ`js_R$UZ()r2x2;# z0R2a!LO|{TFA2bfL8buOi3bgTY(i{UF1~ z=Zk=Ib*Go$tbr;VSC1_jnohvNkZ{nQlBmO23V?+mXkfC0WietT!)aA;A>lG122jg} zh2dwoI$`uq6GdhGKrU*l@ScAB^VSZjZ^ahH%JI{Gf(n*3I*>i4Zp8D(0ddec3WOk& z4(1+k>IfSe)C&{17^7SYngAt%iMG~6OAuPlQ4z2(l zHwff($AE-$2{@A|Qhqwf!;wtD02$4dK!%PWC}fa~!zIIs!*CQF3sMwHG*lHhF)UzA zPXwcAJj4j#&IFTl3KIKokwIn(EMT!v5{-ccg{IAjU@Zt@1quL}&`x`91Zc!;rqIWzP>jJ4PY2)x2Dn`CF%}}(8UdIh0A^4{P&1ZzEHlGi5&%pAkjVyVG-PH4R);_Z zBS#1U%K{Q<$Ph4#Ay=S~;DpOiE3i}t0v?`j4RTWiLKBR<9%BSxi6iiTe}qbkOOdQ7A~wB!WOQ zMM6CAAaM`El@JObQ2_914Ctq^VB;nLnBKw|B~?;nXgxs^O11RhS}m7Jp8=H71kjUE z7z8{wNZSbkO!X%2B|_F{6dZ;{Q2Us$AT_5CxHQg3jknr ztc7e8y-_4k?HPU|=_LRlYy^!(f&`rqo{m>8K+uw*otC&{kSL)rKz4$Z0|F)l{H|BR zQgzG$hXDz68Vem@-~q>Jkj#ZMgXAND0%s=CP<~1%22KRpT?wi`G9NTNke!Ek{NpMC zGzDNloU4s-$p|E$7{de$8Xg5E^N%|OV3HtAA~QVTSQn;u4QT!WebkeSiZJOlrZ*5w!axkg9ga zft8a?LB!|;O&2sxP{9Eh9_h>ga1^K+=u3qDWA%8D`vX80M~}h4gJeGv1hhCVDg>kj zh332=I8rba zxTVE};uPXKCVWcXSqCjby2PzOpooeo5=$81MiDav@-LD&1O(H3=68f642riS2R7+{ zPCowh>4v^f$HW%bAHT;NAl*ZO|9qS_@bPb(c69FY-{>b6 z^!b^qyMO%8F*(yo*Vtb+@LW`5c%M6}d?Zn*tz*D{FhxI4ia9YAE2P^I?|jmq`qA$- zvL~Az{!VHa{&qIbMVibpwb+k51j<=_w67^;#%egsF3ZY#xGHXqnLlMSB)p2xmwRkl zzNTs2xreN}q)8by>iWUTf?CssEpxoK+LINRD&i-$KE8{|GWVE#S@_{dNZ#cz{yr9E zoA0m`PW!hRG53T_D(YiTKY!dJ_)6%t`6JZVvywvXs~)Q=zfxlD#l(i(m0%TO#&MWn z<1U*Zmeb;WrBbZTLMhpQ6XZEH$;Yprc=K6%Ot(n9WzfFm-VqbMoNwFA`)1F$%aw)i z4Wt(O9>Yn!PYgS5R#p$jgmynIs;yr2-<_>wzpl1#S99uDEq`2cBdhvMQ~ji}{JO4{ z!?j@CwD>HcmTOzlQ^In=4tmb!ueK=rvJAY)`aH3rr(S9>C8fBvs_f$$<1+>Pe#l=mp=_Lm>7b=S0VQc2WONr+OXUEAS`1Z}Zgn+ z+N8(Vbj&}%&wa7hn5rf6x^Hj1dpApOOVkaWwskS;AVnkcH&yqOvSfjy)D~HE{@cL5 zQRW-U7QdwcVgE&(WLaRZ*pSZ~1+hq&Sr<-Ty~)G1^+&>(glUMK{O(M`=Ed@ zLk}ar#qZ0g*e#kqutx5Ob|*|VN?G~(4*q+%Z*QVI`#JjnyZv0IwaMpx+KwdZp0XQ{ z#G_6DltXX&dm)@qo9vmjm|fkd>}qf(XD6>@%lpA6_$_oXYvae4m5nxf z-3}P{GLwglm$s1p!rNaS@+@B2FZB_34A^UG`0&CC!`AG1?y9na2I7uNg(Z+!AX!t|(b8`u@hv`umB#w#Ngl z35Jh7q^*3DWmHI$?IL5wx~Ugj)(FN|C7qFFS;}L#XfL75?eP>DjMgLFlcX%dw5UCRqrX=8Ej+Y!)(LCmz@V5kJc)r zu~>hpD@xK3t$Yt}QBj%N;?tQ$hrnR=wm><3VtqOF8EF|aa<{f}_+z+oJR&Mm%ssp~ z;rrYW*5}HJ(MAaem2Ql;+RUYU{2#)zJ5#c2CpOM~>*jx}*_7@7vQbua+dX1DufinY z%6_6O`$<({U!UMLy3XE7H?fCCT$?54YWBW(g8u z|G1}Jc+_;gK`*E8W~4<`nud8-yu(wj+nxwzetTA!C6jw3h|8vM&f@N-I?%cXpqBSKZ6scOcNGgK5+5ZN`xsdtp|F4s}Ax3*opObl;?uV3u`wBkuqR-9;zNS3C9A1?5!QAk9 zL%j71-Re+LK{8arh}%4`IOtj4PEr%4ZdQH--yC$tACcxGAci z+2^nw+C3P_)`QV40|I;l&JLP({*rd4ag^>^3L7&!oHmfq@f}yXGv0k;{-giAQ$TZk z0lcx=Q+L9{8=Lu3<<~_V4OxB8R%A&%vnh8o=@*EHcVhZ8ss*ptb-ryjnU6GonEtZ* z^0TAw=1v>5WwD$qP+8^b+co?qlkveRmv7FUFfQ!UV~E`e5j}3rEQPrDh-Aa6i0FA| zt;no)UM>A0iFxpsGJ8Q|mD974PgV*noo*N22pp;TdUaG;I6y$?k?}zYx-wf3b(+#! z>4`eCtH888S`^2bH;?+J=GyhU=E@8h$3F6@`KzSiDr(H-(U?-X>QGL_}y9oD1rLKpr} zySF@>*>%^|CgAEH<330#5?3z7=E?9Ap8il~xp>s&Ubumi28U?uUoovwCF9;?4y~Pv zi02&7xPt@ErL#60a;8QmTx6E{q&A|R`e8Cd1C?p!YnA-EHxoW{h2MuS_r6~3RiQND zY9E+$j`Anrs3YThMep9I_;J@PoEvO#>e-Oq-YvS5Od%1qFcm3$iQE)Z1^(H%(kHq* zHVS%$Y>+O+ql>**-?)fG-crkeMCWg!FoxlR$-bePs?uA{oT~vdjpDj>OB0>d-B}M2 zPuS;XEth(BgRkfgRbH-7)*^Q$|V)pj2w$pwz4VuMHb?mFs7 zZwW_fXc@E!M|p^tURp8D+1litnHg-!zHpw8uC=R9i&KC21{jkL{J~M=Ree0sy^=*d zyG%w$Iu`35`O>LiYS!-R#X;loN3|cr(_Q4x^IRCVjeTO>R(yg(Mt@i0Ytk<6n`2U? zn5yIn7Uw6z5uaP~b{OA%?ultwTEAA38NQUx{X@WTVMY=c{Onxc%;+JYc0EAa$}e77 zVJ~BYi*9>vi@1w_4rbvuE-0QkVYxFJcs~Ey*@HEoa|QMnOlO5H-lr8MI8C22d~}UV zE5Aei-18@On=Jzx`MZ4Uy4*Ue!@EX`;V&~Es-R4oEu??6WYu?N9|EQhjkBArzdZ56 zhk!898c{BJ(Ryj-0l~oVZYhHK@8_pMZCQ9(tKMnRGS~Ue^M5t?)=l1O>~|OjHMgnV zvpM<%Nbh~$?OLA$T|LKu1zua*H<%yCN(#njh_|JxX z>Q4W-R*m8PD5?7*hF=+7gj>3sBIzci7s`CkBuVqq&kuno6UCt0EBk7`iAI~{Sn^>2${QeZ=LwxIswl)Z;O1l7?{e#I4%gsoO7q1gC#e8Ih* zlY;XznH4IPGE_EMiMp)KD|1?5SE9mhFd8d_{gm%Utlq1e_iW)ISguHL=s6rz5o&S%o2 z@{{i7daoR>^G~svx^NKjMvd0XbfblqNLnp-2YC8ke$Nq!v^f~zDoQzCI2u!$Gne+| zoSOOCdFhQBM_IUEN54CNsOTqO=0>%NKh|%~yZTM_a4n>BRF3HR$cf6B+`l+)yY^@- z^wg8EX97CSwA+`~@2pcV*^l5RlS?Dk^KVJCcDhpquf)@Bl*OE`n>Rmpnk$0$nii&A=HofOK)tx($VFd#J8d*o;>mlLs!Vjf z?I8eH51Nx({3sI+@4ax-QcUt~H>4C$dF;coWV|3$mV+fNa zPZs=T7Zr4yruhXdUhf-m&FS9VRxLUeac8paz4>_YU){As;MGwuJ3w>(CnNZm75uNG z^FQ(b5eP&Z0{oLW$q7J?{5Nm-UlQ`11ZT)85~U>lKcdioqVME|T+%80!;2SGSdZRo z-1GvUGy*dZ7!-b#nTZ9;^xvPV{mVQ!xrBt}Esu$uQqUp0z)_+^XV>5uw3wn*MlC_t zErgm`+BKzgiJL@8r@vzg?f!3nAOMp#n2)&oX}31rXc*UiF?yrH_C`ZM@#amz9gVbu zGd+K>@BSo>=kY*r-un@eX*+HQaCO5uA9p(MHmBt8Bjp}5VI}>HIk~jJPm+n9eHt8H zQVh#AOq;OAry_0y-hj*Q^P4gG=RFG5pHvbq7Z$VLxS}99^{}IPV}tIRcL=2KUMKtS zpH5^?o+|$J$msH`!b2cQv0b-H|3%`cXkl9|>KE%V$Dc$*_#x{w-8 zUwGVIv3zj})>S>>{b}J3!Dsa`h|yEmv!I)pZ;A;fA!pbpz8BmWuTOGK(b&oVVg6o> z%Z;mwCwNXLh0a>&eXyaHtJ!or^}6Au%?#Z{NAbl(kDg*>1I??PxxcNv3)PFMS|6%W zg`%Sd7{2=g&zOJlo2f(@_+AQS=jqeg-edvQ;25-A z^Hh-da!2~iv;yO{i15Qz>++i=k2W^5Xn2#aQ;%LhZ*?JC>=sXH14g(j;-=caT%o^5jHNl zp2jZ>(IatkBYVsM3*g6p?9j$i% z*y`Z(pshD@ugqmR4bsBqLJWK+Hm<%pL0MD9KNS!z=N3l&L;tw05=nPrcpG^x>|jcW%|1PjEe$lG`row!r9peIZU(=zZW> z82_+aEcXlF*eS1}VE6Y69WKB1%H9>awMpJv#;g5dGQ4Cc5t4LZTDqj!)^jw%!dun3 z0*;QS)pKg*c zWMng9Jem?*twQs*gM5_CjTXuB#omhxPcIc@f2HH<;S+w-PE0Rf3*5+AwOnJqQvaq+ zVjcgSE8R1@d_7C%7VE6ofYJpi)se84%B+lKg+!W|SF5q-<1eVe0oAOF)_ZcDzf?~f zirt(Gur2SxdTj)sNIKKAEssUtA8X{}PGr%S_*zc(AM)vKV9Lr&zgDWRz|`#Pcy|xi zC@=d7Piq@ANTkTGtjlqwqI7|j#sP2OlfuPT6j^cwwbD`6k4Bt z+E3O{_786yi?%dRC`0j#z)C>v6;icOyD38o#|e_Tm+jAkvHB8k&9gS z*QTfnR|s?k1le~mXAi_|D#RDDe)ikwtz{{xDf5#uatM%(FjhNm_3Ey1T=L@Wvf{2d zMXord4?)D_dUqd1lcW_Pvv2p!cKpND*H#jSyPIc(eD@ zE;!fS{rL>THpm?j31`$?YK^_!BR%+K>JYf4_25cr${}FQa*`ORrjk=OG)E9g%v`jq zk5<3GwQkGS6L7I~pBgAd3O>He{hM_;J1}KaG?-|lj(lZ%%flt@oO50KSKj*wN4ZC* z&OhD!Dm=i3u$`I;K58rxbIXm>)5?+IG__RKbWulrcsKn4mF_I5d2~*;{^E}Kg~I>L z*7RN&;*x23wCC)j3@_!vSK*2BSen6CCt`tAWh$HGl+*TZ)3=~s>s#8tn3heaOaH7~ z%LOgxGKY>FS*Tj{OM2Z`?Nk$EM)z`yuvolY$O)G}Q!&|V@m?(bwgJrrv~;tOdj@T3 zl`CIi57;C^vV2bZ`roIvyCxSM>nPoDuT{&t7W2?&$L`NZeXl%(c^Q77J#hN_F{x3l zi`MUs+x5ndjGlc|O;Np*#rf;CT~t_{(gE8&%bM(~SI^$Hyj?HdY>xgu;*d2b>#tU` z-fI~W_~anHa=Kb#tt9i&G4l{D-7>W!WYftvZ-T6U88&?OpB4?O zYqpIP&0ealMidLH%?|2kFW%<~%`;7XO(m_l>|cmWz7;Z_6AsEloGSO+ z?y&Q*UaYgdH(c9eAYLHxRcD!abK#Tp zg1Vh_eea62$}6*BA+x@rgrfMFi`!yXPx|<&HcK{K&ML|Lv@CBfG9Kl3-uKioX_NbR zk_;@fm+XUu^vZ^HA1`R89a&lUNOVXonEb^(M=(vPDGac~J+Sg#y&u_H2tzuC3{TGP_mho~Hp9u*QlB^x>pU-fld2Q+zPCmRkzQ$TExma`+9802+x|B2x z_gMbR)VUM>Us!+DPL9^dOZaPk_79)yB`c)J*>{A%vIWQ|ulKzQ6BL-Jn8O4-El7z` zSw#KxccO?FQTRHi#kt+&;a)3CuvrXH%sbQXZH+V>PuId(B4mW^8k5?3_-NJ{>z5y1o;ZtkTfdgN#oyb(CK!S`y=GN}?X!rTOK(n-^fu$erzr^#6OzchrrqTahW9%TMK@_b^hm#BHrK4<2hA! zFHMbMSbskk$Yw2e^sY}{y7zM{NbjqR#_h@s7K5HA?2&{1v<$OyU9Gzxn9n1+{z8gi z^Vv5KJVZY?EAl4j##)b<=M8^{SGgG2Bx)^%)HTle5$GMLX)*bJ5u2uWC=*NeaAsQ5ulFl^4cx+Bo!! zxSJMtM~`#uy<>0RwtN|tU?0Ms|DaZ6EUlw|wQLok%LW&j|CyqsUg<{aUWl%@GM)Qt zp#N<-E{MlnJWHvnDZT7?VV!ESeH_k?rMt%`JQ`|v^(NX`BHY`j@=xo2DA~zX-iGSn z7Pjpj|A5God`r<$_hRr7Et%)vF}-a+2cATJr%GHnA8SWe8>!Q48l9|LBxDKXU-T{b z-F138vHz=iGGE)`KC2Z)RN7S6SpD9ZiTt#8lSIvRB8fFizkTgKnqGANUhgke^OK%8 z|FDv7%)UMZ5|b~Vw&{)Av*{^lmY>FS5Z~9l4To2qY+iTpv5TxO}PdZEI0*@$dJ@8UWvs*h4$xhbTJt5<92uzAbZ8Q`a zScUj5GQV@N&iS*FSI+#?K+CIFIr?wy$V6w1WRAj@+_|=(&RfCbZH3Q8 z8!XqDP=~+?nv;uph+=zs@ul^aFjw@;Dyu*V2PsM3t0u-1e!i?$E>?XtE&6Io4K zvmcI|T5{2Owh9h`jqcaco=@z2X;+SMFfBa&(1e*lnfFblq^wk>L6rG-Fom~7dQ&a$ zpF+DK%yY^%=H*s-$}yI4zFGxo``{QF`7q~=xJ2AvHt$-?R0rgb6%~Bw zlob(LU+y4wR}xX>`k(kUtxdblw9CPHT zbAP4x+H2PcTWUQSX;N|X$Yar`Etaj8eg~fZhR6EpE~Pb#jYWgz!lx#E=+i-(56+mk z(MJ$%vuG1zNra@NREr+VzQcV;PyN=!ANWtQ*YeW??pC`TUu+*NH4p3h4nWn2O~X&l@>0SH{5hFG^-!?h#cC= zlW8P51fb20Zd{A(et0w0&-c7b0K4{V3!LhEBeDH%-pAv`HmBz^wX_K;veCSw(r{;1 z8rjm`Bi@6hDp}ye<1iOH^_ma(tVcg5<=7f|;||)qEMVzUaD5gj93Ih-u_I>CaDm^v z1HNY`@^h!nCdf8txK(Y4KI@|Jy{fq}*Ax@paWLG-)n1VwmJnE%Wh@vL_hir3bZ>BO zrN8lsO}gYO+xU|ivTC z)7P7SbY%FFB(npL#2ID(5JMIgS$cLi1%}Tq%V@HWuHq$Asek?Y8NH6KJ;i6x=1c*C z?q7IrC)R(}U>3e_UG?d4r`xzk`#WxPQo>?mMcw;O&nQ3VQ|k?$QI~V#*LM9(ex3X% zbDI83nYFLkwpIonybVcLizAe@Ah=}b=gpUaAV-XkEyd;!kPt4%AvPh4H$FsH8PnA zF3b2QJ$J?S+^vyymkTUQ?bB(lUT+AM(}}&V=Ttc0dDc|TMV~*H6&-%EAGgiA8a#Q{ z%Zv57WWsDTE#|6ifr*kdg?7&S?t$L4d->gI%m(*shm(c{KjZ}!9>gm*p)$2ZUVgkZ zH7av#?-A!!SAW?wwp+}_8$4;&*H`g12O5-?Mw;rS&s=-5&exFs4+38vNiDV^zrS_ke)f5OYIc4>~FDLo}HFZo?c04zE#!SUsWp#@tM#qaIqWPdt{&Xz9Cbz zGIf^qK9{#5{@aR`l*8Elfn$kKGJ8JS$~b5G;VtTzrE}B$!pp0RK};WW%$GZ#*`z0E z+gZMN*u$mXJlAmkQh#l=r(R|oArW&bl{k>*$JOgFcANe~dn4=<#;&2?yS?RM9~a3k zFNt~7`H}e*{vt#qv{`OWH9ks^Z69x0+d5E=RYF1$*qrH-&yjI)#2`U9klJ z$7MgE17v(8PyiGPfkB~AkU#n_TLj^h7uK;HT7_ic4p0E8g)toG4E&GM-v-4Hop0d;6O^ zFOWsLUUvJ+_SH*Q>nxf~N6Mq?JbLC`TZU5JpV+!wp73}`;YwD{T1G={^PZ35#`vVg zkfQp2s$?edu0@@f?u{Kj?eC`wyWad(yFwS)RlS+Kny`AySbOJPmRgF6?(iLpxcSM}Z|5dpzivva_5Y#gWSb^m%YK14COQ9{UTjrpPxQSbz zbhXgG0W)jOcI%5&oheF89-rtPi#nkkIO-jp{Ot7PofL<^Lpi2XUGodloV8LfRl0Us zWNQuqogb|nhI^*?_o>JVckyWCnJ3Ih!vlnFM;=UQy1ragD*hmo{&eK!A#HF+K zkKGOGLZi3~iNA!Mwi5ZMqI_LFqZvMmj>ojIt|{|B)A;+c3Q@bgTua(+!SOf0ggk&X zI%KYp+3|4~-Cv5Y*&N$g%Nlaf>Ko#W%u?Qpd!iT3$w$25eq6qiW$MKmF(Gp(vaIf| zW_G#E8N>QF-Z##03%cujCy>|9q|Yi!ZR0|o{~h({Jud1s6<hR2t;@9M@SV1{*~3;J_UGuq90dxlRb^B3x58#vvXq8ZlQDgRpSa9L-mtZ(g@<@O~r zrLR9l+He2SDPom!I1!ZEx350oKHwQi_1c#pZ`!Z;*NNO-n2Qtj}OyI*QBknO8?_y3Q=v+%~@|B5$heZyFisG{kEuCUZr8D>cVB zyH=ni*Y9mEZGOk_xI$H84r8bY_9U8ngzJrfh`0dzc1e(Hc&69Bcqm!^_CS+4Z zRThva_aeceuz509fBCa&DG3v*ZR36U(j{#}zU*+#vwy;>sb0Fr(=tyUlgD@&W?1fu zzsWRfnR%4>l0V1rkLd5w#|s+VTRv8rocw>2x63~!ru(2Z+yE16$nIfKtG_*JWmFk8m+3V(RVp?p3`3G1bsyKNp~ z{-f6Zxm&rZW9IBzs>+0iUQu>&rb-$6)>Cn5vFz`Kx#R5D^M>Xu7WBS+OU%41dV^Z2 z{8jpwO2KTVp1D|}NS49)C6nPq&&%`-vHsX!8X-=03#@VX%4E)BuBSar%=&XPtZq|a zXcViFI9A5qJ}wX;okf4ZBzW?qH&%W2?w@0tfuqlq`(tky-lvoQnx_{!Xed+rYnkKE zb2VT!*`e3OgOB&|=>|*OfTNw1RSJuP#ts27ylU~(F$qpC^TlI-Up<=2^!z>~O}~=n z@v_U^yj(V|PR6emc_7ZTB9-WV@FG(vPNQhU%UWq(K)lqr=_8>`STQBV^Z(m&>r!m5uPk3&$PoMeSnVn=vPL4V~a@2#GjtukWV^uD-vXle&6^_%`obR1nErAn(TzO5xUpIk*z>U z_ju#q8KVM+Kpp1xNN!_x(9r``k>x=PQ{iJRzh1T8J9XB5YjalT3KjE0HX*4?aY(kj zojvjPYlP^-vsyp2-OJdA%Wj!ivC=+S%4CUui2zd@0afwn>>=x_id+SM2?wEf-e=8w zC9aF8pK8?Lo#HKAR~FV#7geh;c%gFr)M%S%>H7q!U2Fx_OH6Wzua#bTrOr9)@?b=L zeUaYMWATX9J9jRbFM3;aMIGDIBhxQykntN=-1UO0Tf_R9r`!)b(q+G5N8O8pvV1zf z8VJ;%$nnyPh*_3reHqA{%8s!h{S;l0-F@}Ym>!U;9aVH^NvKgh>wdQcHN0DCU?Dqi zBch)b?`={w6yB^gs--H8d&u%StISEl7XOvW)=g|2v*tRS*hyPWts^?3zKca?Y=<7} zlC)))%UI33FXcuSy7Qz6Q4_lC#?x6jhxltTg(Q0M97wn(CeCtJSR`%Hw(ca3mN^NO z%be2tJ2dN7CzA1|-rhh^(%ZT+AyVhcZKK-`xegMBrH&mZ1?!Ano)%X_zsk~P;&V4w z_}KgKHto)0+QOb2`R@CLYg^StBO_n&mQ^q9GQ~ZTTec1Xkv9)C8WIy@{kmYL;Ua$L zJjP=;zS&{d9&(gzne2#e+=)zl5|Q=fkL=f@Pk+hP`kh{-(PcJ9-qmUDID9^P66bDK zJoHOr7xt*6K<;Mz-30%Hwp;W@jruahuJ+#k__t40^0ki!y}k9+KP@$>=Bmfa>JI_z z7;mOZebMC?TWMY$9&JeqkCJ3-7mAJU)IAf|raOr$NIV@n(VW_9vmnhCS}i}t_L0T= zBGanj2Ho?DNW+Vb)ZJr+r4x0R^@x6v*sBY*(!>uFb>IFUirzht$^ZQy@B4nK98zXQ z2pQX)ay|>M7#cI7h#bP4&xerXry(0gHfNTMoN~w<%K0^fIb{(h$zd`qA<4Ple*f;T zd-wgkuj_hTkHejH3{`H+-FekAe@X+GUO6io$>8#?%Vs`_1|2Xy*}7%yvQPRy_Y3vg zREhBY;Za76d=vTi5I$rdM)(2xX6!1-jU~Gus+c)a!d{*r#*;=Uo74R;s)#eApbhj} zPRHMMJ7cHOIFEMgh^&kTR)QXZ8Wwv=NGvRCi}R%}G>jCXQ+JVjoSJ6SNDKYA@gknJ(Bo}J|=4SKhr1|w9S4(7Lhq{;2`cONmdLE3g8|uj>0_Qi;yC| z2fNCjVSg+eA0+o!FUr(ftITx1FVbqlVv71Ks|KfA1-S zdN#i1J;zC3b8~J>gLv0tqhEZk&7Twn)W(Xo5n3Sh=X!1};#AKYxxYNi7`TN?HEb2& zxY*^t=a%-yF-J;%3G}CgI(V^0=&%2>eFF~kF%II7@_GyP8S}jaIT!zRLOT2ULeley z5gK@BhL@K7?83E&MdmzG{nXHJ)U9TSo@16;5{(BDk^Vl(lp_>of5pP$qXlNh%{u+$ z2CO784VunZdVPLtXd!u=d)mM=OpC1o6I0qv$a-1+hN5{4xo!UWNcQYOj&~cCS>)O`Itm|l-Bm0}PbJX+t5UHNjv^9-OMcTv z$Le-Y_&y|@u&J#o)itU$9VxvyV{m>mTYlR-=>k1wedYElQIXk6=2?9+@6re5f7Y zrcA?SFxx@VlCcNfJTKKG(^)VtC+ES3tnpB@r#AQ>aA4HprW1FshfQ|G;->VR#iVk= z1%+3!ON1~i*$d4xBaLMh`B{wCd^_){GW>~)i28f(;a8KSex@lk&>3mrc>wi-L8Dee zuXz{)yR(g(O*FDtmNeyZs;)f$H}V^iqTZ`n>NrNA&qTNB;jPEmE^abtit>kZ?vmUY z#(w@7_=U3#Ev7y7@KK(vU%OFp*AUuf@}E4uWq9-&$GX7}tSS9ceWU^O$nsvCB&mwE zMAroGMjEf#6ddU2_7{BSYu*piJ zvvj=T81N_%;Zghvlz?{VALTz&#Fx?+$`cINX30;ojIV!QHfInE08(3(0oVhm9idjT zEZhCob?WWwJEo`~i9uwDTN@7$DQO-;1S4Foil&DwnGk`Q1)89e_8 z6JvQ-!mm_qjbp4n72M5vHvSgj9iv)rr2||q@^(Fvqp=(bu*!${Mol-ONT+SQ6Qqr1=B`KBG0POD{Nu-)1Q2d|nVb8T^<0VK^yw>9WsaZE-fdW{eA-D? zKx|mn<)zD@y^#U9Aha4%=z=)8(Yvq3bc*!mc8+bNiAxiLAUWn6;qH43r7I$~0x|4z zasucfMT8n!?prk5L7cj=Rn$MaS6v6pL>^_)bz^}sSM5~dsYhTY_S*$d`Ausl|8Nhh z+S)+m5y5PvAasAWfw2s~i$~P733%skaGCFUMWJ7dm+cOZ1tJ!taQ&s4CIKhJFSA(v z!PY(n>=z|-m!>xpF2*htS!at-FN-Us%i3D`kf)~VZH~JMWRKs~#%2;5$ShVz55;-x z3%jCxF?2sfeLpe@r^-0PYiTq`>L00}*9l^H!)uP7RGx2U38WTBs08PUc-K+vsQ2iHR z&kS~+C_KP`z~+dluv_YqLCk#Cq-Lo;^_yxN)Wf8b4&;D7mGskzKT(PQeX~emH-MsA z8+gaQ*xNlczB)H|lvqqvPR^D$nFoeo^-$gLV1$P~&bxj(#WT*=E5T!t1cl=@>wud7 z?XWCp4tzupVCA66lR>HZYOSWrjg%`6np62!-RaC;FirKT`_hV=TZZK?1$gl-HCe4= zS#_1));{CC;{ZXyYF#G6oPn!lQ_X4M?gC!_3_vXrNR|}29zP0kVvPF#7M{hqond~q z1{zVt8Fr9szViE?dc;$p&@k{N!iBC&PktWiCFPCmAYLo-;>!O_jJ;OE|K0z2yFSM3 zr+Z2=Wt^cmt|_@#SPb63W2IiBMvcNU>c)!pB02iu!03V}r4LZogR?BXYCv2W=TmGI zsZYtIOUEjV8YmVWu^;-zsMUOWz&ReV!NC45C6<@r5ko3?XiA_@w@lCap7; zSmni-(N?HEPE#9a!ySt@+3~8Q5@B~pIQ3<#!duLP#zRRZZ^J2U*mhcLWF4D6z=N9F zzENjUji{9Xy7U$-jF zWcOw{>mR*~xR(}3dKBfSkmZ6~i`X7?fT}Ol<-bN47}en?r5CQ!4EEx)hy&=4ZoEyu zLAhX%&jrGIckQ`q$=%DQN@}$P@h~( zv^SM6uGXEVIyfj-bb~kUon4O7(J3SM|528)@JGmL*hHN( zecA)uxKKALbDz<_W&2|6HT(-D8#(=;IKcli@^MN7?GU=kt@=-HQAR4+y>XFPr3~v8K9Y@GQZN1Ga%qEE2p>dM?!Kn%@JF%d^c&?Z`I+C6EEzE3k zJ<_U`l~Ov6^zpXjGrRAxz_WSZbYOW-xkj_lYoVXHYjQTcIJoc9Kz4PEPmPpf8PR$@ zZPgS;*SC>xSVww-7}mXna@;&ns_r%nmcDR>BvsRjI6l&_iPLGD*BkdNc>Hf zWZw%EB2I+bQFclLmMxC4wEb+qk^|2_Ex)5|@6C8mRFe#9(y}&tz#hcBbm?K!uuT)~ z<|>PQ%hHpar>X@M5k_$@*`0^3%Z5-I#r5VnP5>dcbB69AjvMo2U%qf}3V5{I|aXN$kW4+Ds;8+T!myNU$GsKwCrE|9Jxqpz6u> z*$POsXob3ww~@8PE`TtBS-ctp8+fAO^4%VfBHCWM&6m`=Z}RgJQIb(u=;z5Yh!ZT1#?_zxJ^ErqQW0d!kI zY~eHRr_v)>8SQ@M-hR4lUgNHdRLfnQS#D^Uwa1b6Hy6>xD#U;Q<0tx;vDty(ktGc% zPT*X#_IzvRfbS3py0rzPp>&R9i}?+kPYdSvLho>OKhc~bbiN#E2vzT)iO?5X!`*4B z#&xZ#>BlfhX2I`e&+)x7a@-9$NcTwG^>0#+z8=U-XJc-G%=LnD>PsQAa`C`2a=`$l z`Mh0{RS#(LJBEr}&4|BSLW>?aQ)RXvvbD(P;~6~+Y$sp+P1vW569n+@Im`I;x&Ew` zGWfBMlH(f=}HLrdd{zpI{}ZbB}Hz>fn0lKi$hHh+3O`*?41Zqq4ey}AT;|g5DZ)P%)a%T zHsPBzOFLHq?fRpoA-H~1a@T2=@W0vpu0XK!^I&@&RXJnhYh-BEw**OO|k%@ z<;QA^7G;`^zNwNX?v9Tg>eNwHHqUz$7g*m#Ob5%KVG$*KR#K#Dp8I zF5QVYZ4mWC1)$Zvjx2kn|D1{&0|cu9&*O4vB8zp{uLK9yeTq2B;zT5HZ0<%>=7DKi zjs72XMqah@ecNmc8U3Lmu-grM58)(LN9hgc@OL;)WxSD~h}XY6n;H#dy?+*p%!I;z z;Njn_OxP%c!RlTcjDXRXy{2&0!V_~`2GM?1%=ZAx%cdF-1Vr9f;d)PzBn$1U9T#b{~}xm>7y zFqV~YXVJKMiwI~%?a9tcof+jCbyBt^I*U2gz}%0!qe?`k6%)kihc~fQnr@6Xs!rc* z+Dg~?yBJUuND;X%-N{#l<9u?g{L|P=D16 zjVm%s3f%$0 zE*vM<*i`<2B^}4B>D{G*EFX8im=Cv2f*ZhsaM<~{JNDA=m?wZ8sUP+IQ&x(BnIlcL zQE&DwNsuf>TE!J=IJFQp-W&rBkjL4Jd*tEuEgzJ29_wYj!y?_+2Iou2`rK^>?nD;( z@42Z51XCVp19Rk^l&L}Kt>IzHbj5(^99VZpldP$q3Z0z#aVJ)_R>hjlu{>Xg3)^vY z***aiRK5~~kD!)asj8Ky5G59o3tzYA#TSEjCu~N9?IRbcsZdKEUo?uQH@x_sas~8g zwWwECs!N}%aK0dt&&BJkx zIt9L+Stxf!uI?J_0UO8rx2+=HA{nmNyigQ@*5665$ zAL3dRNSlT2f%TFjO=b<~8q^5tUJ52nA+^UOgk!Jhz$k^J^5Gxj|GK$798oC9+_!JdF)y%DxUAmH=xGs5@YC$(oc@ptmEYu%XJDtgwWYqqjZWnr)`Chm^}~AN z$w!*}f$|AS@*?e6peZBu6d=_{0V=xFU#1p-uAXFFKe}0%iTAWk@vx)bzGK@TK=~>u zzSl%s&{lw?0~+~X>ks9h;C48Ff;YKnx;K2O(c;@tZ$Jj_)(HMB?~&mH-Kbftq|njT z=rFVE8|LdS}#bQRe+%+Q$^g=l;KvLF)E$7 zHwWyN&D{}>`F@eYUTIAgkbpXxg#vL=#3xYq@Q_lvqJ<`uwH{me7#=Aw_KLI?BoNX@ z!?OnnkmLsksc>%_x^E0s72ghp-T6w`f}1x9^ZhFIuthE0$ZApD><_v-sgD)@YT8tr z$B#f3iJOR_(g)2((&CiMrPs8fJL{^adzyzXINuhIEd0>)eTizHMcz; z(9Gc^^9A$PI36H1{M8#<#K=U=K8)L0f8@LAf!oNUW~+m26>d-wmqB*QQpZb%2|RyU z4s4uuK8|9{eS8!?Llo&U4&D@D4~aT?^_?l0CpQtQQnJMZ+#wi9sk(-1pn37 z~N1c6s3<%9QnzEA3vZm~wnzIJiC&W}HJk z@Bp-k4KFs#8JLpn>q!i2b<+$^q%4HwfLg|1Gt;?LAYs|U*4Ef((NC!-?VHyo_koQ9zL624xy=5tHORkih`wWb@v`UM`n^` zl^l`qd!Ov3GEKv~M>-Z)7$5u}xatCyk@p53yfJWadqOMNC=ewd5l{=_LtnXFNq)^Z zizn`@U@TEB>DQ6iBV57+myN#Kr-2R@`a#-AN!d zuXXqSK~`oLce{clhks_gs_~LnSl7_el-XU{$qS61hS8tu5qFysl7{i;{JsbySP^Q) zl438xa@4Ra3(ZqaG}!)v-|i{_X%IR8o+Ht`k+Y!4#g+Shhq8~`6&67qhK+@<`V zq)00@jXOonToP7oy$ZjT3AYp6k-SwpVeu1L)#DPYam8YVC9==&wuU8JzByKLQ08yw zp+a1mp)uAdHNouRXp}FFru+pOc8SKp5ILIfv zW$r~0o4`AblNb{D38a&Z_^#T6`(!Z6JoR-qj8v|kVT&RpV}rd6^+cIZl1oQ=B~>gz z6rC&K=BCF|IqcI&6iY(-g-Q|v%=;)ZhPo2+F+1O|D;MHQ2pgUe29_RacH`2|+zBQ@_Ej}jOMyuD%V9~Cm}B}Wc` zjb+Uk7<$fYJ!>4E5My-Va5Ub|!1Mp<&Gv}9-!^IJNn_it?!JuY{zw(^g)QY&>k>;? zC9tmB;Rw9RnLK>+J5-S`4hYZ&1#$YEa?($9rz>>7Ub2+gXp`M(o5B5#m!wG_SX&@S zP_+jqfEGNN-DkUR2U?QEl7b(!>8L@t1Q@S<*YgUYXV=;LXC;r?VC<+YcoQ$yBL*t} zKsocgzxg)ZRtgvY{EWK?9XitBDSG2JT=zx2C)_P0-13k>KTE`Mr4579yTU0Akb$e) zfnNkYvb0I+Q=Ong3GWExI8PJLUi5z}U&QrC8@ymt6st4*SgHgdD@;)`Ui;tobX0MW z^2hC1;Dx#Zr#Fa#d{PKL?jktbmnJ1_ePGb`fa-t38ERopAU8;3*@+6=KmlvB4I#DO zr>7?3jWr=R{+|1PXIv53@R()y`OBclroLm4{6a{hI4y&Is6mQ=hDWGqqV#985kMdQ z{j=zcyF82x?YjyA$ zL-80w4^`S&%{)olzu|c1mK1kaD8mIv^66e@5-?-2-I?}8Id_+?;j5?Hz6;ypy zHL&Z63d(S^-Z1D>+WmVDoZb+8AJ<}l&S;XNd;x`+(oxN^1G z{IOI@H|`5;Z=?!y*g$;aQ4dhUi<5%+lPWPsk zHY<`}<+kZ_1dUjpTpeA<7vz~b1cq)SF|oK`TQ&xW7XdvZD_7<-`FE22rWBd2=Dd=+ zN)R%(PcrWI{SA}7fC7~VLMFDnRyk6e7g=~JB9W|IQ7KOAN!e`9EzURTCgp#wd@T@A z`1f4KmE+Eg=MU(KhVVH4$Wmn%>qDN5u!t^{HC%hgu0S7SNsa^Ua9z2YX78nw6TN|m ze03O_Af})B-=Cn;Fc0(jkx!Qh6dkDaWV|JX>TrN1Yf#S9bszpc*Hj+vI9j@S0n>5} zgTZsCx3X$1K*?#Lzr{X2x*F?kWan^s>?0Ww=o*fF3AkmYpS~YDo@M8eWreyEi3ibv zPlXqs-{CO4neqzLTABBoN&n*VC%&6o#ReSyxstAo{B7E$uH~y*QQ=hmb$tTAR8!#c z4@afG=kHh8p$anviJ>1rjtazhzr_afp0*Jz&D-5`%}2pSoX_b0*}0rDh?H@ey&>8X z@T%*vW_q?MErCv?%E3?hMryB|;i&*An;&}Os1WG@_uzx+<$$WFg`hGr2XBW%oKUoC zWu0Cu&)Ax_g-OISdb-$lG&36+Qa#5cvez|=w9f0Wc5)n0Foi;^?W`NsJ&?*DXZ)hs zW1y}l)M?(o=Ppd59~V%H2il7*yQow7wOheeNk$V@CC1@~wvP(+M;e+s35~FUE((3m z@>F>nwQ22KrUr}AA1-S}z_7*sYBN!U5_)* zwLFFJGTL{hlab{@5X2rs6s@gjQ*31hD~nd3L-lXk@HXK3M4}Z(AZ+x6KX*W| zFJTXBw_vk(EG%Q{Q1Olk$KrOWNY@#<^62U1t$wbwTiD--vVVehv3|l$V$EPz#|;EN zP8{YxRI<;d<|hHPo#1WEB2nLztcup}gr$ca zLgURJT=&D@4vEQYpv}bqI@-~mV4B-z%O5|BU=OJhw47r@DbTYSobeF_S7kPcs1rP~ zh-gbv{kZMxW4$7L-faRII>V7$%#5(DgnY4*1blc9I*FWq5eTFBM?ic30TuYKhE?D9NXJ*>`MLg zeBFT1L-OL7&!O!_1ig{2<9+&xv*<{Dj(heIn2D)F#$QV4ZE9Ocg6DB!q}wL@18v5+ z^8ILkmR(m2<9OfcsKr1N2slky*ssQGmw7++7r&!@J2m*4Z^dyf7mMw`0kEp3c0R`T zO{Exbs0+uB_FcRL)_?~R zZML8B>uc`DQWQb%1bQ$Ou4~Zy2l4a#IzLR5kxMNjzg@UOYoA!ps^riMjmIGF>p0n1$n^eVdCH}dkYt8SIJu0{zh{9Fa}xgmSyFN)5nO%$2Zfx`u%a= zr~+zPA}X4aC{vCobo!0*o$ZR}+#T%(Uuc)ctXnMfylfO)AM7m0-5U7*IPu=pip->m zh<2V?{P6#M0Yyh=T`GLu>?LkeUYQ0_el_14HQy<_qogA2(+@Pg=4Oyv(kQ2spOEs5 z-{Dra0s69)2;hHYX69wt*Sbd8A0~(r(JqNSZY5gg@HwcN6HU(UG(%!w_3l%TVfrp6 zIOs6oFcw#Ji;F#i-TEb5vNg&y|I}(gTcJs<@0(P9L+!Ye6<|*+VhQ|t0}}SHf74=*$ID6oq3TU%x|9SlnckDF2g*0dLe2 zo$YySE{BO+SK2w$bN_brQ>e+`ux@2g1 z4=M;CpP${B~ccYLTI*%KM&mV(3bt2o6D%{;3^_H6< z%k2bOgkM9v7vjY-pE*w68=kh`{R(VtSS+3=bVtkY<+(X=ExmCb684b9F1kyu{_C~V zbMFJ7+2$mfmBWuMJ(wH-%$ER5N+q~l2W=jnq$4$|LvaB?dq5x8Tf+(HNUI~2tXe`J zQnf8Z+3khTyWDo%;k|4%ryP`wb~yBPz2$odLbP@Zbqa(4p2nw-e^-UFl23A|xeov> zBB-A>tj{?~waK3}b3A#-PtjryUC8Z7e55G}885UaQ?h^8w*|bO@a&hDMslNAMr{|j zbrTtSGV)YED^g7InxGKQ&O2N1bL}N}H(T)=_aaH#M60 zFmnb9>W?yh!4|jrl-+E~1s^_&zzUg{khU;iS8KPWF=u@+2&3{k*rvLEatKdd+_d5r zvEJGK?Z{2lpX=uJHV;Qk=eo+hG@HIGDLuT&DjLYox(p)^djdWO{v$bL|5?4+M(WMD zkk?_=Rjq3ee%0)IXs4L4KfHiHNuP4i1iA750XsVv2fCKe*_*}S7hVLE6I2%x!=5+( zvzulT5qO%l2Wj|^nidc79%v_88%T}9T}ZLF0b1UJu%BqESxSl*Ytu!@0M`2vlb>)= zr*I6Q)c`Edx)@~uxpoZ=mH+6)!`X(DXGbP=aY=F-qc9qt{ipnNaUD_wse*GcGu!G7 zxU?&E;-!io=b9n5s;Ox=F4SnMtl8>9jYTGGbLdb3AW~4UeTFgM0F;WI+2dezp?V)HkPLx#1hW{A~7)Z3G012fRaJ|ik}Vu+3z8Htqmu9mBK6g$A|=S z3;H|H)OrbeGzfe&HQa*_LRu#LkD^VX%^mCnh4v)IUQxs3!@Qejo4ib%?RBms3Ua*8 zw&^VqEfiNV>9|G}QOR{7soDB3SVS=CwZL@e%Ej>ly@Rp#2{wP^JP<$tw6UJINWu)A zGZ$W;VTvds0A;CweHY9uT9YEeXL4xa!CNa9ugjJLcz)~HYBN=p`C(L@F4XU>6=ik^ zYT^go^?kXsWirb24fcC5^aT#nc<3`6OO>g-uClxPh#nl2L31j5dN|*z{2xvv#DYgS z(ex0AwUWJ5m9AbB41Qq&64lIx$V_F&LbM`><@KuH<)&-R27C|wO!(8NJc{4)+MR!& zCo^SZYLpV*3KbeoK>Z?8^{^H(C95_7ViAw{E_|U}P<~uZkp%MUEz@CSI^jMVhdMvm zx$>?NdlSQU!9)E7peBzexi2xPsAC-+eGF)*P>Tee?uU9GR0Im$oMoXox1YW1fC!6^Y!fn9R}SIBdc{+bMj0BH%ut;ge;IadAf(fYFN6Ts;&$B$hmYw;r~u=uaU^&A%Ec$8e6BI_ z#47AVUBjRw$Q5cEP>D%k6{znNi=#~a+a~w@4)rn7)u8F;)@-^Q?a777;dgen?77t5 zFT7Z0c=;}#Lkhy#7}ax_cd4f=Hhe!;Rc@LT&~01s1XdICI6r;y9_^NQhnm_VT`^Cp za$>0v_M^C{gUIEV3kyfMYQ@>B6ejQryt%ddQcopX-M0`mXI}dL`P=YGsd3@r#nq*F zliX%MYfnht1Y^5N2$d<*bt(5YxP4e@;gR`W$@^;|xzFQRA8L$zD%;8)rT1>)Y?v0E zXGpQj6D!^d?mUAY9`C_@!I3E|@$sp+w2=d;G}$3PLz{9`J`~@B))T^SO0QX~W2CF8 zZ$Afylx8N@fOOTVJidw?ESYo{i~-c$e$K47%-?XwI;=F?VV>lPdrZ7s+tEY=^hdeu z9VP|=NR<1gC;GVbRO((ZTfx9rdzx?J#2=Gr1yEnXao$8%J^8Ot_w?=LGmlf9vH-g% zz5J+$VP~+;k-8i~MV6be(QpEVv*m(l!bOv1zc@xgKtKP?rThJ+@tE(N5MqCTH z^R>(=z)se#aBH7iy+M)ih3hYOaRlVk$XlO}}-k8{E6#Tk`;zS`S4*P*oq-E@EPD&_q6yXX} zaV$ak!`yNQ`d=)wL+rPavpN$E%oN%cerJ*V?O*r3l#u7Ws^KWniHEL}csEt3Ann_&?`htznR+%$e9& zex&g8y4!aQEdTjnux#EwgI9YvU_yZ3{vlwFPrl;9bI7Y6m6JX@2VcM%PjR_Bq?Px6O-v9P>Z_yPz6a@U)M^94AnezhJ}Y zyTQY@0F~-#0v|2rcwr{Kn#*@*&>G0gXmjyu!g-UMg(rk+h>)ChATPW?XJBoyHrv@s zHQwM;wB*8?Dq3Twfibe@5n;SZ$-5YxW&uyva2%){hezZh^NYPKh1%-G)0*SLqs5Sx zB)xp-k%+>$mra?rfL#C9eO>vFduBt825T#|RI!YV=BC$)Ik1hhVZ{&h@uXic*6R(d zAIXl2wMNi&iG_<(`DbQ2JN4!}9C!Y4E@VG-=MU>42J0th@c(vF+gvCz4^9Og>{V-D zEI22o$ZS>+dCYvKcRMPNRFZ3V`n?CH>yBXqNycl}A)h|G!GFsa|7cWpAZQ^4NG#dH zK4&V|h?!aVDM4rShF_bUV|k2ov!or%7f)4civD*krLq(zWywvA@Y%1uH&8mz`{Xjz z22tXi)+2Xc=IJX(jszwoqZ7#}jKZB*HJ4p9of2MRm<4_CfCFyWD??`>${a-3pp_ck zG8S=JsUgyEa-F3E+qXlPHRz-Q)cMcjG(g<+)CYfSBy)rIV7Lr`Y zRu|9QH;X7wkqr~h?QlPo40)${p0Bxb8%19AYkU1AIP~wi$M-G$E@;vrj8|vv?a4_iUX* z@E5bKnZ~d2`1Zxh64Hhvjcd7y)w<$D4Pv_hzghP%zl_A30^W?$lp)C#FHNP*9Ryb| zk&vI2|Mgbgq_%#!a^b@Zy1kkO)rputF?K`sxxG4vF`(w2>B)}F!gFOosxHumSwDUf z9v)mA{IGilS9!tn@m4{f!TA-pNMoisZL#f{+pr%byrtUic{9{7h@bEA@9b8goc z@M>nM7c^>+Uy2MvJVV|tE!cM9cZpyl_=_f&rA)*dF}q!CVRRhts1zCDqk_==aV_H( zP-zZx0QN3xY;C5z`eagFCKFckLs&R^i3Q0Eq-&OMAi=le$e}$Gh|i%2CSAGGz4=}1 z^N^?$Jdd1h0UCC?-uSV_uJouO8|2Y2$})Lra0z#JzB-3hgc`7)nSGhHT$daF@fYM% z*|x?JJ!-)!Ss5MhX~&srUZ7;9ddxPS@RE^pgg2gpPc;MXc>X;{&;yD_y;0temOagN zxB1nB{c@2;4X&Lp@nAOzMu~vg8K#)*l?gN`>oK;4Pg-P>Qx_Za&<>$R7BsmciE_o;X!$C~3oHP^jZW6Lo_vOH2*XREn>z-f*Os|XmnI)ypT%j3EK1*T> z&FM4%mVfp`Wxm@YN>cScH;f9*8mF{FM89(dIS$zNZ^p6o+^-LVf2cSu2c&=gU&V7_ zqz30_Y#rAv&{K%W4B3&X@M~+a|qSlLiDyi0^Zh&-i3IZ-&ay?W+&$k^w$Mb zzud?VZa!8NCUtF@`2~!Oea}+O%TgAoRDJdQYoD2o2M$TYCcL>^V{0fY6u-SG5Vd6iBh6?$W$NSC`@SY-BGtld;{!h1yXc-FKGXQHwB6jnWzktI)sA_6 zDcr`*lgl6e8}!)8Fx0IovjSE(v>2@-cB%F2;{eB!e|*;O09BdJBH{EL)o0S~N@o`q zvN%Q@f*-6`kJxZx+b7YN$d!Z&n4c=boI5<+d{Vm)Y8G1@yNj51{mzq@umQ1w)e>{t zi&S*6aCN|QV*ZaUjqF>{+dxuv8(34IMed5+p7y6dn&bAj!f%hpNNA-?5JshZ-o71i zQkKnW89yu^I{168BI!t)m023LLb4YjtLp(Ey9gTX;f{`Py65F>SX%$MwJr$E91;U@ zCe~61_TozQ#;A6Uz}GojnO);F7BQ#T>WUFr!@wlwR5aJaLkmjifErncuAQexi}Dk* z#L32?*eP` z*WCwx)@Bb6VZBQdMi?8BGT8~=36=lpT|4A&3$piGFUm^5YPxiT1c-0zD>8!e4t2w3 zr(EAW${)=sFMxk&`W%-fCw}2tbq-p_`YZ9fAVp4R-*2f4dv{ExRvpH6;?;e{w+t`l z_rq0ox0}H$dic+)K4}t`zC(PAO?`(-tKh~lk~P-i42P#C4cHt(3JjxLIgsmz+!-R)aoXG7o>h_407f?|@3Y6ZmJ`224VavfY~wtrY6-4f<$rZs;$%R<#pU&1`IMM&1~42DKQb?fe}+W5my zC!M^*mR{dJCEdR~WK#9WblYS0B`i-fh*51*1Z~&YQM6`~d+-s^unwK6kEUKU9@87w zloPxBF{?LJ*@o)=Lea+sXIR^8eev;`n5PN(G-L6FZyJ-)QV{9eyHNP83m8Cr#T_X!qXjVaw#b3;Ut|DVs?6qBfS%Rh;qi-!fty zcEl#1!+=Rx?w&?QAGqjbs)ji`M@w^+gOwDFU$v_J>v~?s*+k<1e6-HdO51Q7jL%c+jZFD8=~s4uJSyQa`qPl3heiimR%uV6}a-vCLuSVN|vpLZ`)8j24aMJ1Pp?iHL#H+H|eFj6>~E4U0b)KlrSa2?L)(c=|k?ii6q!!*cdJ_=F{% zL0G^t=H|0H;R1ldFS*vl5gD6&5T>cmkc`6a9Pc8OX?|W6~6o^!EGS0r>Hx-aJFB2PqnP9=f**S zG^2x}Wb{Ma`Tb(`4<=p$Y@i<~fAN^;PO}I3@tf|4M_}ezKjSzHL{h;K zCf_R@mopdojx|)Z%hXFnZWxG0^>uNjDFTg&ih6=dm;r>ZN%E~qw{Xx$D(#|V1K(p* z(DKD$`#@nK3XQ$&kTSARHwVg*gLjo}@+V9tjvE!Orrn=E%Z$EZIsJT0P$6OcmdA2{ z@6f_tq8jniQ*+_Ee!3W(_6J(csBIud^9RJ`SCy)3*M*u)ZrAQD(hRl`?=eKKJnF*OwsRUtkGMb-Ct;@8i6ALNzd@M43a5m2j;g!v zyS$9aiPy3VaemAIoj)9HDZ55b^P)))ilG41CC`h62eQS1*qju0_LfP)x@?8`d0Pjl z-L`5}%Uc4kw$&}^wgXs8`I_Ox+Ew!nH3@52)i-97p}gL7|A2EO)ZaLqo#WQBNcVZa zXD@lHM|OZJA3HFG|C*ofhCdT->G*xYq;vg*w{HMNr0$uqwy<9~-X*)&er8E1E7AEp zoyZmo#YQ(@YveQm@sE543Rn-&O8kLX*3Wf@v24rXpO8ZtMt(W`|0C+#uoGKW|UVa{Wrln#`0XXi69V#COm5TmA&CneL#lhT~$uvv6i^^{DdQW+i( z!t?t)-{0@`{muNdeeQer;kvKuy6^jXzc1r%#OcX8gmq#>(vgck`iO=7Q^Uxp)=ckv z3DF7Ryrgba2QPHEs&-}1i@IjL%Ga!$owtlmgQgfi{?@@9g*l64>&cN>n`>?DmaS~V zX^6Kgb#=(Q2Cb%tTNpB!=>9ILVRqgodH(ybbaZ^XV zY5~Ieh~0K7;oU0tV~m5+=23?S#?J-j7gyIu)&{@q?qqH5A{{7-qrR99*4SM++ zZRLm7?CN@*hQpjpe6*@}`>?&n7s32GTTgH!+!?v<_(DVa`R4uxE5={>3+?AZSw!Xs z=TL4Pw=`;L^Y}@P?fxTY_D;6wB^|0x^Y!*d=m;NQZ%fW;n?MjbS9e{i58YCH*s=Lw zF_%ehotYNiPL;dOY#m#U8gJs^N{au?tgtAJOgFBv_))Whq!)4-))6oB8lJVbYfDlj zh~wJRx%U$3r`kCipcN|ySEhQ7au#A$+^2ur?oGTz*mvrPT89D4Gq}vs-H!A0e0R`Z zn&hDazGji}I9$KnBE*C_@V0l*f8&J&Cx{W$2(ssk>9GSC-z;lvx!MjA4s+Y%^{282 z?ywc;-&?;R=6%)%4o^`)EWi)O{g#3=Lpm{Mov-@`{$u>+3CZ}r*|_&HtG5ByIb_(R zQOXeZetb)Locmn*zko^-Wii;!a`W58SCII;C-MIRMa#x#CFYF|`4i|%qDp4n9jda| zZLiMGH1<95bdwF&vv@0am*=U-%Xz|+4uhdlHUf`P=VKIE8G*P?7&_{j4rX*o$}+fC z@Vbt!xk~g?2b|--)Jz7kw-t2vk?pDtir%v6QWaQ6EV{gqQd-R6wvUD;ttD9srg&73J{YI@`NHLiZNyAL@mCkSjf(@vduSsXDM5D{E984~V`l3x5S$%Q7-@cfL>{yKP;x7+|7_s6!QW0w-*J_*WKD{J_N z*jd8Sg6ZS;j(_tG?l+M<+4Ota?&00B7h(a%t-02-5)9(FG+tG;ke4@dL;9y@#ESZr zsP3()pB{OAP^RZUt^ViwY8m_whr!OgDy@ zs&NhbN>rH@cI)*+kE`BHHNFlWdvA9eajt1|qeSVBob|}3#5;!7!FK({k-mzF2%r8t z)N2&Ry{9ud^{9?5!|m;bTwBqhmoNg|;`W#R6QvYy6nl*W@u}!5!e=bjxgO=C%c~tn z65Oq6y0(EK=4}tE>*_a6KJmD(73Gg>Vok4d&rKxAIptF=(v~_3@|vC|C1t$Hv%OZx z(W}ccx~g+N+_gN_Rt}|GZoN0!<%^MSx$a`xfhkwMcKbxI!6FVt(R}=xW=ahAdSf0s zXSMgHuqb$(%YOm$!5tgP^C5rR_tD0A@52;h_c@!HErjhG$zLp@44>3390Vb8R+qg; zmhj4>jb6|*PbuUP&fvR%gQu@tzP9)Nr5|eTHhwqGe`k3Mwni>MWl)C&JJ3B|#QPmgSYgwQ%=v8j&Dx0>@fOBkI0Qx}`8Q3w zIVuy`22DP{5N-x$2|KSd@LQ?ZGfT~MMTthoy(T5Jd$c~|7#kZO8h@`#Z<(MxrGTM# zqBgkr_@j!u+`rQI&6Q6l%_G%zRt3gI9IKfE`F$2`vy4=moYsOJ@z+A!llC`j<1TNE zrX~f4Fy5-9n6&BDdjIK)GOMqSI>ka@1qIZFs`+%Yd)^uB{jMwA8hDtjhfOn7suHvq z&gV{5wd)sdFn&556UB=}ZW*<+d({`AH|=6HAeR_yzS&h{U(mYlRd8K@9sOPd-P6|+ zdplSa!O4Uh9@fwusb1Z4HFam=6`|$Ux@*Nnmw$(EL_Z1}jQwqu?Zn&q+fuiCW8G%X zX6d%i$@B+<8_u}ry^X7x4aFok66c=A_*~~4k0)>+;BYb2PfT9Y{l<&$o)-CP?fT$6 zTXz#5ZXCpqlXKHHpE35@cMqvsHF=8L7v6Au=tSV%%Zr1=TligGcA4W*5 zGwY}Wx6H1c@pNF6wEK10j`8dfGhXL!N+udYB>IPNYy;!+w8l zq3oEKQGcjrm&MK#=Zr?u)I24&!Lz$x3VWIdk#?pRw>q%K7AL3baoaB}%Nr$GH*;A7 z3uH+p&V)-n_q_h}K>cavj<1Hf(Dx=QNR?$@W^q)<`sCacp3lSoaOx?JE`QY^noD`p zBI(GjG(>%e=J_b0xpe@ba3^;!3^#l zzC*$2XhBu@RYC*x;r1P>H^(|ZpE`}urqVX~so%#DL9(NAFc-XssLt&^@rm^8`8eDC za;9h2POYBsI~zkLuYH+yIoWc*?4!`ZGOa}|>Boa(BIBZ7y z!#-BHHSY`|u2o$MycvxRq;P2#BZBHDK>#2xqDZ#(sS?)B$-L#ym? zRueCI{*?C%guULk;0*6yVWwa|G+NKQ{?n-Uf#H4V9hb#VpWijYWu^qSjZ6%WH@)uo z>WDpDqvdBe<@PTyUtSx{v>g$K@}_Lbm!TnNjixyLuw-`=`nel1yWx`pj&d%AU6 zy0B^I?!PK;I(%Yow7u*CnTnq3tY{0ldg}#_@Dg2hoA0|;e4}1k5xARuX5;Uet?tT) z{xYlD^4{#aa&0)lX6^0@=%l%SYVxsJfgw}>1x|%%gdX%E-^#TQW&YD*_b(u6`y;_C z`8>(^adca}$LPIA<$tOC&_L^s=eg^_{7_Il!j9NaoFQ@qNAJDU&=p;;4$>L2pp?iNW;EWRRr-Mn`w}uUq&h!ezpWAoOyu*c^ zR9lnQbO~>JULHCjHBS*m_IrVBDwm?1&XS6Mx}3Z&4UcG__Nt{j9Ro#`%LMO`$&4U%tnRHjf@N z8XH=Xb@`gS9g;*z%_p$aTy;hjCTZDZTZA*8ltyW6c14Z6WOU&Y7+*t`+6;^uYb|KCFSB{*N*j z%a9*JX0cK8HqX)G{_{A!sql7;;Phj?l(X9dDBmqRV6S%7@eax24qdFp`{l>lnp#{5 z>YhwxbdGS+Q?Z>%PbrtTcUvldT4mCnz43^vjx|+T3NPPEaL~B1#R(+K@a~}Se2Q+_ zjZJ*%UNQQU@HGf|d9niHw$bmh(YbKr+hu&$QtbcUg zY}qABBC(Z9NumlFedj@4A=1!2Wd|k{Oh4wiqutZ)LkWzuSKM0vhmqHOa^uo2P6oH^ z@qAo+W{GH^V{@w0q0w=k>0dui#La*g9hR4BH66|Tjp|M@uJp?dlyrwU@LVhXzwm4b&arod^z%ORo9EF(sXOpjCe?Ov9Xd z-08lZImuh!Din{n9e~EG*)F_Ol{c%q$|f>SFXGe83~X)XW;;p;iH~sDr|L&I-xoY_ znY+hag4|7dAK|^++5`?D4JU*eeJGaV^Hp|u@*M12Ny&Q}A47O^G88XypJHVkUm{L@ z8In&}%sM;j8Aik%(>aTG=j+v>YIuoQMl%w^928xv$g=qt=<3*TJTqjT7+_CG4-w>- z$Id=Y*fx6a6s5~IDh>CSyP&*?{?!G4uFR%kGW5Q$Fx>mw=(FY?PHTnHA+t%>z?3bg zrKGN<9R_b=s7bHS5V;wenz@0~)5#}nwm&@mkRN(*;1!=Qugm$w34#0(w2HhH!yc5v z{14RP{r#KlALuQy)}JRX>IqC@=WWOabRSKrD8 zOwNZJW>li{zd8xN4WE;4d%DRk+HG;$PMh3jI(Dk^6H?2a_otohz_u#O($=QdqHQJO z{+iM{-t`lSR~K=qq}-`tLLD#smJmc*2TVAK7#`tpTK(f?_--?{c-~sA%jX#T@_Ua1 zoqk!R{bLbdBlaB^w%9dozBu{nBt~rHXta5+$*xZ;))p7N0+D-m5!>4E_cD#Nn2$!B ztT`IK>;G=4^*?>)Qwi~8{-qdE89WI?59*7r5VZAaqks@^v$`txY#u@ZX^FJ8)0r&M^6F?Ve2S;khpYY z&Gqfk)UU=mUPr}IONMTpV|7#9yO-)uy!T-HkBiRN++LySFEZ;NQigRX;)0o&b5~yB ztSBK8q^zm#%S33n;D&nXy!zb4Dxzhc@~Nz)YXIZI*y$iCT|TqM`WL{+A$~_v=*pZu zvw2J#^_rM@iyzBhGt99P<7=ur6Mi6d;9!ttzj3EQley;Bx0h6p44j?H8ru|<#Pkh# z`3PO>nf8|0_{Hgw=g*le4d=bIU6Yj!w}(X+?j=|s_*l_qzP=(&`(^hd&+z8ZO;aAV)^z1<+VGl#|4uMY8Sf$Y6cBbhTdGYyKiCq@n%|5=+WPQwV)3}^F#QzR8%7N zOLM1kr&8B61oMUCRg?6~eIadraZs#2{W_R&{Zsy1#(ekY^%XJEIO;ma*`nG#9^gY-1( z7-wb^&QLz|G5FA#=L6@QdkS6-d@aT#oXQ;Cq*WCR6NlS==EP?0sqr*>v((qpfb}HB zpRmFu+@5!d<1dHBo=M8xoLLg4LDjrC%({N*Riv@QXSpK!ulo&Opyl!vAx%( zc?7?UGk?3E5gtE{(slOvs`>oJ7p5|p9V#6EMd$=C1#PU4 zNxrG_G4Jze_iQKM1{d+=jZZk6@MAh|x2WNV;JidfCGa5A`*p2-S@`?B9m3bI;*B+j zZbfj-Ho0{7N%ex*Xl|*ngLQxB`K!|06_#?C1D3hv9QKskd!vn$o)82@lhUYlQ*7s* ze{A2_YGusE_kmL$#JOepqnE^wsC(ZEDY2{e6;dUB@IlPrnJwjnbe%5W=jWn_ENq-N zJyHG@dxO8Ur5kU@d!MEH-rsmzXXN1-X3f{l-)z<&I^V2_y;e|_8s2l0S{^Y=b+c@H zZ_L?*{EuF<)-<*8#TidYRZ^z@c-8a%YW!r?6Ln$jhUts9oc|tZ`PFDnd~9o{`I+%9C`I@%qBp-Wqka!sKF4|_j>$|$J;O6bzdF- z;z~9qhOLyJ9g13WOh(Ejiz=Gb;yks3#|0$&W$^FOP4@-74a;Lj&Q?^yHS zYC}G5s?4(z+wD61Fb&iRiq(rxPc%POy*zf~Pmi1wI>TZc9`s#O1e?olUQcgxcx>Dr z*vH=yLixkZ3dB@?kf@!U5=b^*Sk7%dQh14yreDR6EPGmGm`9FRjH?6^O_ z5B_iyI)3}lGa0+fAbPuqo*9_dONqBRn_Td2a}$wzBl(|0n)L*!n0RG4NJtwhnc^Oa zK6X4I@hV&6k;(kIE7QN}^LRH}|9z1Mr=EX<==5^K6P3$GUIxA;`ds}f@NjuY@rq$7 zLMxd*DC_ZCBwqU%9^1fLa6c2&CU9LGu-~+6mxn;}A2a_Kf{c{XtaMDA@`E`&t=-R4 zP6XT&Ch~gU#xH7j`CzZbU4Bm){UuC2H=p0)GetdiYosoHp8D}=RjN0n7CYa<>LuTI z@jYDqfD(GFBQG(amilM>cjw3-tE{1$YyIA(!qpJN?H|_7>Sc(>nVM*?_^Wh$*O$(7 z4#Z;HZfysLD{s8V2aOI-pNf00F^|AE>H9T)x2+4UkMrV(NgF1ohF{?~IDk1-oDpXJ zypZ|~q)u6DE{Bidht7B+r-M@6-+#`tn3X`@l{$kc^IIyg=XX7BmN!b0=|vskk^2Qt zy@v&s0{j;+`OegPSck#yos<6pmYcd;uenP!oT0h(bm%+AG^?Z^O~=h%5i3Wuifu+% z_8t!}x~Lw<3?6^blAEa+yYSe|^DNZ*G=<=uzsl^6QcP#RI2qj(?R~%UbtOxf5F*@m zJka;Zk0qVjj%$X9#&r}Yr2FJwCt}>d^9Zg^sSq#Ci_-L6vf(5-Cr|Z)EV#H2boDjn zN-BuEl`r^qbM>4I*L@bX)5aOA6?9vs4Fm~RzssE>=GNdsVA;X=C$e6MDN za*$=Dm2iz71^F3Lh`mIqHVmuZ>oGOC;OAiB_GQ~JjGa*) z@gis^J=l87`}`dXwj;}FtlsNWlt^m3Ex4vPD8Eaovb7OtNwM8O+RXgT*gi{R581XR zcT@xkA+xb^h)?uR${F9DAk{b@_JH|S$EEormlEQmmZ3%VNLgw9%MD+8Z_J)@!db~9 zqGM&VQ9b&aC+l>gzI6YWje{M~G4H%(d&sw_uKNxnWr_VGz6Vc~oYf6)Hn_Njc%%$I zD=FtJQho*%XTIDvXdN*f*JtsGA0p0kg2aAInPTRK9{nZ+UGc_uy0u>TLV5Ag+Q&A+ zy?#;Qzh*PH`)w<;Y;1I3W)*R*jl!Hh6yhS)Iuu*5vtLh9-oxHRrE%ZlLp`_sZIJhy z1DOfIx)o4gmp3p+{U5oH-?E4Q^(E{B&wq?nQfO~*-c8b6!W`i|Q6;)<*sc{8io3aj znDza{4XMLQiwmR6^ZEl!9<$2M|2x{TZn0cOj(e=Pr!PWOerOTnh^vxI39~((B zQut7#Xu6dth^m!Khf|&+Qmx-{r&gB^r*po7M^aI4wEJy#brg=a4E#iIyrP*=VAHYz zD~7Ccxs0jF0fXa5Z`m&RewT7?S)0_~9&B>mT-KrjlFWMcLjMuk$$H;!|9Ig(^4;^3 z^-{W}U^aOIc6|ChF*-suFmJe=@?$p5yj~s-QdHvl3kl#2>g7SXq*%X7?*3-1(h;kf zIHAs%VPLvJuvLl^1Rl6kb9wFx^J-Q`(mt&-Nu}=N(;ueW503UNE43_gHuNUqFta|< zVN|VST5cls>D7vGd(|{{!Az33ozNPjJeNpSN6l2I??6Zbk;eNb2~gp0JHmGF!V#U) zq*kYKx!cC7OmYqJ<1LG<;(6-1i6niUNR@EzLQhtX9ULewk*BAxt@xd{P zp@T`v5Vwx9ESEwM4Iuu)$b*8ojHaVs|6QkFIqK|DEw5;NI8JvUr*APj8DJde+t16a zF$*>8L2MMtd%tv-X|;z1oA5VQ)DVt~iZi5q z#abV!ou#H+CawGne4nKtX5GV2Pi(;WU2s#s8?-s-SD$;+w=CbnX>JJuA#1JI()2_6*K9c8sooh;mO zKB8(Qm!-a6&@ zu`X)rHAkb$qG2XYI3iOSXKf1fYEMbkHNj=6fZd16sd+?nLRWns{FQ_Zj61>?K* zZxUL^Q2b=!8Ye?DDqahuYI^;t(zS1#CDq%~hNrD$2@ft?xD_wU=lAj2DE)1YD&tji zA1)g|%Dt^tGDvLjFM6V}OszD;8dCJRD9jUT^P!YTZT5#?Q_zV10PXv0{x7Aq_T;Ol z>gu4YUu7$UmD@^%5pzl)P`$Q&Um4tE(MUsZukNwjE{uNkiI>r7Lw7eTlf3WUt8gXzt04YnPdX70rFAe$w6k8s5f z2-TgB-sIlc!*J*yueezdaU^BvQuH`I%2+$dhOjJmjm7OW@??8enq39&72dsU`TRql zo3Y46?32xX4xbc&c;!yMT*lkSP6#OyJ=Qw1>bJSOOoy|n7|t=c&Ao|ZjZfV;%?@sG9c^uKj5O=fyu>z&I;_uG$G^6+@l>f~ z5#29*{ipnC>%?HM`rk&x!Fm|a>J&@vVB|<&a%ev}u@gj_3+g%bJmJXHKkO)VsKqXU zV|ePqiEF$fYa7gw!4OV|fyj&lN!xO;jW|7?zl@0seOhGesFG0FY|rI#5xcU?*a@%B zB5=_!>Zth)D~qXL5cslb{rIwZRYXLYM!e09p3f^gJQk>5TpaOD+@r4~M|Az}E{+wn zw0!T@ub7y(6BqFrV`+%Cw-!%0vS|5VWz^sD;Qj-->(VXD3mR{zPNpzglZH5mJ6~Mz zX?AjHi71E?JzQ_BkDU0ut=%swDka$b&IU`j#ClG^oGgCxO;>RdJ}gsRMa%?yni&MT zS+4pBEg+(-5iJt5q^wf$miN2wt4sg*!NN%?_nsX_dx3y#&rOohyhZgL#SqIDpO zwLv1$QmJdoN)4vNKBZKD@=i#R1G;m-WVL2d)|~<0U*a8v*?%>olr4<&x`l`}RI2!o zzdfw;m-8p&K^;n8DBtIA`QkRuUN18h*BB@1E7q0o5XuSfs9$|8rF~L4Z0gU2Ea*b! zY1vebs6bNcVkNxC_O=%e5Mune>Vv6v3pQ3?oC^_aOx4f{sbv{uQ&{6DyXt%p6ZK#(wW8J{i8Vv8EF*xsxYwpZ=Jk zl^Atmz)^*#&OcHme4no>8y_2a8CYK89M-J8<%4c#LG zSpDH=-IIi}Zmw?lsqg{gDH`v`(I(NR0PI)Ioqs%fCNB>kKKfLhQEkTl((M?r#sImR z&cv!n^f;D%HQHFL+Ztob_lY24NWJn@YBLHJcv$HAK|&U}JsoE38WZIWH|f_@+|Uqx z0rzynn^VJ|KuNZ?_<(t*4E+`Eg${m)%NJw)>Z${|b@0+XG{O6GZb`fBwiF==j9&rl zlBV{za%oz+={h5CzJo{cWihkVFh0uUBI$7D7)#V6J6&>faIC7M3~{HR5l23mYvDaY zR}z9E-s`uF=X*iP6RA#V4RO%n&K7Xid+Zt8oAKA0Uv9+*vjHvkD z8$LeGci7OZSJ6;C0inHEWUVA$OgfgnV`@Gukg7Q^u+>qC0-r@!u6d4(_ITCk*Ob+u zP$%3a?S{FVH=&ymdx91*r4&zwXp_nhu2Gh1bqAtlEen6O4%-);2-0X4v>4z9`wD9N z9mBu%<6nNht|OE_sL>W`%cwONP@SfjJY` z@NuCl$+BI&&<`pd6p9v=HcmTb(ezb2-1DjGBJl{~>BR&RT^QU=yB1hG*n|Yh5iUl) z_d|iS%GY!p9I7&>OPr!iB1)JI)K8AhL9EhSl|m088yZ{51H@%x4zDK^@VLSsxWoAxbTcyTGK zDAf_SzJ6uJQ?lUJ4IY;n?%9HRn12L?ocR8MxkD1TAM4bRWswPOjtV!f5+ZH&$A!?( zAVZW9)>q%K6m=%p;C!g4s6OsoOU7^*)t9``Wm_*~A|C8A$?rc@)0&}Qv-rnCa_;r;pJ%d$84`8z9D10aS@VSX zrt}ENk}pcJkrzn1gwXt?Oyt$Wsow);0&AIUZC+qr+4s0iy-H%@4^GQkSdAy8yFAtM zsd@-Q6vMz4k%-@ENbSb>jrT0vnHZ34tv)mfH*ekRv4jRwc!8%3%a)9oe_{VK{Wac7$u#fw!tut~0No^?o>bZLZdHPTecpSe5GImXx-KI?f{J6wF~ z2l9T(2k!jbPvPr-q?`3>5ZpzQGsh4YEnV!Yso*jv+r}&H`;^!Xwo;s`dzS6C1o!&D zn4(e03Aw=Jlh*MG=31$6&bUTfD(R9h5?E8qc2Plc3*S#OCtK$C&qU0yCg+nPq?Q+X zgwp91!zuaiWg9`_orXu-gr$-jP&>@2>JmQ1nOeG8KLdU&iL&6PA=GO!^p9!ztuu(9 zTJdZ#=&!-W1nV$IeKLG%FwHtrZmeQ%%8t7Z9&&Xi3&uYKJ8`p=t~P#$oT+`X=W|IS zVIe6gXm8L)YP?+vhpmRHuDVes85G>1wzi(8R#D2`9mn( zS0D?uGZAR`+qm_x*HnFHoR;i`S0Qid`Srb4L!0d6^9jYLTySv|-&*`>&n{wdbYdf4 zj&vWdavYUW%Vo`MNap3Wg784-wjN=ETk=kkSC!onE#aGCQSoESlMP~7pPTY$#LK*& zL6mofxzl`gY(3A$5iiN$w6!caNhOen-THi4-+?VB!l-5c0vaiH@*B#T<(h7ntKs*< zdkND5)Sx+gWgm19Q(QKmKFwgSIKR92ZTw~;ewqAO_|3CJn?107K51~9q>lOlGfg*m z>InI9kX`iH@{a0jXZtE4)~{o7r9A66;;Hu(7wiOZP+(gM*f=1lu>#RPdvw(yIrN%1M~G4ecm2z(SRUT%FPEmGS-~E~7cx;5o%lGsW3YZ@LdcYGo+3d7DL08( zjK0YNkLf$ZQyl3Wh&H_KIiH!*bS4vHYXSWr>t4pw2Zyy+5&ujy`vpBLxtr*k!d~B$ zB@%~?kDp}I1T4R;z1>l`>q*p_DId=Y3*Q0S94-+X5%1`BnafGV2OfQ2HfXQSzB!#U zd!>k-v9Epc_cjKY`vmDWAI1+Y8jjgtL;$nY%`Z5mV$bm~o6EB>6!+GmU0UTPqXxpX z)<8;`*d4zNNenh+d;Rk;-$^RX@Fcce3JxxCPf9LDLNe>V+9mAUBqwHNc)nNVXYC~E zl)8WSe{|}*fsNg>I$qKUYslg!RPG==)P)C6^SF$?{q%bOrHCMNS5W=0^qcZ-1)bsBYDeNJZxt2OS}mAC^r6{Pbjyvz7RG&sW_~wrf-TZ0p;( zB}LU|cIVu&+UMV#e1hf)V_1$yR(gul8(vXZ1l_682_|j@{W3~Z^=qR`_aai zFyuz32JA8}#k7?J5@wYOwP?a%GfpUJN8htnnOXO@UADWTR3@1n@Oj}P_E*nBVr0Co zt?jldJA$@yCPKK&`Cp*HyPH-Yl*n@sLEUW48yhw3%9J9pVs|CKHF{|H)bCx6%3oYj zWxIS~O`Nt2ZAT8L-C)2n&s^qzm7q;>G%iD}F*0kA*qOtT_w8(reD^Hr;FtcM5P1}B z(R^n?OMTlX?ZRydVf=Q;-|t|`eoPuGlw)Tjz9j_)^Gt1UpVNcW&V69K>WMI)J zVbRWE{gjom`S^*bLvo!u*Te~vsho^UZquz}tkaPzDL;z|Q(2x*g3NPQ4R+#8CuMZ& zEK~M$3G}Qbz4R3WpC&=H?PCZ2S^2$n^M_h=o!+zW5GR8jGn81_ZST>Z6IrE#&Bs4} zAvy(SCIkomS=GI`x=C(V;r3bewKyhmCa}^}T8w;Hyf|5RmAm){ZpX^0v-tW7nVGc{ z;*cIx5TV(A7C$aZ0T(-XM5=Qs;J+$LOl*G7u-SK!huOO1*plfo;r_G>eS!L4fxbu_MQld zgGe=(M-aTlWWe_ozd%lR#?ywim8~5i(yU#!7=Ix;rG9P##~1^-cmh_fI~4KBng0S`&S`~zcTW08Hk-%}^FLZ7S4oOVIBX{mvbD}FvSyq0Alrg$ zWPKVv5#NpkNwr+3i>Jbuca8Q%G~q{dnT-JIm3I5#Q--H zA4-C$hn?j}+w#wYg1#aoGB6*xU0W87j1)hA`Vl-H4$sdpmD%U=6nUF$i?w;*$+_vG+$rYS$le{x0ta%~~E zD$;i&LX3ghjz}iO47-K=fRK^EWe)ag7R~ml*lDqd&r7U6ECie}-oTyZTU5>7WMP?B987Hlv zo!5}Ja9+H9w|!rFw$(#fg$sc}z1Pz%+Ti!N>zhlFvgi~!YjCQ*Nt|!=tJj8&$S{mZ zZj-Y8ZS6)F9OvfFad10P=-6Kn6Tf6D47Rhu^4gPSIKSZNsiqS_pc7F3tBK+!)Z!j#sX^6VZ#U-7%}pt zyPSgfIO8_mKN;0Vnmf=}{jpq$YZC*qj%APtI%Lz}Gz^66r3 zwE;*T&srJM3m^a97r4L3+OE~qz;Ps+A+dB+!Ro_b3#?q?Z2p#(0`Ujua{=KcP1ZI>R?wfIf#%CVD z-hnRoE}FicD*wZASbfpV`GkGVnX|InYCh%@9*!za)sx>Cpa^qL|7|((P55rusin)* z!@06QM7LFY4F-j7m7VB~) z+eNTA3Q|yT;9bw+Ez?U0cm00jP9=Xkymnd0m( zhYgpn=y3f?BpJy2m3v+la5x+M_ebiqrdT9T{83oBZX{6t7z zl|12I)?`%6_tR4y_4F>r#RLY$e|)op>(?bW`UyMXJD;f^0Z$B<4%*^>W0UC#^1ZPh zL#d;^pM8q!>R+)!nDk_!Qk3&*weV@)L$lCmx+-%STN0Ja7L^2#xnq~=+kNwXrftNX zV(r!J5fw;neKf4Xz*ICs+muO((?ZPm(7$=S4e}_SRRqYLUoG%c#`lD-=SBb01ka=s zU1zM$RpHarXFM&uGYol%7Kt54xSR~zPdBJp>hDw zqysH|aFn>d#P-IGHK5R;6Q z$+AK6vGp)uJqfcOGCNFCZ~}6BVD(J0b2bqTpl4jMqcl{j80yzYj`xDeL?phLZ~=ht z-awuhu(@mo*! z7wcZ|AYbvc;!sV-yI^ot009L6Wf%ei&vhfu^`hir-5f8nycG3(5K`7n;6tqB8?+?Z z*e!~v01;u&AVJlA0A_~ZKq1*^kT5r> z%lAQ#(yT^VR@q{*%nQAR36pg~&`JQHU=mBy^;a`#QNxz?q0oIMvLPap3X$}Xkn73u zt|oI7v;qKZp%E3<18|55k3yamlNFRvb7E4Mm^>;*uTvt>6-aRq^lo<(9*p=r2Nnas za{w)PFFK}xaFqdZUQdQ+>&`NX;|k~iF<_wpwV)8MtOIhCQQ5npz>rCHHh=&iIZ&&Q z-Bzv7V1NiU0cg$jLXRn6jf8*^05MX8Dmam^K0|L&g61%_IIe`5KFHBN6MqH?ly)Zw z5L1AXb)zhl(15Gem3#nDg8G+&^N8J|3Wpby=S1Y}e6ocXX|@N=TL)wVka{tZyKsLoL>$ zS}8>N0Ey>I%xNG5D3j%CRukD)GBFl_0HYhoyg`(|2u<%JDdrQ{0xMoA3hoP!1uLYZ z=tA4&vExcsMvA&d-C757fYCleyqHWZ!p090FL-Lr^~0P! zpbAP>ABV|zeRNw@wEVK+fE(ee7#qJHRkj-fcQwfc!>Ghou`I%s^Vr#JUACG@_BvvV zB6M6#0-#o1IglKHEO5p84*|p+*j*@mw>QdPi6|2jLS4yS0*DhRtJ&n%J`vfb68}TLbP8tHZEUFE+)@02zN`NEza-@%CKBjbf*VAR8cEi zgLoHI8re`kFIc=7HL@O1@FqL=k-_Jkpg<@E$`%0d5|g_sM7}#P2PI=X0e?EgNDWYc zkUn;iorfSuk;$AGJHrGzRmet8T6BwxkO#n3u$mAn zSvIHy$fKQrf&!VS3ZO;g01+_<3YEDL(YqmC16D>#R+0i38tlV*;0i#9$tUO1Q4{I_ z03o;TCR(i1%6W!X>;jzCAlXh(MHsfz8{J7G-|YgjArMfUW@y0f_2_W`g3KX~7QlGQ z#4t%SXxNWLoofZcG=+Q3W6a|5Wm-RQDB-5hn; z6<63C6%|_ymvqCgDiZ=U2qT~Y>M~(JLj#J~Y#3~J0m*VbdZHWbh%ToTj&vq%^@Zn% zhyWN1+6zaNlAXJ?=3L2pplATl^6P@kiB04*@|+Ob;so)}!?yN7jzNJd3J`@2#0x^e zUybyfh8i6L%$)!Q4VZ!p0W(O72Q{;pJYI;t>Pr&1LoJ+j;YF|(C~CX_a1x;6z&Y)N z5VHYuF$t~!N)&2t7}_Z!Wcxy{I>TDlYt7}rLG3!if+2Sk*1=F^1!STS1&(Wgh}+D9b$VDR+pkc~Z&zZU(y|i{itz@GA6xv*lu56G{KR}iVP;%G*rZF1^;d_xT zP+&wRaiRom{lxE*b%VKoBC`xdAIA4Rx0a5GkMy0Ti-LX5As3=gF9SvP1#K z0jxSZ$-pzMu>Temd5#7uXVRR|p#6rd(9dA4 zFmh`zYL@?}6eaJ}a-or91txLDSZ76DaE*Kfm*hJ578*H>Mjip+ngD2V zz&CURKpVND!U_m+G^@D*Ag2qE(*dLy^$dW+ePD`eRzvG~6^3jtDeuR&yfkZh_XEnA}PS zcCQ1v#OPTM!aDG`pg^`dL4jhmyN^6K2uht*JdG4E1ZxrN&VcKJMy?+~&2$6tV(j?( z|5}Y^kj522*#Hzlo6Z8?T6epxB&FEcPV!sX*nq9l zWsAw3RMMzBNyf4&8vw3s0OAYb*$SZH1CS6RvInA23^@uu*+;J5K*sohY8kbs032}C zY!6&vw-$UITYGO4sr4%-v!rQ7x}r!DvtJF*^gcXxsbfBQ|lQN zGM5XkUeNrZa=W3LYE}{-LW>f)o(8IGP*?od{<$8)%ph@QkUaBD*J(ZEc`gLVMPUHg zY!9Tx-9%BHFi}A65`zOs0LKs<4Y2+>F=0jw6VM@=Zjjwxpt(dNpfJe*1k~H$x3OI$ zuv*D~kC8`vK@)E^Ck7>!Kvx1fcf$ZE9Dry!<&fnXT9$)^0C#dLjXYaQ_^)QMRjWGz zTqC1Cpa27C1rh+xYYrL?z@C>tx0H}Ui_XNLZ(Jf4M`5tEPhVdvBc67aW5PyiKsAx{f{5RG~W z3Z-PW2%JX~4vpMJ)0!2K5f zQBDj9vP8?WlqB~hwm9iJQBhr`x?y6_;Y5Lc>A&589s*dm4%`v^|Ca*dDCmh@xB_k! zpbCl#3Xbrf2d^AfeOBWUENCj?{9fn^Q;Z&?L}|1GY70QSJq#G||aU-5PS z6<-y`_GRz}OGqo)VCKd{s7&A$LeM8Ts+Nk{{nHI%`w2R+fI+{y`RFO|8qu#WxQqFy z++CWj#wZyCUYGHv)B@g3{ki`9M$wOqLemioSqbSUATXbn-B*OnDi0m4&6dKDBPodR z^bG?eK?WQ4DV5FOdG|>BCsVXnPX5%Vl1v0Z3GSjM`P3pYaip* ztAC7D{1MX{b$x^RZe6vfE{nV?(+ZK#+VYe&#;mhb72!mSk?C2oVuMwh5@<9+fI6YEV>aQ3FzBXNC|!Kn*TP zU4x>f{;ds&7H}ItG=fXC)J97+XtZckN)ZtS>6`ZxOfuIqXSwg+IS=WV)~|PDl^_`v zN5L%zMj>S!T}DL;vh>d2VCKc2MbS zpR_IlZ;G`$O^yLh?UDLI-TFgHU4k)vCbjJ!HWt5z2~J^*Aj1r`d^6BupaU&4b=m6} z!Og+NP6jUJK&zuCG)Tcm4)8hJ4rx=;2!+Y%osm+VxA!8_jaIltzsB{jTT+5t)2?N# zS0y%n0Q{bv4pIZtX^9e`HVw?jGo7hzmPkboZsQ*FS$)PF;HPi|qrL$A^#OetAMhp4 z#Tr7Tj7ts5E`qNUURie-R!Zsj)Y>6Im+fq2ATz^f5|u*I@lpD~Qz7s%bEjgTxw#&g1m?8qqX(06OC}v4 z6Ur1+!nhk>7!6L~`ac^VDZL>zPZYrfh$bd;(m{hW6_x&h9~z>8fQ3&kDZBIeBomn2 zt$!&}PX_M}F(^iVU)DjlEJ!UMoUtg@FV-)&w8RC+IK<=4gGhs=!a&m}plEXYYha3R z+~l2F{m(%7eI^fhuezj)lyXci&`0n`pegC8-Gr<39C%3G0*}Ie3@j5X(EY5_*@JmL z;N3u2*d={FI6g$7wd2N6np8{_^iCv@Y5vBY830EbDFf$!YMlZy6-tG~CzsvnuUGl5_#d$he88%E^6(4b=o-qwkiLo_N-+U=8*GCD!9N~hjK(^DJ-8wOl zU9!MJxedRWUXAA;Arb|s2f0=mk2DEj6Tifc%xakNk6UhOmQ#m+cT{V9n1f4TqAy02 zM(LP-R5Jxwm0$EJZlu%cD)W{u?j}(QK+E1L9ff5lROzg+XX@7|WI)0bi@} z7l5S`FotP9A?+3WDGq{XFN=QkO73fy zjpD^l_hRq4f`igfe4t;A7y=~*#T;)ns+#U6RVC^NIdfgLPfhGDh5!kQ_Pxfwe*)^a zyVM_9)^<}b^T#flXWb1j%>wG6)>z?nN;Y^0w~_`yoHK0-VdpL&jBM7ej4OR4rkEojh}?3HDOH z4A$|;P@ruN?5|vk04;18-4m=z@h6dBw`0}NE2DgYAwAlt)J|lEfCmG?Kdp{6EBvsF zBOK=x3ci>ea>fOd_08cM2vhVDG6%I&*BZWE?jv0Ubw5pi5h^9!eFFTf|2UvoT*KyYszlOha-REL0hpk^#Zw zVlj|Nn1o(nE=M5Nq!0VLZpY5N;-Hohv^ z)fNnkhMA`oi7O$#2GxE3PUR%Kb!A}i&W z+q1!C9FI!_Vlcb&0EABjJWnhuIx!yHGD#;9;6Me&(efUuq>s6^wIbN_+)%1!uYXcu{OH{{q~_1fLGl zZN?MS@#iF|0jc=|%&Y(pMxX8^x^1~)pe52RD{9Mv*i=?g!ONP#I3fI<0%=YcrtB7Z zdd@KAoHmOPWS>Yl!71HjmC2}7Nm>P>|D94YTh#*CV%z#swQ@y76PW9n z?C#LWUP8-9|5r{2rfcvGkk#oI&d}_Q5uMkd?q=SU9L55Z>VGXW`{VU4>r5@$Ph1x& zup+UPhMeZhXRGEl#I8VlLx~J93+lWLmg;r>#MDC^79v0f9!DFbJw(SpC{FUNhP0{BS&T9-HyQWp?s*-wH(xx zg%oXLpu-&3a=a~(^@IN?ihlvpF%eti&9Y5N+i{YxyU7f%5=I9+4OCsDPc_`VhN{AW zQXNAM+hof89EsIR60ErOYiMXqhxI>b6D*{E9(HK%)@sff1^e4fqCZa&TV)zz0cbER!Vv1GM8sBM+!CH2MJC*T!>C}8Bp-Jzw&-Uy2a4x5a}NptF#}B45@If>wPwU`&_zVkcq#@A-0bgx z8_YjT&&k#Mm0`)>m}vAEENmmO$x(ontju9NIInK@RYsD|JJ@z2;u;8lLUchO9?>xl zFQz&YcpP*a+)Q;kUSBl0u+XEk7h_v)r$&G?B-+iy1Ps1ggBn;y7_%;8uG3D@u{Rcy z?dHuMr2ci1l!}>)Izhl6*d4!k1@Z#>PSZ~XR$a^xEo>$ijDJ5x>fj7c5UC#8izyt~ zWtp_w;5{`GP@<*d?7@5KAp>}67h6H4^S0JB={yI~bC@ff#sBLnMwWneU zc4rK3I}IbBgc7qjYHo_EpmPkl&CMgz;jM$yl^yVVL?sz?PGtna#P51fVChCR1QbHA z^aL?T^Q0$78o3NIP<+Rb#oA>#MLbFaeDM}-e2p-y5+{zdOlNHDi}#zlk=&hl(!O4r zSGoz94Gl8MZllZB&=6z_qY5PbZVcPR(^bo)@gtilpq5m+5I=kkfz=(pu^ECLMLp=Z7&OX7zpWO~ zm6)e)RU?~ZnEW0ZNCEAVmFfE}Xl3kuFu0BV73j_L)&Ba>z2(J?TLFPe9Dj!!lBug* z4j!M?meA0l`q_QzHcqmD>iS->hC!H_>^1{^>NJE;;K@`V^qel~2iF72r`Q-!Q_c3| zje&oer5z@g7u-n1Q=zh^+tk?+#carG74US`WPP;sPxtqj?NdvioXkI<2zNvuk)fvv z%yLf<2wl~mt_2$yh!%H&%|6gmL(*pXJJ?X5(>o3`xecWQgh6zO5fUX0+dtzS)lf=! zPhg}ah>=i-dg}`VgB?VV=95RkCObk$SRD7lvCv1BA=y&QHb)ahP|5*3;X61(du4k-sp}B+cYOZ@(Cp z-DGWP2Dqzg*OnN6{5mEZ(CxNmV;u;Z?v=h|Xjd12f4GgogGryyZ3pU(LS{5sqrHpj zti6|PNo0d)CbjT^kIc}T8NZ?^{I5WRXOjMOD^Qsw|=Ou1}^U_rhb zJ6m+%yKx4G_;Q;ABpl+A))D6XC_S?gmghDYco->}YeaUQ=a&QN)OsMkfn&=U@JHxR zQ$$x~BNxF}!}>2vsKxPk>l_|!V$=PZjWc@9sp%7q@Wvcrza+lmpaLzw2bvKtm+=Y)N#C_9_PpN!kTB+{aQ8{Ue|W zGBA;?I%TI(s9FOJ1|;8+@xYgeHge^FN^U!ciEbZ}wtB`2$z8{NbfDPayx^of>5~{Y zsRD*UwUPdTh8nD4L;;qd&uh0b7|!S?2;6B1Q`4r0Q5|UfWw=y~ex`&{%b#Uz_7%8l zloxW2dmYrRIxKrdy8k_;7Q)+U!1+2LlW z8F?qjhRoaWmS)nmmjxPzC7&5Y9+aw%0}PT;Z{Kig2>ssl$TV9V$}O!`hMmS`PMw5- zqewtK_0)dBY+oB}LB$WW^;&~m`k4oGu20tBtKe^RiHGI`bEXdi)Kw4}&(%Ja)h(y4 zgm};hCsMVl&{LVdi?IZj=G4xTcmUWSLqu)ixM~JCz9;ZO`g$@d|ELBjl= z{WVF-=IuYrjl9$l2sbNaxU!Kwu-7U|4R&P3`YTk9uzO3<$0LDk1~ZVM<|IU z&sPK)LjyH3Uco!$r>8AH!$6{E^t^H^$4$YpwSDosF;zZ5<$F6lQIz-fQ#)25dyJVt zKR`K9nW9`zErX4zaBPWA8t;PLc!C@#o{sU=z8u9WD$D3^3IWprt8hWM7m)gdn}BFJ zzTs0r_nC+}Be|b4;vp9g+ zm8+wJ9968X6W^uZX$?koDSv=}XuHg-xfHUJNv?cqnlLA0Qs6=soy_H6M@ReOT8Mmb z7mM?mO}tjFL1@XK+)Aw|y82QL1dOk|63FP7Way9$Y6F4pw*X~L?FetpTt*sC@Hr!Oo_*y2^3R*eoB|u_z z5XxmxFXQJ6Cq-}wYGA@9KSlb} z>&GiM;{z>~g=B)VYu-8HsRP3h6tNA#JBvkNZHXdNO8Q8}zcYbvR4 z=`jvLj)ZY0V=WpAHij5Cntj8*2OE`q+~4T>9lZ~ik*le{3qew8NEFZOcBI|8rHtZW zbEw?ups6#57s%uUQXeZbxP0kHZ*-)QG%2lZH!r~)Phr38iHgoyDmKnL4p-9u0g%lVxTyJBgh=>cG9Z4>J z;+;`0Q}!%f$0}9&5H)kazd4Ibm8<5Sw+{}XIci8gY+&5vt|L-HOtPz9;pO2#BlM9m zUgE12gPk@CBf1lw>Pg2EZ$?k-4}ws)D}Ss&Pu|%@>c6yai9<-$I_!)`T?834R-eV> zOrgFYbDTmH6gCIavT3fTR2ND9Jfz8s|!2 z2Js2~;$@J&kXqTw&=yXa6W&>R3)Zd9gAB^A$&2HPP~-|a2~=wJeyB>2DKSI;Ix4qo zj{5f?czRo{$`0(eqbXN~V2QBFu{g?FvXm%gL)GA~*7)iEm_M+}p z01Qb|cmnoclkTRMr8pzxBN5jOS0yo}c||lLQ$V)m;X^x&ypchwo zu!N~n7895_%)Th8$58z+x4_)85r3;gF4Q(jFAcJ!q*FOGIEwCXTyoph$Rm0KU?U6e zMt&@^EL#vLSkf^}g)NlQ>X?j(n7x{|y7lkW4}gJG22c=<&nc6%Qgq*5D3|xm(p=C~ zGo-U?JLQ?oQy?21Ko4?ybSeo(aUer0!|A}A`Ky?O$>GGL9Z`cE?WhZT3NG0+YFXsQ%416?NPWds>Nrm^J=QU<*jl`Xe4qyeTskTDQ%xJ0MXrelk%OAoMbD^qO} z5f3A9HhJvJUOt@FHimH74>1N-W1I$HYm7U3Kmqi4e)}i)CSPd9Z0U`nsX9(iL=1L~ znNug#sH6Hi?{Sk9&0rSec;zvD3O~82ThzRq-M0x-Yid*q-XZkFL^0JkB$G+S@+X7yjzid6tIE(MW2ODMYDK#Vm@i zTf^RNR1Pzwjt-my>)7T9ERY!nB>II%QzZt!Xprt!vT{ER_*_U`OXN*Q3jWdm%BEF83XJwXPiI+WC; z_=GT~NL1&bdT`50^>kj>rWxtj&cDS3Y+Jdmw-qj4o{L4ObasnixkM+oco!v#fL}ZG z1LZV6ObL@2s6XE=)n6=}pF96$u;u03xi|Ze57hR;D$`41+9Dtyl+YQ4aId7Ck@SkhD+&)E!x68lZ)6n!pXw(Sr=42pSAR1C2uW_#_+YR=yh6a)E&|SG5BA0_qKZ z_b8jx_jX+>d!FbtCi*A1>^K*{GpYaUaFu)7IcR9D{N>7yMK7b!XDN0X^3|ke74QF* z)vO4JW;8R!X&;-^$G%GLoQRg=iPa^@16WC1pT>{qrwG2-ng5H6O5xWkL!t35JUTKai?DxXS=*QFm7 zbCboO3Kq~L;3-1@k`_mm8wFd&RBDhDvmCbKPmSRH%IUy$Dv`c^`f zRPhla1N!wGZM>Zqu*)E8-UYxa!4;xZ929ZnVG5^g z=(l9M#pMT<^$;_CW<3PxlSj}%_<-N2`&PX?>px%+jA&-z>w9F$W8VTZs8dh2!ap}m z01hSfdy-~h%1lG3&Z)iaGXBYVFqKUXywfE;+Wwv09#HKeH-(WS@Pji>Eh>}0A-ZES zXr}VxM_9HB6Anh-^Vw5Jw}> z9WP370`wvy6DsaJw0ltWU~Vtm&yQ}u13sWUY9|`|0G>R+ydv9`iRa+#oc|pP4UAJu zcQ0S3)S!@Blpx2+1F+{E7c(C+8lZXj(59ZPe>yeH>g zPbpN6xFhESLkCmPiXGu}=Zu7%x7u_lxlAR*=jMYZ*DX5N!K36GYITTk0jSauRBiZBG~gv z80_{*ne)S>O4%pp9O=5MNun6!CaijZxu1WU_V|S3CPvjG#UAA`S=-!$ZIu#4AM_Q>~u9dBmFnW`6Nly0nxz>GSR0I-)`bI!Fd0u{Hu?tBLQ7iEq7MCq-_$G-tHz|+ z*CEZM(AfQSz?C#)F-2S@B1ARCN2%yg(2#)98{q7_qvR0KVOSVlgli+4=6~{<^v--# zkOR&fFM5pN9i^}qwo>;L#4%lTiCLJRVEc`pHCv^ZCWGDc-AXQOWUD3Vk;vL8z3BQ{ z9q*I-8v|#2zC}Cz@0K?6N`CP^jYoHf`Nt*Gi~Q#fC1E|T4<3-W&Cez(BT(6KXt()A zdYzPborBt$eG?4px1kN=U%_8dY$n=@?Q5;a4ttog`HTKMwq;^*&CQjO4=*@4Wg735 zYO&aCbG!~_R_YNYldt31vCtn}@w)NzFexuJr!#_)Df1w0cz(%RSqP7_bp1J@zP(Hr z#|YyXWN|`N|5~Srbyhw*ElZDt@Lgjx_FrHD{?jPB6%PfP0$Mw!`2VFq2RLK+dn_}z zbg$;zJEB=c{5UGvjB)Dr<4m+H_H(UvYuV(>SK4{; zg#GK&S1+(b%O%eM1! zIKXN}BCRFus(C%AG0b7Njd|HGYAt(mW5cNbC+NGdkk|OKnD2gj{lZH)d%*H(gEDb>Sw~9ve+8 zx#Piv{dK^dcnxg`_^ybk0CvtC*8Z2{h9>(gP*&Xchys&WKJY;$7E{-WR4$e7_&p+XYP$_ytM z`>of2l+Y~3FAjZq&!*m+IV;+BRqoO3w|S>bKAE&w{$vG_%Gb#x^)v9*K1{+ORi-+} zGWJ1KJ5+TOn1j1nf}FRjW&!z-MPUnbKyT4YUHUWXS{_JNDtWK53s0rIg0@Xy0@li~ zi9KcO)Qf#Wj-g2$5=)MC&dlaT-6E2i>(v03?cga>Jr0~iN0SWGx8b%YYCClDw8Q)H zO(?5)%Jg@6R#Dsg|1D2mR+f&jm#ui}2Oib-S?ptuEqr$@F(lgdj7^2%2Cc5v`^kpxw$k2E6=z2d#QPInE_f`#Dt+>9@8rVQcJ&dlDmN>F-nI_ z;V$BRYCmwqsm#?NOXkXwMW;VPU2%dLn?{q*MBl)(z#*}`hH4XqHz)uB6$LVwMRR1y z98qIKu z6ku4LB#3?K{PT%7&NoUw+luSf#qSg8W~+SM_^fS65K5gx$y&t~P099Kv1GTwwOZ;` z_?y80@w|WU<>BSt*PbL^>~2$H#@{({LR~=|QjS|0cuuLbi?|UpgdBsXkIHn80Qovt zA?attA)g)nXsG7`@+$gAImd%=ONQfufs3_rGZwzCS)s0-@_@CPfI$>d-+a6mnu4s!(3bn4Q+{gbh+TC65KxTYW)sa!hQ=_l}z zj9CG04J{^wlK0iz?^E18#`Nr34N5BPmR9q z>n;@wfr|pK=kpzb!PuNJE;xISNew*S(fl+mOP|cwsDkjYd`*{RIOWpDSIzt{r5k;o z-$zu90lJ&I5!M$Br!ukjeGhii=H1|bm+|p!@!Mnj=cb5gaQ6Jg_MTguD7=P|<4ux> z&&+#k)|ZRp=Kuq_6jBJU44QOxL=fq7AqmO(I+O7#Iolu5h3;6WzGRuCuwMj0gC%g% z6hc99w#XP-+4FcQCoP-oK94IopPlVqe+Gxy(FT3^K4!fi>H&1n(Umo879Kmd_2V_I z*B@J?7K5f39bXV0FQfRh0@Z)q%csSEeEu#il-}V*22D@l=;;Hu4eMd-(6tYtsBI0m ztlbQ5^@AV8l0d%P}Xo zu?KoA#{!TJ7pS#Jj?2Qr>ep}h7G{>0R_Q|Kf9T&9P3D2=VGN z!&}I|4XnT!6Y>nTkrGI``E6{~-l7mvaL%PCKcLLx&#$<11i4vb()l|c9&%V|bZu9R zM-CUBrmlTqi6jxXman5Y9o;9ClP9t}#xHgz&p2Y1c9)kSQ_a!XX492^(TNHw@>&3o zvX^x7qIGeoHriA>2LuM@gIDBunA$AEM}>0`Vxr1Jt7lGQR7cV7W#Sfzc8woxagI5V zbD0gtGvxeC-{cTH38=HxNt5Qu4Z~uUY@UTCJ45E-|5z6FQxlm5eWlSfcM({%++xU9 zzOQI|Q&>>>BXGIdv8<>G2-)`=ZT^*0NyHl+H>s~`hQWZ3N^@gnHn*ISpgL&Xjn^Y#;hS!DY&gpfgYrHY1eSL;S(vB!fI*RKpd_zgU-QDp&^$Fnu>iN8ofM|1_gz+ds?ZOK3T=lhwfKtmHZv(III&G zoExgYpp!mQnB0H$t0i~j!Ue|F>)zFl2SpWhq2_xtjO}V=2Q#bmK+2@45dmQi!#5sR z>z2&S=A=-I4}8E*lcLq`rlVhMlH>i_>?e5QengGzmT$vyFB4xZs6z+(S^E2qad{gQ z^83p?oxh~;gY?GH17&|7Gp_yLifLs<_w24stUG(8+0fwfqZi=u4VHZOhCw8{BAs?9 zO(`+#o1YtkZUPIIUF)3oCzSAUdKbNIKcS6iH}jjDepJ^}Ct*mJxQ07ZuK(ajY}&+N zC}{$}C~GDER%PSnK@NubVAnJkj591%t%xciHP{!qUjnS*6Bcwgd$FSi_ZE6FIR2w| z@HT}Yre#g9ZFg&3?@R}M!3^GI2K=&1U8y$c4 zC*^+jy7(+jbvV>_v_iA+0Ii~y&o+&j6qm;D$ffYJZ>pgI1tzoa_1G@2Ft&e#_PZzjj{zEc-3t@Db z^^0s&h-YJ4ghEdv3}G#6=5>!E%EH7iNAQ88T34#@$bUe1R(k7{iUF@p+f8UN9`;vC zN>hP((1qt{7JkQE{fGUd?SqShn!62r^)R5I9t)bm^={t!FM}G;;noU%{TBEToH@yD z@nkX^F+Vhx(d-Z4iDbx33oypIU!u-gTR_CcRdw zGN;IxqJqM378k#oN~yoxCY(A9C17$fh*@l!HsySGGN4!odPwhP(6GJ zFullkX1{~o-b(sPV*;5$(_So&4oitx{A}i3(hoT!HeydQ=apjQU-gpZIYMOu1y~%WSOZ*S2HCb1LU;RwSsw{ekR0l#P8v&`TD-m{gs75L{rR1|JUES|+iS^ZUfVkk%&*iXAXhJ5mI=bp(|6olIkm#RaGv^fG69Bn(!2`@F$L@-s1V8u188s4&rH*=Q+!JnZAKC!vb95wqH7@ z5_|(QpW#M+Jy_DFisKAv_CnT(juD%C5b`}a3q>~9ZzRq zfotY_06|HGMw8Qb3SK$$^sB5*m{q6`RsWq9Z?iRJ?AL9&P`u;Jj_6xZrQ&pa-Jrz7 zk}T2p9Pt|4WW3YW-+*0zq+jyai)SvAyU-c^>^uD^m9#1-yBb)px#0`IE}oe(mN}#_5|#5!v<1vhF0PNc={7@i@}Y_`D(= zYpL>X_ER~|Rj?^+4bnb)_M9n+9WTQd2STXIe+hI|GE!Sw=+TqnFHG2F5T{FYi@>jS zIu3q81pQhrlfZEQ>=9>j4wOkbgI&$c%2{4y0~r9CFeyi^)vZE0qsU=)1#FplnCj5? zd`lK$tat7ne!7JA^EOt_dGhF`3TaW}1wpct=z6fz@ND z>aOv&Yw!6DI74|?F9E{s&3Pw_bUSp&36aaAs({!K&vsw{+e_F5xhj2SaY%#lkq1bo zcGtdaGyBH7u!_jtAf6M%mj;Y!%pW$L#y?HtIG;Y=)Qg^cSeiS!@4Q_!7*9snHho+kGgEDX?1xlg%fQ)@z?xxLuoDkf{RdRt3IA3SFQ#SC zw3HVn@#xHG^)>39Yodejvg9WJj@#k1kzua}i&E&C9Db?MLA3ny3h0u1^xGtIpxqCG zZ3G>nHmAOF2xXc`XNp-Wv#y27??_2Bnx;!yVLx83RE2kbhVl4oGTsxNYJ;~Wh&SukIsDV%&};p02KU};|!%&B%*sw_0Z|43JLA4+VcoWEA^L8JQ3 z{$OgmdEJONrAlkR16XJf<#$|lXhW}K8)h~DyOk{tIgteUdlKqk8xp3%E2&;^T(I zF{Iy1Ub?iTt$z+HRDI0cU$5NJA-%|w3Re1!3HVX*oNzX$`4!$}CYu;Nfn3krEJ)&B z;iSzU`rEG6;VgM%zI?{tMP9pGFCDa`Fgcl;P680)sT^rs8ywUn}DF-WxQzugzygK4UF=q$GzWR z^So+Nm8B+WH#lgY(M{QprKEqyU)-oD>6VJx9|RKz#PcJc6K=AubmjVHS+ss=6ZL{` zSs~ti7+%niWg&(q5NckHD&O1Y7?5*!qFfX)RTK3)-QtzJwjr)GqVgY;Pn0=PJ^GGG z6zRp$P!H=1ki;a8m^O2H+d^ogacp%@q&mlI70*E|%O7m^a(}n>IXUN#pKn@n7M2+p zzjxe{C5mrH3q{Sk**ij&kvDfza`*RVxVlU`WA|w8v^DXhHfmeS0KF{c*MomoSz`9? ze;{J6eGCQs9WQ4al!=TzlJ01C=X~xH^l{5MV2 zOfl167wJLV^A*W4AwS=IQ`BzaiNIlN zXpne;Ylk#puKaV+14PMvjTmfLS4ms0dT<)_r@;$)oXweybm0jN@>)lZLfLT@EH#l0 z*k+P{0)p?DRJ3)2Yrs4&9&8h&0`%dgR%iwCkN&1y;k&mo%d2482(Lxtd%nJ4$G(@H zKUEF*aW6Xp_ZR~dFp>yx8*(HCxu~bn-;-QJv1(G>o+=r);Dqipw+E(EN%%`BA3-NsTSc3|( zQYYz%bs%sdeD5x-Cf)wFI88A(-^ujMqYxHsGsXmvQ{Zhs>?Nr+|-CJbV;}NkRbafb33iG1` z!bPWsUFuL5cO3pP%}RNnQS{QIo6Lk7ZUBC=E!TfMAfE`6v|ine~%haap`?})LYCh6e(T>RK%sb9kA@X>Jjv$@x1x`cn?qU^F z&f(H!8`*t#F~dTjQHYA`?2^*mPL!pK@+uDrQl-HMfz&B|gJ^wt(ckA|CK+P=LLp-^ z%dP+PbbSQAN)hzD%_NWy@w^6p?C6Kt_x4_>y$_pQiSFpDrN*#{W_35YxjQ1DqrOFxKlL z1|5E?_=iz)^|XjVjj_jf?L=^Jp7fY*dX{O?sGQ`d#eCrRQhrGJ=eLL=Zq&o0&YQl? z$-b?QeO;6z!Z-Yab(NsXFh3*tw8B{pBvrlp|C+r~<(nw`K)plQM!1ABX#zZD4nmT? z=1k}kzRb&4r_!fzNUEzMj7YxBE?H~{o3811nUL$;hPX*s+RydMM~@W?fa~()HgYze zsMV%!!ZZ1%VKLlLS|&((w06~f*RZ|uzx74hn@&9bS^FC~T>*V%rhp|}I~{sjxEMHl z67V^x*#}?V!DHrdOqA2!-{Go4t!tTVpUZ=}ii`fYC&&EA*_gV%OWz-c8tj@Rkhq_% zjl1bzdT-61$!>)YqT}Ar9qD|!~-rq|h4IYeR7GY=Mh;ed-6#c!yjnyHuBpkbhu#%s9IF2Ws5(bfx&Fp3GeC z=Iz>6QUV(`8=ifVNYm4GAr!a$%gOyItv{T`*Ax1@N9W;#8V@iz?2#o^=Sn0f(5=1k ziJONx+IQSJ?%1Y;r3pJ9vqFA5-i<%m_#4;Htr<=Y)*<$W9d|4e_ZaUoDUEZm6u3Zg z!j|=kK7McA@Rl6ZqnWtZmgweHhulwg?q6ObaK%sUvlBXGeO)tpK;)!htm!;Eyw)WC zF8-TG&sU@8BQ_oV_x&`R$=;kE_|1$NLdn***C;Poj56+! z@mmEO>Z_JuRGP0>2r7;9kJ|I2VYKcy5AS;MvT3eG=7=cbXKesu5<^+~!D_|w=gebh`z+(3$T+UiV(Ri0O8Be;t4hHmRtZWQnsBVK|EsjOK>F4~~I zEEU1fhAHyrzsS?D;Gp?My~KTYH2sp6zoPSXA;qR#RnFD6e)jW9r}^0NSKR;fXyUQm zp+85p%?Is|KyRWgq2bXP%O_U3J* zV6F|0roim`Y;#aIp7=5U{eMcF? zYF-J5EIfzjF__Eu^FzbPYnQB+k-nk=*R7($XP+MG3>(~OegX9}kSXwOgp^9g75dx~ z;EI_1%+rR}{hXx1O1*=O8+5u*uM7^LXa7ZYQj@++*rQhWNpd?SjDS8G0w&Ge)!5@& zp}8H%YDSaQ_--^3nDCOcDcKzxlyyvro==#0fkNRDHr*9oxP0xr4FkxdM<+jSb(3!| z63(A5J+ToEJ}AZlQ$y&TPbff_9RYg-(*a8&HsKO!Z!1QC{U%qOwrc7(+dpmJSJF?L zSMtp#Y`b25Jhai}FHDCAeXYA3N8R~=;u=fm4-sh#quv5;RpoC;_8Z%b6yqrMh<4tx zU1wXixD?!+5ZqLEw^yZMS49_uLPZv@6B_{@e~>dylo9A`4c zq-5NcS`J_~Ryw)UZ~=kM$wV5_p!4!;UJw8|u+-?LG6t8?^I48Jai>vB7FG~n*T#9s z8N^<-?%d7vMKMpO$37Okq4x_`0>cTs-{|zC)V=_10p`yu=R!XDW|iy{;CT6Q)79uD zZLZpLZy#D6rY%C~_9|&vD*yXU7t{Uc6~tXnU~;ecQ0u9apkMuM%IoHlRIE(0@0T?w=b9P z_B4%cZCo_8DCU;8BQZhrB6q8?yYA6nOVhSeHO5pR^pcDQd$GQIF8A#ccTnAWeC^J5 zEdC03!$W~&`XWgA#tCw1$#w-M+#ih!p3H08Gr%!A())h@?klD-lgjQAI*OYjOAN>j za=qvfMc}V9pqGI`o4+ayOo?+ki1qUn=G94;;l-(`2S;Yl#~LM|4fl&!OyGX#mNuhB zkXe_LHD0?T6o1$E@nHOdW)3xrAw(|B5lKC6Ezz$Ynd)Xp#~t2dW1KA?5$UYz|57slPJh}S@6Hw69Ap?QRRT(l-RPe(2k5Sc7e70A67KYSka*=5Br_&= zx(@n{_EF#wy&3%70lrj-n${-K7A+kO7zF1={+Xg!Mb|h=`jr>|uc9+?YvSzM_)I3r z#Oxx3uq6RpA_Rzt$j&4Yq%JimRZ!Fki$+T=QUt_>NkS48lz_O@+B&$jsjsyGm*Uz9 z5e;Bpqs2B_wLznAw3JecxZ7{Oe_*a_CYgE8xzBz74p(>TrS=S0|N6Kv{}n65e~=fp zx2P>Lr&FNkK=w3Qg4+>lwQGVCX@msi;+Bk@I3Kn+yTe=@Mrcxga0im{~va6gqca@E>dGNat% zUlj#)D!W}v>DNy)RpZj_V6V458G~nvI@N%!@t6bzIx~9_0NF21^^iJ*I zeIkV}D82m0UmU9G`739_buafQCY5P}PoVD#5)*BzoqHBj<%Jsd;rhk7Rq#0lJ&NLr zFLevi>ZK8ScHkrygUvv7)sr2wToq9;E-a`%w+qVy@g*f?q>X!%&YNm2bkQ%+}9_=2=AE zrs-qsILey|#SL?a7-%8L{DTO)Wt)4{qpZOfW)BEE4-M)k9(ox;FwUGV50Ibd_JO?b zZrpe6p^TN0xvV83+Qs9u(!uxL8A|tgI)%3fgo_Nr+<|Drm-{P<&STztm1QC9P$TB) zFcKH>%lhkvpctCoAYh3#ZzHQ`HrskZrx4sH)#h)*ON@ODxkuO4;L32RGu`q;_c*fo ztAU|($H%(+UArjTKFnz-7ayp7u6l<-pohA?$IrO}lT93VngX0#GnkorjxuMM2_$iimVLM9`@qkedCTbNvb2aLRU>IQ6p)F2kvx&gyCVKb(Vayq zww3NLjN1g48Y<`>Rr?)?2(+B#w!-w;woLU_tuQeq7O)@T+B*mqI!3x*0;S~NdJk0^ z-?Nr#zyujs3b4*(E;V@5>L!~tq5b2>#{CQ2zta43%4%#;T;U{)w)B49mqn{|Sf4t8 zN$WAYgUd()1dY)iX5PIOA;R*mE?v|`SVup zX^G2t1=^8l>9AxhD%`LR`^(LDU^SeCI5LyxAHl>D)P?%RB1ci7OUvbTVP|Hod#ZjS zl1M)gd30DUlNzKJ*)c@1nn#C{(dTM(=%?-~P*0np7!t0VmA{dx?+reLgZi44mf3%? z%!P1Yx$uqYtE6G>O7y>#nOFQ0s!zr0Nc6PlTShKn_ zMnv>p0{9oZ-|4CbF6I2}iBK;MOpqVJYtQtxMjQV^YNAuWpDhNdS79?I_IzlS=%C;%&~|Xh1yqTy4pTKzUReiVq?zkZnr86CH^s9N4 zuXgM-+c-P(*D7jF`+1=TUm0I=61K&U&TX^&>bgu!6#K56X;oJQeo9J$a3azXpL@JiRN&4nfhGpCoj3j;6wnX_6}cGMj?{)!)U zVJuyFa4+`zLz5rVb6Kiz@j#crZrf-{pgMvki-zewD%qh=A_q^gcwl@RC3lP~70B{9 z*rhq4@XZLpVJ~NAR(yz1AWhyTq=8s6jurQchcgFMEq^zG(wG+Zh%<{E+fVC%NcY=3 z7=HiQn|HQz?tcsofDkBk!9wi=0OOimN>BpueGzwpzoqDdWyax&Wiug4#L%Fxb zV;i9rCRl#pPV&_qxH`S_qytU$KgiyUaI@B1_P%(#S`@Tz|5+i$B?I=~ik+|oJ$*Oh z(dm`c%||?%7Zj-=wnB}ZKmRsh9<6Z)Sf#Gn)VO_aGF<8?F9|T*W6%&{G1QgqC&HE{ z?=K6xLosAIG#5evT!@~EyrPZ*?spNJDNuBpHHG3EPJ;}`bKJ4 zD3d4@Yd`~@5EF=0Rq*9*hu=iCL-bM9VBq$Gw*DWU{INf@qXI7Wew;yFfXJV3gkNAw zKcFlcb`h2R`^O!7#`z9A^a+BL6L-Vx$gkh)@7U^+bn5|u8gNh-yh{w?e=woL?_c0h z^seq7Wd8HpbbXngv|W_;bvXm1pT-iJK@?2fz!1$=tjUpFGxya2-Uq=pgC8Kv$Mnzi^q4PbEp*1#F8&ZIUVo(M zbKCf^|G5KFjzzHnHU&v0s`+$3T9KUAN8tA*pUlTK=FXXSj>xC{)~m%4pz7VDM1@%{r-H{#2YTQJlpUI1@D|*-Zvsz_3(xI z2=H|t4{a}&*(q*hx=$5-yn$@AF&N>6nA)kTU`EMx>1~h$y?EO6amn(czT~5t{2hb0H z@23rb*K~I9$cqNSP71L(A=)^?t*Dj!=Jq9>r0(NzxUH|@c#PGcSC};@}?E~GVck1hT5<9p+aRqC~Itk2AMKkp5ftu6J zB`hQmxdR+6wrrGqGQvnyG0;Iizlu(ir6HzPx_PQNyhI{TrH4oZ9ADB_yP!InK$)X+ zi%TTvNCtF8)D5DwO=mc?mhaJWm~<(V0bndAk;9mAr$T3m!qI$gN zm&p@989ARh&hLQ_jB(*f>sSO@Y{1MJXFKQomogU@3i4Q%7NAJr02lYD{3(Br8t~2A zh$)T09oekzUbV7t*X&{^%V)gdv_5c*nru|MeIp!hL&cVknZ*1U>>mkOUSzxOylJ#Z#RV$&}mo zs%*hq`uaTi(A8Up=TQmV&D11b`3kJ&Cy|Qy!v`S6H&zEj9Y%A#7nKCi#HSp;>FcL^}hhRgKVOo+uxetK}ac)NuM{YkT}jOQufIscxl^TG(7DL*j5!N9rxugp+t;t z)j|8>e-5kn2>d0fsbPvC5x$HeSE8c9GEf5RN!^Z^I~qwsSLRgU31JOwNQyJnynbY0 zwlX$!fx9eVzdHKT)n^c~v7H#CbG{-*aoHBeFpcP+qzr2f^=`;I&Ng0}ee;nIEY{sb zWe6{UznIm{G6}LgB7Yc(=WBGI9*t!j#!I!porJAR;m;nOJvjNv1$Jz<!+udYfrp$@T)EIf*ap(o)?&^Zh3P#XJQ~J3*V2Lv>aB{^$Bpzr(zHlA7*G z-iwaDScRL1{-dacE@<rZMz~xpRM_*oMVcxlconJ`_Rp4v?%K_cEKCVGZ*qX+Ve$&ER%D zM%?A)`0GWFRd|ZIGox3kMFx&UWuhl7R;kj&#MXY}Ttfdx#jF%aHxi%s_uOx9i{3IE zPh3svaEjR6mp~U}Ks|%Bspyt375Ma7hUxLsJiAuB3e9M4J@l zrNhytIddSc5wVlqO&-|>1iltwf73q#kJah74GF`@hA??fvNHcUptHVjEQM-}niwRfP1~RH=rt+{Mt3kCe z)xdj4f4+$I5BB5R#%=QLL(W+wFo0Po|x8>vR zA-3=|WZl#azBV|kmA&V+qmWx}bh1+UO-MVjo=EnKbrVm!_>GXvG?>(U4$lvg?ri!QQ2-9(_jjHP6>Fj!1nN?K zj4Iwb_$_o^|2U)~wFwO3MNSod#hBoarjC|YvSXKGdMt|m9opAs#!n$zD02Cmag{+;Yu3V77CQcG-T>C* z8omC!DHFFPGjaDaxQc(G8}?Rx>;rI^%0cqiwtecZ#mz-4ksFJYj{+!u*ABW&A2BM$QMAb8 zrfbfHHzTnhT=3_`;VldV8(eO7)-2U`c!ptb@~6%6=i;KSTVlzBS&Yr!lD9i241No* z%3khz8N>>qJde+GW)AFT9cnwW_y{^Cl?>UOb-w&S$hMI!Nrm3)M|noJEC?ol|IH1p z0Te<@aaMDJv36p`qp4?D_z+1uD54RF^sPY3$cN4f3N&x0A^()G2o1@Rg_;K zdwxhTzQPDDH$=)Fjf0<*p zgtfA#N;je5cn5!3he`jCiq`6BL7Wfu*VPhZDLX-3H^pLmt#2zyn1)81^fsG}JwMP{ ztE4tm4la$v$s5{LS>p(W`DpP0X*0c~>UK)(9)4ABjZ9Fj&4q1qmh!lKp6qJzR z9=po6@qQ2*kISf(*)Jo1wUt=4`I)04a1RxB`T|=d_EuMw@SzzjP|FySI^x_YmTDJw2!=i)^Z}?tZagi3jCV;Nk#AccPH^#O& zUG26@;AA^}qS7}{J?4LvrdajYoFi7crKHhxba5X13L=l#R0EmG@rvS;UJ6;qgj>2T znTC~;=V1nj$iJzm5?T2{Wo+bB-X`s@E*jk`KIMb2xq!Y7VpN^CgRWv!W@H0)kM;~m zD+N*@v?O7ZITAl_6%EJI1|sMY01$Ynb#zW(ruHVq~1M=Q+ty5`YU&NLV+$(&-#jJ(mK-srO>L;Wjg6DqL9 zF7E8_5EV_GM-m5jOKfS@_u+#*>=Qv}n6vl5uOaJr%}8wGQV7ImuN5tvxjqgm4$l1Y zmM6)VD2{~YWZC~X?9t;Hb~EHjkE7hI52}p9?4A_R_8T*?k`?}->oAizA@0;Fp3(ke z25jM#ivw7$083a;6ju^2;ymU^DTC7r{b)^ibgM+0+JrR?gdCn<3Iy6o^F=f+;2--2 zayf}tQ9{}%Vps;|`Y6QkhC`rq5`ar%`PA{M21KJ%ssZSFK_8cb;;Nja&Q&)+F`PqnlwcE8En zVq6_{_<}KT)?gS<@uU5y@BrX$`)tz7y#9B<5{jExHFgXw z6YNJ9%{Oo8m69t#mlZXj_rc{v7mo5TFpjN93#-KtvXSF1B;42Vd9uWK9$9MgiuAh` z^yMOC=(VCG-pW29Xc^Z?rH5Lz84wHTlJrLgzGcqPo#zR7z{vc1MyfPs|0#8vx!lHx zKmYa4uTE(0y#2`kg)$20zN^QbRb1Vepe9JzxmbOlhjo|hHgSw0l%Jqqjyb}UXd;78 z&Us>Wx?D@Uh-$h=(tRhNV^Xu?Nss5DPDPKoB9@C0Od`Nw1X#aPF>e|jE~ys{OJT`T z;waCR5RA{;$D>`58xZ@<~QW@_{SeJ|f58fp%b7n#R1rVk=Ei5~SXT;QXt0bOUtoo?u@Z{hToGln;cwl4a;x z3Rf!vx`-i0iTpKyz7m7So1#b^7s@`F-s=?^fP%qlj#^eILG6t?#S~DjA+J{$UcM2Y z^yrji<_zek2ImDf#VXV+H;+wE!=e6i-)*A- zkeNL-YPaT|tW=DE2_dgRJpN6L} zs4C#H?t7f=PaP?V!Kyesa0hs?$+=j|m#9NWg(vL?8yh07@7%^_aECarX*4>Q`;=>S zWgZ2ht@8~w2B~U%0<6i6dzqev_$Q>k2ELh-qM9S1ocrC~tMWwiB0RM)dacWpw?UM> z5)oMPxb~SkPr&`pk)n4wgT9R-#hL=jsVgn?KI z=67o@2irNob%(TcsYJbXMF`?Dh9R{dJNW-~7lASapYgME`l= zcLqZ3@}JMiLz!s}yp?mph&3gQG!A`vt}W>|A9y;!leycA5czV_q})FvfdZDK80G~n zBnr*WKh>~1W!#~`jBQ+S06o{XTwNvlOr`k_DG8(WJ}Jmm4&U4_(5Wv|nuY zE1j#+;Xt2o1@dZR8e%ANiO}T-gQaOY{r_;U`&?V8z7y@zVJ&QO=ZGw<8~e1B^W5p~3K9>s52hGoc%6U1&qqGw-qgCQ@M=juH;56fPq7N4btT*@@$n?zI{r0qTL6MN z<;g+nSyVdhp@f7e9tA3B@1bkqMuCqON;^muJw`UD)1ri^e?^#O5;o{T^}V`UooTH> zX)7d`Y1eYgc*HDe7%&y@!-hoJbNTBY+S^CZp@D*I|3EY|Vkg|T2h<&3NJINNUj9(D z7%oTUWFXdOAePYTamNuW;fHyVQ5uFW4&DE;r=D%Cp?CGYF+Rb63mnCD<0l(2s zskYrRc(js4aAO{N&6Y-ADh-mS&QlLu@^~y*|@ZNmkW-OI6i6hmDo= zJVSZPVjo%ixw<4&*KB!vukH%DZNR|=3!`I4`F+PJ#G|H#3M1w7K(-DdkD|Q9_%OOK zXOOj@`%Ks=gnh8{w$6nP=}vHT2HRU-`$C>8UP!kdp8WvRCd5r&Swz|#_fa0kA@|MY z3v&Xl)?6BL{*M{U#t^9Q=^rWp=?QAE{ug_Vv>T1!E7H!|( zh+&V)IgYlyrhf-(59G!-z;Edy-95`m(K-hIPQ)mkN-qzgkFmnNBq?h4OWtR?JNpGl z>TdGQ0!Qg8R&t1yhxJM9o@ug>j{s+3V6*B|o3#*63k_Jx0t#upoP$lgg~Jm**cTQ2 zKFHj;9u2Lms%5ZTwASbhJM^ih0jROEt$uI6{?NfT4&sV6boXVcPi)_p$G(6su8dM* zr7Aq+@vO;hYjSliB|UFh(E6U+@(V6ox_Yy;VhezVU*tZ6(OBVPHJdUR&o1E5uTX(@ zrNOGy!X76C-7J!M>1uWe$-e*0jySw8?cWBGBW?K14AL|Cm+^6-ZfM3{pe#wu#JCV=X zGc<<@t+|vwEUDo>dXOrl=aH)^6h#J-sWaZWG>{=@y=KR=@OkPPZI`lGHa`b9KNSKt z!LzLnS4I|6#d`{3U8bXgS{4XC@*l?}{zih-qg)en2qrYkk>xUBY%34Tz0)EpYEnBZ z>s*-7F-`*|Gn5feh+?pDCkeb$JbW}6A1%fg2H4S0;QPYzbOoddrJVAF!GnqMIHQYo z^J{x~s^JugcAFKl!|>2RksHyOihJ_u0reK_u2&AtR;AIZ@m)mNPcpaWl)x zS7hA4S@;RB=B91bKh;FRlLA7|mJadB#_8;|a_c01#eK@d1_48uf-(O~(e7qT#b6y_ z3#MTg*yj_=4UPK@t8Q4#<<>A2-kBm@yH=>Eg08Dowo014_+HCBk>rPO{*ugvn|pWe&!ey?i0uuXZrJk-e39n#jc{ql&BV_3k#uhze z&c@PpT6|Ot+1^X@@%W{mYZmkR4+9?A89M$d_qb4g$Np*rq7CZoCdp=IYEI z)OIu`J6n$vwtQa#Kh?Ye=!~&aAjy_x%8U^j?r~-99=oM2(CGoZR8FE8`MV|te z$0nvwMg>4wP?dIAbRE`sCGNjoHKJU@wQMggN8e)$<-3D3{G*R+ZXN-9*&S*1+`lZ% z=sN{{l6R`qULGZzW(s0~n?=Cjd7Xm$eucP{3(H5Drg(R{h0B?#6Ghm<&Db)HSo)!F5a z)m?g$Gs#E|7PZYLODsw!!Jc@ZvSzUM0{5w=9Nlcd(yA(A)%n3m+-C+TmJUrqE7`zX z)A+jH1h+u(#;h{Zyw8L3B;HW=j7fdqow+2F*mQy%=Z6faSncg&?3p0ff#9!v_yBw_IRN5cBNkUH{!~p(JNfaQxuz_a zoP@SpmvA3;UrB8}kqW#~Ym4^Al;=Y-dau0z2{tHajAE4F$MdXIn$6j-4+2YsS#V5+ z95cNixPlho#egr~HkWWmF~VEe$AwyaL9ySLFqxw)PlKePpD6HrRy4c;!cPZMo|6!B z{VRU6CrXsv#UgR}#`ko@VGHPIxl(A_wj~o>* zLTiLu0MaWiM%Ji>5T&;<2kC<7u(b`gdWlV~T+i_S6_T)V8{01X!zDWgB8<9{X{~Bm ze+J!=i~QlEB8V-Z>D=8JB(}P%@iN8=ZCZG*X-@18;U=ReKAq!Q%F4;`@87{@+W#ZW dwe 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 z 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 z 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 Vz1ZOo#>R(&oVj?q;-pW~{{zZv1@8a= literal 0 HcmV?d00001 diff --git a/assets/icon/komet_512.ico b/assets/icon/komet_512.ico new file mode 100644 index 0000000000000000000000000000000000000000..bb8e2799732f3a9ee623e58319b0d8adf4269753 GIT binary patch literal 4286 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