From 20cbe52127e819b8c3dc5034e7db6a7406d346ea Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 27 Oct 2021 17:20:53 +0100 Subject: [PATCH 001/125] refactor(dynamic_links): rework initial commit --- .../platform_interface_firestore.dart | 2 +- packages/firebase_dynamic_links/CHANGELOG.md | 294 -------- packages/firebase_dynamic_links/LICENSE | 27 - packages/firebase_dynamic_links/README.md | 189 ----- .../android/build.gradle | 55 -- .../android/settings.gradle | 1 - .../android/src/main/AndroidManifest.xml | 11 - .../FirebaseDynamicLinksPlugin.java | 382 ---------- .../FlutterFirebaseAppRegistrar.java | 21 - .../android/user-agent.gradle | 22 - .../firebase_dynamic_links/example/.metadata | 8 - .../firebase_dynamic_links/example/README.md | 12 - .../example/analysis_options.yaml | 8 - .../example/android/app/build.gradle | 52 -- .../example/android/app/google-services.json | 113 --- .../gradle/wrapper/gradle-wrapper.properties | 5 - .../android/app/src/main/AndroidManifest.xml | 41 -- .../main/res/drawable/launch_background.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values/styles.xml | 17 - .../example/android/build.gradle | 31 - .../example/android/gradle.properties | 4 - .../gradle/wrapper/gradle-wrapper.properties | 5 - .../example/android/settings.gradle | 11 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - .../example/ios/Flutter/Debug.xcconfig | 2 - .../example/ios/Flutter/Release.xcconfig | 2 - .../ios/Runner.xcodeproj/project.pbxproj | 505 ------------- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 93 --- .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../example/ios/Runner/AppDelegate.h | 6 - .../example/ios/Runner/AppDelegate.m | 13 - .../AppIcon.appiconset/Contents.json | 122 ---- .../Icon-App-1024x1024@1x.png | Bin 11112 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - .../ios/Runner/GoogleService-Info.plist | 42 -- .../example/ios/Runner/Info.plist | 62 -- .../example/ios/Runner/Runner.entitlements | 5 - .../example/ios/Runner/main.m | 9 - .../example/lib/main.dart | 172 ----- .../example/pubspec.yaml | 33 - .../firebase_dynamic_links_e2e.dart | 73 -- .../firebase_dynamic_links_e2e_test.dart | 9 - .../.gitignore | 76 ++ .../CHANGELOG.md | 3 + .../LICENSE | 26 + .../README.md | 26 + ...base_dynamic_links_platform_interface.dart | 20 + .../lib/src/android_parameters.dart | 28 + .../src/dynamic_link_parameter_options.dart | 12 + .../lib/src/google_analytics_parameters.dart | 40 ++ .../lib/src/ios_parameters.dart | 58 ++ .../itunes_connect_analytics_parameters.dart | 20 + .../method_channel_dynamic_link_builder.dart | 121 ++++ ...method_channel_firebase_dynamic_links.dart | 147 ++++ .../src/method_channel/utils/exception.dart | 41 ++ .../lib/src/navigation_info_parameters.dart | 19 + .../lib/src/pending_dynamic_link_data.dart | 21 + .../pending_dynamic_link_data_android.dart | 21 + .../src/pending_dynamic_link_data_ios.dart | 12 + ...atform_interface_dynamic_link_builder.dart | 49 ++ ...form_interface_firebase_dynamic_links.dart | 86 +++ .../lib/src/short_dynamic_link.dart | 10 + .../src/short_dynamic_link_path_length.dart | 2 + .../lib/src/social_meta_tag_parameters.dart | 19 + .../ios/Assets/.gitkeep | 0 .../Classes/FLTFirebaseDynamicLinksPlugin.h | 8 - .../Classes/FLTFirebaseDynamicLinksPlugin.m | 373 ---------- .../ios/firebase_dynamic_links.podspec | 39 - .../lib/firebase_dynamic_links.dart | 14 - .../lib/src/dynamic_link_parameters.dart | 325 --------- .../lib/src/firebase_dynamic_links.dart | 164 ----- packages/firebase_dynamic_links/pubspec.yaml | 30 - .../test/firebase_dynamic_links_test.dart | 675 ------------------ 100 files changed, 858 insertions(+), 4244 deletions(-) delete mode 100644 packages/firebase_dynamic_links/CHANGELOG.md delete mode 100644 packages/firebase_dynamic_links/LICENSE delete mode 100644 packages/firebase_dynamic_links/README.md delete mode 100644 packages/firebase_dynamic_links/android/build.gradle delete mode 100644 packages/firebase_dynamic_links/android/settings.gradle delete mode 100644 packages/firebase_dynamic_links/android/src/main/AndroidManifest.xml delete mode 100644 packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java delete mode 100644 packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java delete mode 100644 packages/firebase_dynamic_links/android/user-agent.gradle delete mode 100644 packages/firebase_dynamic_links/example/.metadata delete mode 100644 packages/firebase_dynamic_links/example/README.md delete mode 100644 packages/firebase_dynamic_links/example/analysis_options.yaml delete mode 100644 packages/firebase_dynamic_links/example/android/app/build.gradle delete mode 100644 packages/firebase_dynamic_links/example/android/app/google-services.json delete mode 100644 packages/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 packages/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml delete mode 100644 packages/firebase_dynamic_links/example/android/build.gradle delete mode 100644 packages/firebase_dynamic_links/example/android/gradle.properties delete mode 100644 packages/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 packages/firebase_dynamic_links/example/android/settings.gradle delete mode 100644 packages/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 packages/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig delete mode 100644 packages/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.h delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.m delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Info.plist delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/Runner.entitlements delete mode 100644 packages/firebase_dynamic_links/example/ios/Runner/main.m delete mode 100644 packages/firebase_dynamic_links/example/lib/main.dart delete mode 100644 packages/firebase_dynamic_links/example/pubspec.yaml delete mode 100644 packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart delete mode 100644 packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/.gitignore create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/README.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart delete mode 100644 packages/firebase_dynamic_links/ios/Assets/.gitkeep delete mode 100644 packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h delete mode 100644 packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m delete mode 100644 packages/firebase_dynamic_links/ios/firebase_dynamic_links.podspec delete mode 100644 packages/firebase_dynamic_links/lib/firebase_dynamic_links.dart delete mode 100644 packages/firebase_dynamic_links/lib/src/dynamic_link_parameters.dart delete mode 100644 packages/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart delete mode 100644 packages/firebase_dynamic_links/pubspec.yaml delete mode 100644 packages/firebase_dynamic_links/test/firebase_dynamic_links_test.dart diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart index 9c36cacfdda3..85328e60941f 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'dart:typed_data'; -import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; +import '../../cloud_firestore_platform_interface.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:meta/meta.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; diff --git a/packages/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/CHANGELOG.md deleted file mode 100644 index 13e1ae582b74..000000000000 --- a/packages/firebase_dynamic_links/CHANGELOG.md +++ /dev/null @@ -1,294 +0,0 @@ -## 2.0.11 - - - **REFACTOR**: remove deprecated Flutter Android v1 Embedding usages, including in example app (#7158). - -## 2.0.10 - - - **DOCS**: changed "ibn" to "ibi" iOS param name in long dynamic link example (#7081). - - **CHORE**: update gradle version across packages (#7054). - -## 2.0.9 - - - Update a dependency to the latest release. - -## 2.0.8 - - - **STYLE**: enable additional lint rules (#6832). - - **FIX**: Use angle bracket import consistently when importing Firebase.h for iOS (#5891). - - **DOCS**: fix readme example (#6790). - -## 2.0.7 - - - Update a dependency to the latest release. - -## 2.0.6 - - - Update a dependency to the latest release. - -## 2.0.5 - - - Update a dependency to the latest release. - -## 2.0.4 - - - Update a dependency to the latest release. - -## 2.0.3 - - - **DOCS**: Add missing homepage/repository links (#6054). - -## 2.0.2 - - - **TEST**: rewrite integration test to test for parameters explicitly. - - **REFACTOR**: upgrade example to v2 Android embedding. - - **FIX**: fix broken ios code from #4354. - - **FIX**: retry handling iOS universal link on network failure (#4354). - - **DOCS**: Open Android App directly without opening link in Browser. (#3127). - - **CI**: setup `firebase_dynamic_links` ci workflow. - -## 2.0.1 - - - **DOCS**: remove codelab link from readme. - -## 2.0.0 - - - Graduate package to a stable release. See pre-releases prior to this version for changelog entries. - -## 2.0.0-dev.1 - - - Update a dependency to the latest release. - -## 2.0.0-dev.0 - -> Note: This release has breaking changes. - - - **DOCS**: remove incorrect ARCHS in ios examples (#5450). - - **CHORE**: publish packages (#5429). - - **CHORE**: merge all analysis_options.yaml into one (#5329). - - **CHORE**: publish packages. - - **CHORE**: enable lints for firebase_dynamic_links (#5256). - - **BREAKING** **FEAT**: Migrate firebase_dynamic_links to sound null safety (#5368). - -## 0.8.0 - - - This version is not null-safe but has been created to allow compatibility with other null-safe FlutterFire packages such as `firebase_core`. - -## 0.7.0 - - - **FIX**: Add missing sdk version constraints inside pubspec.yaml (#4604). - - **CHORE**: harmonize dependencies and version handling. - - **BREAKING** **FEAT**: forward port to firebase-ios-sdk v7.3.0. - - Due to this SDK upgrade, iOS 10 is now the minimum supported version by FlutterFire. Please update your build target version. - -## 0.6.3 - - - **FEAT**: bump android `com.android.tools.build` & `'com.google.gms:google-services` versions (#4269). - - **CHORE**: publish packages. - - **CHORE**: bump gradle wrapper to 5.6.4 (#4158). - -## 0.6.2 - - - **FEAT**: bump compileSdkVersion to 29 (#3975). - - **FEAT**: bump `compileSdkVersion` to 29 in preparation for upcoming Play Store requirement. - - **CHORE**: publish packages. - - **CHORE**: publish packages. - -## 0.6.1 - - - **FIX**: fixed issue with overwriting correct url with null one (#3567). - - **FEAT**: bump compileSdkVersion to 29 (#3975). - - **FEAT**: update Firebase iOS SDK version to 6.33.0 (from 6.26.0). - -## 0.6.0+2 - - - Update a dependency to the latest release. - -## 0.6.0+1 - - - **FIX**: local dependencies in example apps (#3319). - - **CHORE**: intellij cleanup (#3326). - -## 0.6.0 - -* Depend on new `firebase_core` plugin. -* Firebase iOS SDK versions are now locked to use the same version defined in - `firebase_core`. -* Firebase Android SDK versions are now using the Firebase Bill of Materials (BoM) - to specify individual SDK versions. BoM version is also sourced from - `firebase_core`. - -## 0.5.3 - -* Fix for passing null/nil link between native libraries and flutter code. - -## 0.5.2 - -* Fix for race-condition issue on iOS during initialization process - -## 0.5.1 - -* Update lower bound of dart dependency to 2.0.0. - -## 0.5.0+12 - -* Fix for missing UserAgent.h compilation failures. - -## 0.5.0+11 - -* Replace deprecated `getFlutterEngine` call on Android. - -## 0.5.0+10 - -* Make the pedantic dev_dependency explicit. - -## 0.5.0+9 - -* Remove the deprecated `author:` field from pubspec.yaml -* Migrate the plugin to the pubspec platforms manifest. -* Bump the minimum Flutter version to 1.10.0. - -## 0.5.0+8 - -* Support v2 embedding. This will remain compatible with the original embedding and won't require app migration. - -## 0.5.0+7 - -* Add `getDynamicLink` to support expanding from short links. - -## 0.5.0+6 - -* Updated README instructions for contributing for consistency with other Flutterfire plugins. - -## 0.5.0+5 - -* Remove AndroidX warning. - -## 0.5.0+4 - -* Fix example app build by updating version of `url_launcher` that is compatible with androidx apps. - -## 0.5.0+3 - -* Don't crash if registrar.activity() is not there. - -## 0.5.0+2 - -* Change the OnLinkError object to be a real exception. - -## 0.5.0+1 - -* Update documentation to reflect new repository location. -* Update unit tests to call `TestWidgetsFlutterBinding.ensureInitialized`. - -## 0.5.0 - -* **Breaking change**. Changed architecture and method names to be able to differentiate between -the dynamic link which opened the app and links clicked during app execution (active and background). -`retrieveDynamicLink` has been replaced with two different functions: -- `getInitialLink` a future to retrieve the link that opened the app -- `onLink` a callback to listen to links opened while the app is active or in background - -## 0.4.0+6 - -* Update google-services Android gradle plugin to 4.3.0 in documentation and examples. - -## 0.4.0+5 - -* Fix the bug below properly by allowing the activity to be null (but still registering the plugin). If activity is null, we don't get a latestIntent, instead we expect the intent listener to grab it. - -## 0.4.0+4 - -* Fixed bug on Android when a headless plugin tries to register this plugin causing a crash due no activity from the registrar. - -## 0.4.0+3 - -* Automatically use version from pubspec.yaml when reporting usage to Firebase. - -## 0.4.0+2 - -* Add missing template type parameter to `invokeMethod` calls. -* Bump minimum Flutter version to 1.5.0. -* Replace invokeMethod with invokeMapMethod wherever necessary. - -## 0.4.0+1 - -* Fixed bug where link persists after starting an app with a Dynamic Link. -* Fixed bug where retrieving a link would fail when app was already running. - -## 0.4.0 - -* Update dependency on firebase_core to 0.4.0. - -## 0.3.0. - -* Update Android dependencies to 16.1.7. -* **Breaking change**. Dynamic link parameter `domain` replaced with `uriPrefix`. - -## 0.2.1 - -* Throw `PlatformException` if there is an error retrieving dynamic link. - -## 0.2.0+4 - -* Fix crash when receiving `ShortDynamicLink` warnings. - -## 0.2.0+3 - -* Log messages about automatic configuration of the default app are now less confusing. - -## 0.2.0+2 - -* Remove categories. - -## 0.2.0+1 - -* Log a more detailed warning at build time about the previous AndroidX - migration. - -## 0.2.0 - -* **Breaking change**. Migrate from the deprecated original Android Support - Library to AndroidX. This shouldn't result in any functional changes, but it - requires any Android apps using this plugin to [also - migrate](https://developer.android.com/jetpack/androidx/migrate) if they're - using the original support library. - -## 0.1.1 - -* Update example to create a clickable and copyable link. - -## 0.1.0+2 - -* Change android `invites` dependency to `dynamic links` dependency. - -## 0.1.0+1 - -* Bump Android dependencies to latest. - -## 0.1.0 - -* **Breaking Change** Calls to retrieve dynamic links on iOS always returns null after first call. - -## 0.0.6 - -* Bump Android and Firebase dependency versions. - -## 0.0.5 - -* Added capability to receive dynamic links. - -## 0.0.4 - -* Fixed dynamic link dartdoc generation. - -## 0.0.3 - -* Fixed incorrect homepage link in pubspec. - -## 0.0.2 - -* Updated Gradle tooling to match Android Studio 3.1.2. - -## 0.0.1 - -* Initial release with api to create long or short dynamic links. diff --git a/packages/firebase_dynamic_links/LICENSE b/packages/firebase_dynamic_links/LICENSE deleted file mode 100644 index b9f0ba5d5188..000000000000 --- a/packages/firebase_dynamic_links/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/packages/firebase_dynamic_links/README.md b/packages/firebase_dynamic_links/README.md deleted file mode 100644 index e320725e17bf..000000000000 --- a/packages/firebase_dynamic_links/README.md +++ /dev/null @@ -1,189 +0,0 @@ -# Google Dynamic Links for Firebase - -[![pub package](https://img.shields.io/pub/v/firebase_dynamic_links.svg)](https://pub.dev/packages/firebase_dynamic_links) - -A Flutter plugin to use the [Google Dynamic Links for Firebase API](https://firebase.google.com/docs/dynamic-links/). - -With Dynamic Links, your users get the best available experience for the platform they open your link on. If a user opens a Dynamic Link on iOS or Android, they can be taken directly to the linked content in your native app. If a user opens the same Dynamic Link in a desktop browser, they can be taken to the equivalent content on your website. - -In addition, Dynamic Links work across app installs: if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link. - -For Flutter plugins for other Firebase products, see [README.md](https://github.com/FirebaseExtended/flutterfire/blob/master/README.md). - -## Usage - -To use this plugin, add `firebase_dynamic_links` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). You must also configure firebase dynamic links for each platform project: Android and iOS (see the example folder for details). - -## Create Dynamic Links - -You create a Dynamic Link either by using the Firebase console, using a REST API, iOS or Android Builder API, Flutter API, or by forming a URL by adding Dynamic Link parameters to a URI prefix specific to your app. These parameters specify the links you want to open, depending on the user's platform and whether your app is installed. - -Below are instructions to create Dynamic Links using Flutter with the Firebase Dynamic Links API. This API accepts either a long Dynamic Link or an object containing Dynamic Link parameters, and returns a URL like the following example: - -``` -https://example.page.link/WXYZ -``` - -You can create a Dynamic Link programmatically by setting the following parameters and using the `DynamicLinkParameters.buildUrl()` method. - -```dart -final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://abc123.app.goo.gl', - link: Uri.parse('https://example.com/'), - androidParameters: AndroidParameters( - packageName: 'com.example.android', - minimumVersion: 125, - ), - iosParameters: IosParameters( - bundleId: 'com.example.ios', - minimumVersion: '1.0.1', - appStoreId: '123456789', - ), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'example-promo', - medium: 'social', - source: 'orkut', - ), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - providerToken: '123456', - campaignToken: 'example-promo', - ), - socialMetaTagParameters: SocialMetaTagParameters( - title: 'Example of a Dynamic Link', - description: 'This link works whether app is installed or not!', - ), -); - -final Uri dynamicUrl = await parameters.buildUrl(); -``` - -To create a short Dynamic Link, build `DynamicLinkParameters` the same way, but use the `DynamicLinkParameters.buildShortLink()` method. - -```dart -final ShortDynamicLink shortDynamicLink = await parameters.buildShortLink(); -final Uri shortUrl = shortDynamicLink.shortUrl; -``` - -To shorten a long Dynamic Link, use the DynamicLinkParameters.shortenUrl method. - -```dart -final ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl( - Uri.parse('https://example.page.link/?link=https://example.com/&apn=com.example.android&ibi=com.example.ios'), - DynamicLinkParametersOptions(ShortDynamicLinkPathLength.unguessable), -); - -final Uri shortUrl = shortenedLink.shortUrl; -``` - -## Handle Received Dynamic Links - -You can receive a Dynamic Link containing a deep link that takes the user to specific content within your app: - -1. In the [Firebase Console](https://console.firebase.google.com), open the Dynamic Links section. - - Accept the terms of service if you are prompted to do so. - - Take note of your project's Dynamic Links URL prefix, which is displayed at the top of the Dynamic Links page. You need your project's Dynamic Links URL prefix to programmatically create Dynamic Links. Unless you are using a custom domain, a Dynamic Links URL prefix looks like `https://YOUR_SUBDOMAIN.page.link`. - -Receiving dynamic links on *iOS* requires a couple more steps than *Android*. If you only want to receive dynamic links on *Android*, skip to step 5. You can also follow a video on the next two steps [here.](https://youtu.be/KLBjAg6HvG0?t=60) - -2. In the **Info** tab of your *iOS* app's Xcode project: - - Create a new **URL Type** to be used for Dynamic Links. - - Set the **Identifier** field to a unique value and the **URL Schemes** field to be your bundle identifier, which is the default URL scheme used by Dynamic Links. - -3. In the **Capabilities** tab of your app's Xcode project, enable **Associated Domains** and add the following to the **Associated Domains** list: - -``` -applinks:YOUR_URL_PREFIX -``` - -Remember not to include `https://` or any slashes or paths in your prefix - -4. **If you are using a custom domain** create an key in your `Info.plist` file called `FirebaseDynamicLinksCustomDomains` and set it to your app's Dynamic Link URL prefixes. For example: - -```xml -FirebaseDynamicLinksCustomDomains - - https://example.com/promos - https://example.com/links/share - -``` -5. If you want to open android app directly without redirecting to Chrome or Any other Browser you can put an `intent-filter` in your `AndroidManifest.xml` file. It will open the system dialogue to open link with your app or other browsers. Users can then directly choose to open the link in your app. - -Note: This step is optional and in case we do not implement this then link will open in chrome at first and then will eventually open your application. -```xml - - - - - - - -``` -6. To receive a dynamic link, call the `getInitialLink()` method from `FirebaseDynamicLinks` which gets the link that opened the app (or null if it was not opened via a dynamic link) -and configure listeners for link callbacks when the application is active or in background calling `onLink`. - -```dart -void main() { - runApp(MaterialApp( - title: 'Dynamic Links Example', - routes: { - '/': (BuildContext context) => MyHomeWidget(), // Default home route - '/helloworld': (BuildContext context) => MyHelloWorldWidget(), - }, - )); -} - -class MyHomeWidgetState extends State { - . - . - . - @override - void initState() { - super.initState(); - this.initDynamicLinks(); - } - - void initDynamicLinks() async { - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData? dynamicLink) async { - final Uri? deepLink = dynamicLink?.link; - - if (deepLink != null) { - Navigator.pushNamed(context, deepLink.path); - } - }, - onError: (OnLinkErrorException e) async { - print('onLinkError'); - print(e.message); - } - ); - - final PendingDynamicLinkData? data = await FirebaseDynamicLinks.instance.getInitialLink(); - final Uri? deepLink = data?.link; - - if (deepLink != null) { - Navigator.pushNamed(context, deepLink.path); - } - } - . - . - . -} -``` - -If your app did not open from a dynamic link, `getInitialLink()` will return `null`. - -## Getting Started - -See the `example` directory for a complete sample app using Google Dynamic Links for Firebase. - -## Issues and feedback - -Please file FlutterFire specific issues, bugs, or feature requests in our [issue tracker](https://github.com/FirebaseExtended/flutterfire/issues/new). - -Plugin issues that are not specific to Flutterfire can be filed in the [Flutter issue tracker](https://github.com/flutter/flutter/issues/new). - -To contribute a change to this plugin, -please review our [contribution guide](https://github.com/FirebaseExtended/flutterfire/blob/master/CONTRIBUTING.md) -and open a [pull request](https://github.com/FirebaseExtended/flutterfire/pulls). diff --git a/packages/firebase_dynamic_links/android/build.gradle b/packages/firebase_dynamic_links/android/build.gradle deleted file mode 100644 index dda034ab7e8c..000000000000 --- a/packages/firebase_dynamic_links/android/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -group 'io.flutter.plugins.firebasedynamiclinks' -version '1.0-SNAPSHOT' - -buildscript { - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.4' - } -} - -rootProject.allprojects { - repositories { - google() - mavenCentral() - } -} - -apply plugin: 'com.android.library' - -def firebaseCoreProject = findProject(':firebase_core') -if (firebaseCoreProject == null) { - throw new GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') -} else if (!firebaseCoreProject.properties['FirebaseSDKVersion']) { - throw new GradleException('A newer version of the firebase_core FlutterFire plugin is required, please update your firebase_core pubspec dependency.') -} - -def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { - if (!rootProject.ext.has('FlutterFire')) return firebaseCoreProject.properties[name] - if (!rootProject.ext.get('FlutterFire')[name]) return firebaseCoreProject.properties[name] - return rootProject.ext.get('FlutterFire').get(name) -} - -android { - compileSdkVersion 29 - - defaultConfig { - minSdkVersion 16 - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - lintOptions { - disable 'InvalidPackage' - } - dependencies { - api firebaseCoreProject - implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}") - implementation 'com.google.firebase:firebase-dynamic-links' - } -} - -apply from: file("./user-agent.gradle") - diff --git a/packages/firebase_dynamic_links/android/settings.gradle b/packages/firebase_dynamic_links/android/settings.gradle deleted file mode 100644 index 2a833554f85c..000000000000 --- a/packages/firebase_dynamic_links/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'firebase_dynamic_links' diff --git a/packages/firebase_dynamic_links/android/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/android/src/main/AndroidManifest.xml deleted file mode 100644 index 663e4f0f3de9..000000000000 --- a/packages/firebase_dynamic_links/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java deleted file mode 100644 index 7ec424a846fc..000000000000 --- a/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ /dev/null @@ -1,382 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.firebasedynamiclinks; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; -import com.google.android.gms.tasks.Task; -import com.google.firebase.dynamiclinks.DynamicLink; -import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import com.google.firebase.dynamiclinks.PendingDynamicLinkData; -import com.google.firebase.dynamiclinks.ShortDynamicLink; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.embedding.engine.plugins.activity.ActivityAware; -import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.PluginRegistry.NewIntentListener; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Flutter plugin accessing for Firebase Dynamic Links API. - * - *

Instantiate this in an add to app scenario to gracefully handle activity and context changes. - */ -public class FirebaseDynamicLinksPlugin - implements FlutterPlugin, ActivityAware, MethodCallHandler, NewIntentListener { - private Activity activity; - private MethodChannel channel; - - private FirebaseDynamicLinksPlugin(Activity activity, MethodChannel channel) { - this.activity = activity; - this.channel = channel; - } - - /** - * Default Constructor. - * - *

Use this when adding the plugin to your FlutterEngine - */ - public FirebaseDynamicLinksPlugin() {} - - private static MethodChannel createChannel(final BinaryMessenger messenger) { - return new MethodChannel(messenger, "plugins.flutter.io/firebase_dynamic_links"); - } - - @Override - public boolean onNewIntent(Intent intent) { - FirebaseDynamicLinks.getInstance() - .getDynamicLink(intent) - .addOnSuccessListener( - new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null) { - Map dynamicLink = - getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - channel.invokeMethod("onLinkSuccess", dynamicLink); - } - } - }) - .addOnFailureListener( - new OnFailureListener() { - @Override - public void onFailure(Exception e) { - Map exception = new HashMap<>(); - exception.put("code", e.getClass().getSimpleName()); - exception.put("message", e.getMessage()); - exception.put("details", null); - channel.invokeMethod("onLinkError", exception); - } - }); - - return false; - } - - @Override - public void onAttachedToEngine(FlutterPluginBinding binding) { - channel = createChannel(binding.getBinaryMessenger()); - channel.setMethodCallHandler(this); - } - - @Override - public void onDetachedFromEngine(FlutterPluginBinding binding) { - channel.setMethodCallHandler(null); - } - - @Override - public void onAttachedToActivity(ActivityPluginBinding binding) { - activity = binding.getActivity(); - binding.addOnNewIntentListener(this); - } - - @Override - public void onDetachedFromActivityForConfigChanges() { - activity = null; - } - - @Override - public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { - activity = binding.getActivity(); - binding.addOnNewIntentListener(this); - } - - @Override - public void onDetachedFromActivity() { - activity = null; - } - - @Override - public void onMethodCall(MethodCall call, Result result) { - switch (call.method) { - case "DynamicLinkParameters#buildUrl": - DynamicLink.Builder urlBuilder = setupParameters(call); - result.success(urlBuilder.buildDynamicLink().getUri().toString()); - break; - case "DynamicLinkParameters#buildShortLink": - DynamicLink.Builder shortLinkBuilder = setupParameters(call); - buildShortDynamicLink(shortLinkBuilder, call, createShortLinkListener(result)); - break; - case "DynamicLinkParameters#shortenUrl": - DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink(); - - Uri url = Uri.parse((String) call.argument("url")); - builder.setLongLink(url); - buildShortDynamicLink(builder, call, createShortLinkListener(result)); - break; - case "FirebaseDynamicLinks#getDynamicLink": - handleGetDynamicLink(result, Uri.parse((String) call.argument("url"))); - break; - case "FirebaseDynamicLinks#getInitialLink": - handleGetInitialDynamicLink(result); - break; - default: - result.notImplemented(); - break; - } - } - - private Map getMapFromPendingDynamicLinkData( - PendingDynamicLinkData pendingDynamicLinkData) { - Map dynamicLink = new HashMap<>(); - Uri link = pendingDynamicLinkData.getLink(); - dynamicLink.put("link", link != null ? link.toString() : null); - - Map androidData = new HashMap<>(); - androidData.put("clickTimestamp", pendingDynamicLinkData.getClickTimestamp()); - androidData.put("minimumVersion", pendingDynamicLinkData.getMinimumAppVersion()); - - dynamicLink.put("android", androidData); - return dynamicLink; - } - - private void addDynamicLinkListener(Task task, final Result result) { - task.addOnSuccessListener( - new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null) { - Map dynamicLink = - getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - result.success(dynamicLink); - return; - } - result.success(null); - } - }) - .addOnFailureListener( - new OnFailureListener() { - @Override - public void onFailure(Exception e) { - result.error(e.getClass().getSimpleName(), e.getMessage(), null); - } - }); - } - - private void handleGetDynamicLink(final Result result, Uri uri) { - addDynamicLinkListener(FirebaseDynamicLinks.getInstance().getDynamicLink(uri), result); - } - - private void handleGetInitialDynamicLink(final Result result) { - // If there's no activity or initial Intent, then there's no initial dynamic link. - if (activity == null || activity.getIntent() == null) { - result.success(null); - return; - } - - addDynamicLinkListener( - FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent()), result); - } - - private OnCompleteListener createShortLinkListener(final Result result) { - return new OnCompleteListener() { - @Override - public void onComplete(Task task) { - if (task.isSuccessful()) { - Map url = new HashMap<>(); - url.put("url", task.getResult().getShortLink().toString()); - - List warnings = new ArrayList<>(); - if (task.getResult().getWarnings() != null) { - for (ShortDynamicLink.Warning warning : task.getResult().getWarnings()) { - warnings.add(warning.getMessage()); - } - } - - url.put("warnings", warnings); - - result.success(url); - } else { - Exception exception = task.getException(); - String errMsg = "Unable to create short link"; - if (exception != null && exception.getLocalizedMessage() != null) { - errMsg = exception.getLocalizedMessage(); - } - result.error("short_link_error", errMsg, null); - } - } - }; - } - - private void buildShortDynamicLink( - DynamicLink.Builder builder, MethodCall call, OnCompleteListener listener) { - Integer suffix = null; - - Map dynamicLinkParametersOptions = - call.argument("dynamicLinkParametersOptions"); - if (dynamicLinkParametersOptions != null) { - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); - if (shortDynamicLinkPathLength != null) { - switch (shortDynamicLinkPathLength) { - case 0: - suffix = ShortDynamicLink.Suffix.UNGUESSABLE; - break; - case 1: - suffix = ShortDynamicLink.Suffix.SHORT; - break; - default: - break; - } - } - } - - if (suffix != null) { - builder.buildShortDynamicLink(suffix).addOnCompleteListener(listener); - } else { - builder.buildShortDynamicLink().addOnCompleteListener(listener); - } - } - - private DynamicLink.Builder setupParameters(MethodCall call) { - DynamicLink.Builder dynamicLinkBuilder = FirebaseDynamicLinks.getInstance().createDynamicLink(); - - String uriPrefix = call.argument("uriPrefix"); - String link = call.argument("link"); - - dynamicLinkBuilder.setDomainUriPrefix(uriPrefix); - dynamicLinkBuilder.setLink(Uri.parse(link)); - - Map androidParameters = call.argument("androidParameters"); - if (androidParameters != null) { - String packageName = valueFor("packageName", androidParameters); - String fallbackUrl = valueFor("fallbackUrl", androidParameters); - Integer minimumVersion = valueFor("minimumVersion", androidParameters); - - DynamicLink.AndroidParameters.Builder builder = - new DynamicLink.AndroidParameters.Builder(packageName); - - if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); - if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); - - dynamicLinkBuilder.setAndroidParameters(builder.build()); - } - - Map googleAnalyticsParameters = call.argument("googleAnalyticsParameters"); - if (googleAnalyticsParameters != null) { - String campaign = valueFor("campaign", googleAnalyticsParameters); - String content = valueFor("content", googleAnalyticsParameters); - String medium = valueFor("medium", googleAnalyticsParameters); - String source = valueFor("source", googleAnalyticsParameters); - String term = valueFor("term", googleAnalyticsParameters); - - DynamicLink.GoogleAnalyticsParameters.Builder builder = - new DynamicLink.GoogleAnalyticsParameters.Builder(); - - if (campaign != null) builder.setCampaign(campaign); - if (content != null) builder.setContent(content); - if (medium != null) builder.setMedium(medium); - if (source != null) builder.setSource(source); - if (term != null) builder.setTerm(term); - - dynamicLinkBuilder.setGoogleAnalyticsParameters(builder.build()); - } - - Map iosParameters = call.argument("iosParameters"); - if (iosParameters != null) { - String bundleId = valueFor("bundleId", iosParameters); - String appStoreId = valueFor("appStoreId", iosParameters); - String customScheme = valueFor("customScheme", iosParameters); - String fallbackUrl = valueFor("fallbackUrl", iosParameters); - String ipadBundleId = valueFor("ipadBundleId", iosParameters); - String ipadFallbackUrl = valueFor("ipadFallbackUrl", iosParameters); - String minimumVersion = valueFor("minimumVersion", iosParameters); - - DynamicLink.IosParameters.Builder builder = new DynamicLink.IosParameters.Builder(bundleId); - - if (appStoreId != null) builder.setAppStoreId(appStoreId); - if (customScheme != null) builder.setCustomScheme(customScheme); - if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); - if (ipadBundleId != null) builder.setIpadBundleId(ipadBundleId); - if (ipadFallbackUrl != null) builder.setIpadFallbackUrl(Uri.parse(ipadFallbackUrl)); - if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); - - dynamicLinkBuilder.setIosParameters(builder.build()); - } - - Map itunesConnectAnalyticsParameters = - call.argument("itunesConnectAnalyticsParameters"); - if (itunesConnectAnalyticsParameters != null) { - String affiliateToken = valueFor("affiliateToken", itunesConnectAnalyticsParameters); - String campaignToken = valueFor("campaignToken", itunesConnectAnalyticsParameters); - String providerToken = valueFor("providerToken", itunesConnectAnalyticsParameters); - - DynamicLink.ItunesConnectAnalyticsParameters.Builder builder = - new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); - - if (affiliateToken != null) builder.setAffiliateToken(affiliateToken); - if (campaignToken != null) builder.setCampaignToken(campaignToken); - if (providerToken != null) builder.setProviderToken(providerToken); - - dynamicLinkBuilder.setItunesConnectAnalyticsParameters(builder.build()); - } - - Map navigationInfoParameters = call.argument("navigationInfoParameters"); - if (navigationInfoParameters != null) { - Boolean forcedRedirectEnabled = valueFor("forcedRedirectEnabled", navigationInfoParameters); - - DynamicLink.NavigationInfoParameters.Builder builder = - new DynamicLink.NavigationInfoParameters.Builder(); - - if (forcedRedirectEnabled != null) builder.setForcedRedirectEnabled(forcedRedirectEnabled); - - dynamicLinkBuilder.setNavigationInfoParameters(builder.build()); - } - - Map socialMetaTagParameters = call.argument("socialMetaTagParameters"); - if (socialMetaTagParameters != null) { - String description = valueFor("description", socialMetaTagParameters); - String imageUrl = valueFor("imageUrl", socialMetaTagParameters); - String title = valueFor("title", socialMetaTagParameters); - - DynamicLink.SocialMetaTagParameters.Builder builder = - new DynamicLink.SocialMetaTagParameters.Builder(); - - if (description != null) builder.setDescription(description); - if (imageUrl != null) builder.setImageUrl(Uri.parse(imageUrl)); - if (title != null) builder.setTitle(title); - - dynamicLinkBuilder.setSocialMetaTagParameters(builder.build()); - } - - return dynamicLinkBuilder; - } - - private static T valueFor(String key, Map map) { - @SuppressWarnings("unchecked") - T result = (T) map.get(key); - return result; - } -} diff --git a/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java b/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java deleted file mode 100644 index dbf3822c7a24..000000000000 --- a/packages/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.firebasedynamiclinks; - -import androidx.annotation.Keep; -import com.google.firebase.components.Component; -import com.google.firebase.components.ComponentRegistrar; -import com.google.firebase.platforminfo.LibraryVersionComponent; -import java.util.Collections; -import java.util.List; - -@Keep -public class FlutterFirebaseAppRegistrar implements ComponentRegistrar { - @Override - public List> getComponents() { - return Collections.>singletonList( - LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION)); - } -} diff --git a/packages/firebase_dynamic_links/android/user-agent.gradle b/packages/firebase_dynamic_links/android/user-agent.gradle deleted file mode 100644 index 06d7f9075b82..000000000000 --- a/packages/firebase_dynamic_links/android/user-agent.gradle +++ /dev/null @@ -1,22 +0,0 @@ -import java.util.regex.Matcher -import java.util.regex.Pattern - -String libraryVersionName = "UNKNOWN" -String libraryName = "flutter-fire-dl" -File pubspec = new File(project.projectDir.parentFile, 'pubspec.yaml') - -if (pubspec.exists()) { - String yaml = pubspec.text - // Using \s*['|"]?([^\n|'|"]*)['|"]? to extract version number. - Matcher versionMatcher = Pattern.compile("^version:\\s*['|\"]?([^\\n|'|\"]*)['|\"]?\$", Pattern.MULTILINE).matcher(yaml) - if (versionMatcher.find()) libraryVersionName = versionMatcher.group(1).replaceAll("\\+", "-") -} - -android { - defaultConfig { - // BuildConfig.VERSION_NAME - buildConfigField 'String', 'LIBRARY_VERSION', "\"${libraryVersionName}\"" - // BuildConfig.LIBRARY_NAME - buildConfigField 'String', 'LIBRARY_NAME', "\"${libraryName}\"" - } -} diff --git a/packages/firebase_dynamic_links/example/.metadata b/packages/firebase_dynamic_links/example/.metadata deleted file mode 100644 index 866a061a7a7f..000000000000 --- a/packages/firebase_dynamic_links/example/.metadata +++ /dev/null @@ -1,8 +0,0 @@ -# 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: f408bb06f9361793ca85493c38d809ee1e2f7e30 - channel: master diff --git a/packages/firebase_dynamic_links/example/README.md b/packages/firebase_dynamic_links/example/README.md deleted file mode 100644 index e098704eddc5..000000000000 --- a/packages/firebase_dynamic_links/example/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# firebase_dynamic_links_example - -Demonstrates how to use the firebase_dynamic_links plugin. - -## *Important* - -The example app for this plugin only receives links on Android. Xcode has signing requirements that must be configured with an iOS app developer team id. Check the `firebase_dynamic_links/README.md` for more details. - -## Getting Started - -For help getting started with Flutter, view our online -[documentation](https://flutter.io/). diff --git a/packages/firebase_dynamic_links/example/analysis_options.yaml b/packages/firebase_dynamic_links/example/analysis_options.yaml deleted file mode 100644 index 98eee62ba0f0..000000000000 --- a/packages/firebase_dynamic_links/example/analysis_options.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2021 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# in the LICENSE file. -include: ../../../analysis_options.yaml -linter: - rules: - public_member_api_docs: false - avoid_print: false \ No newline at end of file diff --git a/packages/firebase_dynamic_links/example/android/app/build.gradle b/packages/firebase_dynamic_links/example/android/app/build.gradle deleted file mode 100644 index 61748d009e2c..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/build.gradle +++ /dev/null @@ -1,52 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 29 - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - applicationId "io.flutter.plugins.firebasedynamiclinksexample" - minSdkVersion 16 - targetSdkVersion 29 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} diff --git a/packages/firebase_dynamic_links/example/android/app/google-services.json b/packages/firebase_dynamic_links/example/android/app/google-services.json deleted file mode 100644 index 7123ea9b2ebd..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/google-services.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "project_info": { - "project_number": "479882132969", - "firebase_url": "https://my-flutter-proj.firebaseio.com", - "project_id": "my-flutter-proj", - "storage_bucket": "my-flutter-proj.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:632cdf3fc0a17139", - "android_client_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "cvbxvzv" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:215a22700e1b466b", - "android_client_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-8h4kiv8m7ho4tvn6uuujsfcrf69unuf7.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "cvbxvzv" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ] - }, - "ads_service": { - "status": 2 - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/packages/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 186b71557c50..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 3906eecd9efa..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml b/packages/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f88420..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/packages/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml b/packages/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 11beaaf68414..000000000000 --- a/packages/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - diff --git a/packages/firebase_dynamic_links/example/android/build.gradle b/packages/firebase_dynamic_links/example/android/build.gradle deleted file mode 100644 index 649f806eb474..000000000000 --- a/packages/firebase_dynamic_links/example/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.2' - classpath 'com.google.gms:google-services:4.3.4' - } -} - -allprojects { - repositories { - google() - jcenter() - mavenLocal() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/packages/firebase_dynamic_links/example/android/gradle.properties b/packages/firebase_dynamic_links/example/android/gradle.properties deleted file mode 100644 index 38c8d4544ff1..000000000000 --- a/packages/firebase_dynamic_links/example/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3c46198fce9e..000000000000 --- a/packages/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/packages/firebase_dynamic_links/example/android/settings.gradle b/packages/firebase_dynamic_links/example/android/settings.gradle deleted file mode 100644 index 44e62bcf06ae..000000000000 --- a/packages/firebase_dynamic_links/example/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/packages/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig b/packages/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index e8efba114687..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig b/packages/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index 399e9340e6f6..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 9a7df42960b3..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,505 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */; }; - 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */; }; - 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 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 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 = ""; }; - 20643451FF253CB176AF9580 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 23C87C2196BFAAA7E465A745 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; - 8FE60D1A20C0962300E3A541 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; 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; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 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 = ( - 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 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 */, - C265487490C4649DB6EB38D8 /* Pods */, - FB89BCA43D68B61E6BC59A86 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 8FE60D1A20C0962300E3A541 /* Runner.entitlements */, - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - C265487490C4649DB6EB38D8 /* Pods */ = { - isa = PBXGroup; - children = ( - 20643451FF253CB176AF9580 /* Pods-Runner.debug.xcconfig */, - 23C87C2196BFAAA7E465A745 /* Pods-Runner.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - FB89BCA43D68B61E6BC59A86 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - DFB8FA600F7B599A94289A9E /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */, - ); - 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 = { - LastUpgradeCheck = 0910; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.SafariKeychain = { - enabled = 0; - }; - }; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */, - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 9740EEB41CF90195004384FC /* Debug.xcconfig 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; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - 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"; - }; - DFB8FA600F7B599A94289A9E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase 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 */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - 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_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_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; - 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 = 10.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - 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_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_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; - 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 = 10.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = ""; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = ""; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - PROVISIONING_PROFILE_SPECIFIER = ""; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 1263ac84b105..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c74e..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d68..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.h b/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.h deleted file mode 100644 index 36e21bbf9cf4..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.m b/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.m deleted file mode 100644 index 59a72e90be12..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2d9d..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "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" : "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" : "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" - } -} diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index 3d43d11e66f4de3da27ed045ca4fe38ad8b48094..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11112 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 P-1+_A+?hGkL;m(J7kc&K diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 zcmds$`#;kQ7{|XelZftyR5~xW7?MLxS4^|Hw3&P7^y)@A9Fj{Xm1~_CIV^XZ%SLBn zA;!r`GqGHg=7>xrB{?psZQs88ZaedDoagm^KF{a*>G|dJWRSe^I$DNW008I^+;Kjt z>9p3GNR^I;v>5_`+91i(*G;u5|L+Bu6M=(afLjtkya#yZ175|z$pU~>2#^Z_pCZ7o z1c6UNcv2B3?; zX%qdxCXQpdKRz=#b*q0P%b&o)5ZrNZt7$fiETSK_VaY=mb4GK`#~0K#~9^ zcY!`#Af+4h?UMR-gMKOmpuYeN5P*RKF!(tb`)oe0j2BH1l?=>y#S5pMqkx6i{*=V9JF%>N8`ewGhRE(|WohnD59R^$_36{4>S zDFlPC5|k?;SPsDo87!B{6*7eqmMdU|QZ84>6)Kd9wNfh90=y=TFQay-0__>=<4pk& zYDjgIhL-jQ9o>z32K)BgAH+HxamL{ZL~ozu)Qqe@a`FpH=oQRA8=L-m-1dam(Ix2V z?du;LdMO+ooBelr^_y4{|44tmgH^2hSzPFd;U^!1p>6d|o)(-01z{i&Kj@)z-yfWQ)V#3Uo!_U}q3u`(fOs`_f^ueFii1xBNUB z6MecwJN$CqV&vhc+)b(p4NzGGEgwWNs z@*lUV6LaduZH)4_g!cE<2G6#+hJrWd5(|p1Z;YJ7ifVHv+n49btR}dq?HHDjl{m$T z!jLZcGkb&XS2OG~u%&R$(X+Z`CWec%QKt>NGYvd5g20)PU(dOn^7%@6kQb}C(%=vr z{?RP(z~C9DPnL{q^@pVw@|Vx~@3v!9dCaBtbh2EdtoNHm4kGxp>i#ct)7p|$QJs+U z-a3qtcPvhihub?wnJqEt>zC@)2suY?%-96cYCm$Q8R%-8$PZYsx3~QOLMDf(piXMm zB=<63yQk1AdOz#-qsEDX>>c)EES%$owHKue;?B3)8aRd}m~_)>SL3h2(9X;|+2#7X z+#2)NpD%qJvCQ0a-uzZLmz*ms+l*N}w)3LRQ*6>|Ub-fyptY(keUxw+)jfwF5K{L9 z|Cl_w=`!l_o><384d&?)$6Nh(GAm=4p_;{qVn#hI8lqewW7~wUlyBM-4Z|)cZr?Rh z=xZ&Ol>4(CU85ea(CZ^aO@2N18K>ftl8>2MqetAR53_JA>Fal`^)1Y--Am~UDa4th zKfCYpcXky$XSFDWBMIl(q=Mxj$iMBX=|j9P)^fDmF(5(5$|?Cx}DKEJa&XZP%OyE`*GvvYQ4PV&!g2|L^Q z?YG}tx;sY@GzMmsY`7r$P+F_YLz)(e}% zyakqFB<6|x9R#TdoP{R$>o7y(-`$$p0NxJ6?2B8tH)4^yF(WhqGZlM3=9Ibs$%U1w zWzcss*_c0=v_+^bfb`kBFsI`d;ElwiU%frgRB%qBjn@!0U2zZehBn|{%uNIKBA7n= zzE`nnwTP85{g;8AkYxA68>#muXa!G>xH22D1I*SiD~7C?7Za+9y7j1SHiuSkKK*^O zsZ==KO(Ua#?YUpXl{ViynyT#Hzk=}5X$e04O@fsMQjb}EMuPWFO0e&8(2N(29$@Vd zn1h8Yd>6z(*p^E{c(L0Lg=wVdupg!z@WG;E0k|4a%s7Up5C0c)55XVK*|x9RQeZ1J@1v9MX;>n34(i>=YE@Iur`0Vah(inE3VUFZNqf~tSz{1fz3Fsn_x4F>o(Yo;kpqvBe-sbwH(*Y zu$JOl0b83zu$JMvy<#oH^Wl>aWL*?aDwnS0iEAwC?DK@aT)GHRLhnz2WCvf3Ba;o=aY7 z2{Asu5MEjGOY4O#Ggz@@J;q*0`kd2n8I3BeNuMmYZf{}pg=jTdTCrIIYuW~luKecn z+E-pHY%ohj@uS0%^ z&(OxwPFPD$+#~`H?fMvi9geVLci(`K?Kj|w{rZ9JgthFHV+=6vMbK~0)Ea<&WY-NC zy-PnZft_k2tfeQ*SuC=nUj4H%SQ&Y$gbH4#2sT0cU0SdFs=*W*4hKGpuR1{)mV;Qf5pw4? zfiQgy0w3fC*w&Bj#{&=7033qFR*<*61B4f9K%CQvxEn&bsWJ{&winp;FP!KBj=(P6 z4Z_n4L7cS;ao2)ax?Tm|I1pH|uLpDSRVghkA_UtFFuZ0b2#>!8;>-_0ELjQSD-DRd z4im;599VHDZYtnWZGAB25W-e(2VrzEh|etsv2YoP#VbIZ{aFkwPrzJ#JvCvA*mXS& z`}Q^v9(W4GiSs}#s7BaN!WA2bniM$0J(#;MR>uIJ^uvgD3GS^%*ikdW6-!VFUU?JV zZc2)4cMsX@j z5HQ^e3BUzOdm}yC-xA%SY``k$rbfk z;CHqifhU*jfGM@DkYCecD9vl*qr58l6x<8URB=&%{!Cu3RO*MrKZ4VO}V6R0a zZw3Eg^0iKWM1dcTYZ0>N899=r6?+adUiBKPciJw}L$=1f4cs^bio&cr9baLF>6#BM z(F}EXe-`F=f_@`A7+Q&|QaZ??Txp_dB#lg!NH=t3$G8&06MFhwR=Iu*Im0s_b2B@| znW>X}sy~m#EW)&6E&!*0%}8UAS)wjt+A(io#wGI@Z2S+Ms1Cxl%YVE800007ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b70f1..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 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/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c939..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard b/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist b/packages/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index ac0d4c98b0d0..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,42 +0,0 @@ - - - - - AD_UNIT_ID_FOR_BANNER_TEST - ca-app-pub-3940256099942544/2934735716 - AD_UNIT_ID_FOR_INTERSTITIAL_TEST - ca-app-pub-3940256099942544/4411468910 - CLIENT_ID - 479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9 - ANDROID_CLIENT_ID - 479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com - API_KEY - AIzaSyBECOwLTAN6PU4Aet1b2QLGIb3kRK8Xjew - GCM_SENDER_ID - 479882132969 - PLIST_VERSION - 1 - BUNDLE_ID - com.google.FirebaseCppDynamicLinksTestApp.dev - PROJECT_ID - my-flutter-proj - STORAGE_BUCKET - my-flutter-proj.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:479882132969:ios:36e157824ba4dd3d - DATABASE_URL - https://my-flutter-proj.firebaseio.com - - \ No newline at end of file diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Info.plist b/packages/firebase_dynamic_links/example/ios/Runner/Info.plist deleted file mode 100644 index f24bc9d4f80d..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Info.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - firebase_dynamic_links_example - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - Bundle ID - CFBundleURLSchemes - - com.google.FirebaseCppDynamicLinksTestApp.dev - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner/Runner.entitlements b/packages/firebase_dynamic_links/example/ios/Runner/Runner.entitlements deleted file mode 100644 index 0c67376ebacb..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/Runner.entitlements +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packages/firebase_dynamic_links/example/ios/Runner/main.m b/packages/firebase_dynamic_links/example/ios/Runner/main.m deleted file mode 100644 index dff6597e4513..000000000000 --- a/packages/firebase_dynamic_links/example/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/packages/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/example/lib/main.dart deleted file mode 100644 index 1426406be6ee..000000000000 --- a/packages/firebase_dynamic_links/example/lib/main.dart +++ /dev/null @@ -1,172 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; - -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:url_launcher/url_launcher.dart'; - -void main() { - runApp(MaterialApp( - title: 'Dynamic Links Example', - routes: { - '/': (BuildContext context) => _MainScreen(), - '/helloworld': (BuildContext context) => _DynamicLinkScreen(), - }, - )); -} - -class _MainScreen extends StatefulWidget { - @override - State createState() => _MainScreenState(); -} - -class _MainScreenState extends State<_MainScreen> { - String? _linkMessage; - bool _isCreatingLink = false; - String _testString = - 'To test: long press link and then copy and click from a non-browser ' - "app. Make sure this isn't being tested on iOS simulator and iOS xcode " - 'is properly setup. Look at firebase_dynamic_links/README.md for more ' - 'details.'; - - @override - void initState() { - super.initState(); - initDynamicLinks(); - } - - Future initDynamicLinks() async { - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData? dynamicLink) async { - final Uri? deepLink = dynamicLink?.link; - - if (deepLink != null) { - // ignore: unawaited_futures - Navigator.pushNamed(context, deepLink.path); - } - }, onError: (OnLinkErrorException e) async { - print('onLinkError'); - print(e.message); - }); - - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - final Uri? deepLink = data?.link; - - if (deepLink != null) { - // ignore: unawaited_futures - Navigator.pushNamed(context, deepLink.path); - } - } - - Future _createDynamicLink(bool short) async { - setState(() { - _isCreatingLink = true; - }); - - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://cx4k7.app.goo.gl', - link: Uri.parse('https://dynamic.link.example/helloworld'), - androidParameters: AndroidParameters( - packageName: 'io.flutter.plugins.firebasedynamiclinksexample', - minimumVersion: 0, - ), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), - iosParameters: IosParameters( - bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev', - minimumVersion: '0', - ), - ); - - Uri url; - if (short) { - final ShortDynamicLink shortLink = await parameters.buildShortLink(); - url = shortLink.shortUrl; - } else { - url = await parameters.buildUrl(); - } - - setState(() { - _linkMessage = url.toString(); - _isCreatingLink = false; - }); - } - - @override - Widget build(BuildContext context) { - return Material( - child: Scaffold( - appBar: AppBar( - title: const Text('Dynamic Links Example'), - ), - body: Builder(builder: (BuildContext context) { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ButtonBar( - alignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: !_isCreatingLink - ? () => _createDynamicLink(false) - : null, - child: const Text('Get Long Link'), - ), - ElevatedButton( - onPressed: !_isCreatingLink - ? () => _createDynamicLink(true) - : null, - child: const Text('Get Short Link'), - ), - ], - ), - InkWell( - onTap: () async { - if (_linkMessage != null) { - await launch(_linkMessage!); - } - }, - onLongPress: () { - Clipboard.setData(ClipboardData(text: _linkMessage)); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Copied Link!')), - ); - }, - child: Text( - _linkMessage ?? '', - style: const TextStyle(color: Colors.blue), - ), - ), - Text(_linkMessage == null ? '' : _testString) - ], - ), - ); - }), - ), - ); - } -} - -class _DynamicLinkScreen extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Material( - child: Scaffold( - appBar: AppBar( - title: const Text('Hello World DeepLink'), - ), - body: const Center( - child: Text('Hello, World!'), - ), - ), - ); - } -} diff --git a/packages/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/example/pubspec.yaml deleted file mode 100644 index fcce1b116517..000000000000 --- a/packages/firebase_dynamic_links/example/pubspec.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: firebase_dynamic_links_example -description: Demonstrates how to use the firebase_dynamic_links plugin. - -environment: - sdk: '>=2.12.0 <3.0.0' - flutter: ">=1.12.0" - -dependencies: - firebase_core: - path: ../../firebase_core/firebase_core - firebase_dynamic_links: - path: ../ - flutter: - sdk: flutter - url_launcher: ^6.0.2 - -dependency_overrides: - firebase_core: - path: ../../firebase_core/firebase_core - firebase_core_platform_interface: - path: ../../firebase_core/firebase_core_platform_interface - firebase_core_web: - path: ../../firebase_core/firebase_core_web - -dev_dependencies: - drive: 0.1.0 - flutter_driver: - sdk: flutter - flutter_test: - sdk: flutter - -flutter: - uses-material-design: true diff --git a/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart b/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart deleted file mode 100644 index 91d298d479d0..000000000000 --- a/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart +++ /dev/null @@ -1,73 +0,0 @@ -// ignore_for_file: require_trailing_commas -// @dart = 2.9 -// Copyright 2020, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:drive/drive.dart' as drive; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void testsMain() { - group('DynamicLinks', () { - test('buildUrl', () async { - const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; - const String iosBundleId = - 'com.google.FirebaseCppDynamicLinksTestApp.dev'; - const String urlHost = 'cx4k7.app.goo.gl'; - const String link = 'https://dynamic.link.example/helloworld'; - - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://$urlHost', - link: Uri.parse(link), - androidParameters: AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), - iosParameters: IosParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await parameters.buildUrl(); - - // androidParameters.minimumVersion - expect( - uri.queryParameters['amv'], - '1', - ); - // iosParameters.minimumVersion - expect( - uri.queryParameters['imv'], - '2', - ); - // androidParameters.packageName - expect( - uri.queryParameters['apn'], - androidPackageName, - ); - // iosParameters.bundleId - expect( - uri.queryParameters['ibi'], - iosBundleId, - ); - // link - expect( - uri.queryParameters['link'], - Uri.encodeFull(link), - ); - // uriPrefix - expect( - uri.host, - urlHost, - ); - }); - }); -} - -void main() => drive.main(testsMain); diff --git a/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart b/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart deleted file mode 100644 index 9ea0d073c35e..000000000000 --- a/packages/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart +++ /dev/null @@ -1,9 +0,0 @@ -// ignore_for_file: require_trailing_commas -// @dart = 2.9 -// Copyright 2020, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:drive/drive_driver.dart' as drive; - -void main() => drive.main(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/.gitignore b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/.gitignore new file mode 100644 index 000000000000..2f9ef791f160 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/.gitignore @@ -0,0 +1,76 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ +.metadata + +# 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/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md new file mode 100644 index 000000000000..ea062ddb2331 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0-dev.1 + +- Initial release. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE new file mode 100644 index 000000000000..5b8ff6261110 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE @@ -0,0 +1,26 @@ +Copyright 2017, the Chromium project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/README.md new file mode 100644 index 000000000000..b91dcd77d97e --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/README.md @@ -0,0 +1,26 @@ +# firebase_dynamic_links_platform_interface + +A common platform interface for the [`firebase_dynamic_links`][1] plugin. + +This interface allows platform-specific implementations of the `firebase_dynamic_links` +plugin, as well as the plugin itself, to ensure they are supporting the +same interface. + +## Usage + +To implement a new platform-specific implementation of `firebase_dynamic_links`, extend +[`FirebaseDynamicLinksPlatform`][2] with an implementation that performs the +platform-specific behavior, and when you register your plugin, set the default +`FirebaseDynamicLinksPlatform` by calling +`FirebaseDynamicLinksPlatform.instance = MyDynamicLinks()`. + +## Note on breaking changes + +Strongly prefer non-breaking changes (such as adding a method to the interface) +over breaking changes for this package. + +See https://flutter.dev/go/platform-interface-breaking-changes for a discussion +on why a less-clean interface is preferable to a breaking change. + +[1]: ../firebase_dynamic_links +[2]: lib/firebase_dynamic_links_platform_interface.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart new file mode 100644 index 000000000000..c59aa0f582a4 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -0,0 +1,20 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library firebase_dynamic_links_platform_interface; + +export 'src/platform_interface/platform_interface_firebase_dynamic_links.dart'; +export 'src/pending_dynamic_link_data.dart'; +export 'src/pending_dynamic_link_data_android.dart'; +export 'src/pending_dynamic_link_data_ios.dart'; +export 'src/short_dynamic_link.dart'; +export 'src/short_dynamic_link_path_length.dart'; +export 'src/dynamic_link_parameter_options.dart'; +export 'src/google_analytics_parameters.dart'; +export 'src/ios_parameters.dart'; +export 'src/itunes_connect_analytics_parameters.dart'; +export 'src/navigation_info_parameters.dart'; +export 'src/social_meta_tag_parameters.dart'; +export 'src/android_parameters.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart new file mode 100644 index 000000000000..a7340f76cadc --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -0,0 +1,28 @@ + +/// The Dynamic Link Android parameters. +class AndroidParameters { + const AndroidParameters( + {this.fallbackUrl, this.minimumVersion, required this.packageName}); + + /// The link to open when the app isn’t installed. + /// + /// Specify this to do something other than install the app from the Play + /// Store when the app isn’t installed, such as open the mobile web version of + /// the content, or display a promotional page for the app. + final Uri? fallbackUrl; + + /// The version of the minimum version of your app that can open the link. + /// + /// If the installed app is an older version, the user is taken to the Play + /// Store to upgrade the app. + final int? minimumVersion; + + /// The Android app’s package name. + final String packageName; + + Map get data => { + 'fallbackUrl': fallbackUrl?.toString(), + 'minimumVersion': minimumVersion, + 'packageName': packageName, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart new file mode 100644 index 000000000000..9fb57224449d --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart @@ -0,0 +1,12 @@ +import 'short_dynamic_link_path_length.dart'; +/// Options class for defining how Dynamic Link URLs are generated. +class DynamicLinkParametersOptions { + const DynamicLinkParametersOptions({this.shortDynamicLinkPathLength}); + + /// Specifies the length of the path component of a short Dynamic Link. + final ShortDynamicLinkPathLength? shortDynamicLinkPathLength; + + Map get data => { + 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart new file mode 100644 index 000000000000..7f13f847df1b --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart @@ -0,0 +1,40 @@ +/// The Dynamic Link analytics parameters. +class GoogleAnalyticsParameters { + const GoogleAnalyticsParameters({ + required String this.campaign, + this.content, + required String this.medium, + required String this.source, + this.term, + }); + + GoogleAnalyticsParameters.empty() + : campaign = null, + content = null, + medium = null, + source = null, + term = null; + + /// The utm_campaign analytics parameter. + final String? campaign; + + /// The utm_content analytics parameter. + final String? content; + + /// The utm_medium analytics parameter. + final String? medium; + + /// The utm_source analytics parameter. + final String? source; + + /// The utm_term analytics parameter. + final String? term; + + Map get data => { + 'campaign': campaign, + 'content': content, + 'medium': medium, + 'source': source, + 'term': term, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart new file mode 100644 index 000000000000..515c20fdd1f4 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart @@ -0,0 +1,58 @@ +/// The Dynamic Link iOS parameters. +class IosParameters { + const IosParameters({ + this.appStoreId, + required this.bundleId, + this.customScheme, + this.fallbackUrl, + this.ipadBundleId, + this.ipadFallbackUrl, + this.minimumVersion, + }); + + /// The appStore ID of the iOS app in AppStore. + final String? appStoreId; + + /// The bundle ID of the iOS app to use to open the link. + final String bundleId; + + /// The target app’s custom URL scheme. + /// + /// Defined to be something other than the app’s bundle ID. + final String? customScheme; + + /// The link to open when the app isn’t installed. + /// + /// Specify this to do something other than install the app from the App Store + /// when the app isn’t installed, such as open the mobile web version of the + /// content, or display a promotional page for the app. + final Uri? fallbackUrl; + + /// The bundle ID of the iOS app to use on iPads to open the link. + /// + /// This is only required if there are separate iPhone and iPad applications. + final String? ipadBundleId; + + /// The link to open on iPads when the app isn’t installed. + /// + /// Specify this to do something other than install the app from the App Store + /// when the app isn’t installed, such as open the web version of the content, + /// or display a promotional page for the app. + final Uri? ipadFallbackUrl; + + /// The the minimum version of your app that can open the link. + /// + /// It is app’s developer responsibility to open AppStore when received link + /// declares higher [minimumVersion] than currently installed. + final String? minimumVersion; + + Map get data => { + 'appStoreId': appStoreId, + 'bundleId': bundleId, + 'customScheme': customScheme, + 'fallbackUrl': fallbackUrl?.toString(), + 'ipadBundleId': ipadBundleId, + 'ipadFallbackUrl': ipadFallbackUrl?.toString(), + 'minimumVersion': minimumVersion, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart new file mode 100644 index 000000000000..2136d6de73dc --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -0,0 +1,20 @@ +/// The Dynamic Link iTunes Connect parameters. +class ItunesConnectAnalyticsParameters { + const ItunesConnectAnalyticsParameters( + {this.affiliateToken, this.campaignToken, this.providerToken}); + + /// The iTunes Connect affiliate token. + final String? affiliateToken; + + /// The iTunes Connect campaign token. + final String? campaignToken; + + /// The iTunes Connect provider token. + final String? providerToken; + + Map get data => { + 'affiliateToken': affiliateToken, + 'campaignToken': campaignToken, + 'providerToken': providerToken, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart new file mode 100644 index 000000000000..fb3b546751d5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart @@ -0,0 +1,121 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/platform_interface/platform_interface_dynamic_link_builder.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; + +/// The entry point for accessing a Dynamic Links instance. +/// +/// You can get an instance by calling [FirebaseDynamicLinks.instance]. +class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { + /// Create an instance of [MethodChannelDynamicLinkBuilder] with optional [FirebaseApp] + MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks, { + this.androidParameters, + required this.uriPrefix, + this.dynamicLinkParametersOptions, + this.googleAnalyticsParameters, + this.iosParameters, + this.itunesConnectAnalyticsParameters, + required this.link, + this.navigationInfoParameters, + this.socialMetaTagParameters, + }) : super(dynamicLinks); + + /// Attaches generic default values to method channel arguments. + Map _withChannelDefaults(Map other) { + return { + 'appName': dynamicLinks.app.name, + }..addAll(other); + } + + @override + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + final Map? reply = await MethodChannelFirebaseDynamicLinks + .channel + .invokeMapMethod( + 'DynamicLinkParameters#shortenUrl', + _withChannelDefaults({ + 'url': url.toString(), + 'dynamicLinkParametersOptions': options?.data, + })); + return _parseShortLink(reply!); + } + + @override + Future buildUrl() async { + final String? url = await MethodChannelFirebaseDynamicLinks.channel + .invokeMethod('DynamicLinkParameters#buildUrl', _withChannelDefaults(_data)); + return Uri.parse(url!); + } + + @override + Future buildShortLink() async { + final Map? reply = await MethodChannelFirebaseDynamicLinks.channel + .invokeMapMethod( + 'DynamicLinkParameters#buildShortLink', _withChannelDefaults(_data)); + return _parseShortLink(reply!); + } + + + ShortDynamicLink _parseShortLink(Map reply) { + final List? warnings = reply['warnings']; + return ShortDynamicLink(Uri.parse(reply['url']), warnings?.cast()); + } + + /// Android parameters for a generated Dynamic Link URL. + final AndroidParameters? androidParameters; + + /// Domain URI Prefix of your App. + // This value must be your assigned domain from the Firebase console. + // (e.g. https://xyz.page.link) + // + // The domain URI prefix must start with a valid HTTPS scheme (https://). + final String uriPrefix; + + /// Defines behavior for generating Dynamic Link URLs. + final DynamicLinkParametersOptions? dynamicLinkParametersOptions; + + /// Analytics parameters for a generated Dynamic Link URL. + final GoogleAnalyticsParameters? googleAnalyticsParameters; + + /// iOS parameters for a generated Dynamic Link URL. + final IosParameters? iosParameters; + + /// iTunes Connect parameters for a generated Dynamic Link URL. + final ItunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; + + /// The link the target app will open. + /// + /// You can specify any URL the app can handle, such as a link to the app’s + /// content, or a URL that initiates some app-specific logic such as crediting + /// the user with a coupon, or displaying a specific welcome screen. + /// This link must be a well-formatted URL, be properly URL-encoded, and use + /// the HTTP or HTTPS scheme. + final Uri link; + + /// Navigation Info parameters for a generated Dynamic Link URL. + final NavigationInfoParameters? navigationInfoParameters; + + /// Social Meta Tag parameters for a generated Dynamic Link URL. + final SocialMetaTagParameters? socialMetaTagParameters; + + Map get _data => { + 'androidParameters': androidParameters?.data, + 'uriPrefix': uriPrefix, + 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, + 'googleAnalyticsParameters': googleAnalyticsParameters?.data, + 'iosParameters': iosParameters?.data, + 'itunesConnectAnalyticsParameters': + itunesConnectAnalyticsParameters?.data, + 'link': link.toString(), + 'navigationInfoParameters': navigationInfoParameters?.data, + 'socialMetaTagParameters': socialMetaTagParameters?.data, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart new file mode 100644 index 000000000000..cc99fe95f2fa --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -0,0 +1,147 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/services.dart'; + +import 'utils/exception.dart'; + +/// The entry point for accessing a Dynamic Links instance. +/// +/// You can get an instance by calling [FirebaseDynamicLinks.instance]. +class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { + /// Create an instance of [MethodChannelFirebaseDynamicLinks] with optional [FirebaseApp] + MethodChannelFirebaseDynamicLinks({FirebaseApp? app}) + : super(appInstance: app); + + /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. + /// + /// If null, the default [FirebaseApp] is used. + + /// The [MethodChannel] used to communicate with the native plugin + static MethodChannel channel = const MethodChannel( + 'plugins.flutter.io/firebase_dynamic_links', + ); + + /// The [EventChannel] used for onLink + static EventChannel onLinkChannel(String id) { + return EventChannel( + 'plugins.flutter.io/firebase_dynamic_links/onLink/$id', + channel.codec, + ); + } + + /// Gets a [FirebaseDynamicLinksPlatform] with specific arguments such as a different + /// [FirebaseApp]. + @override + FirebaseDynamicLinksPlatform delegateFor({required FirebaseApp app}) { + return MethodChannelFirebaseDynamicLinks(app: app); + } + + PendingDynamicLinkData? getPendingDynamicLinkDataFromMap( + Map? linkData) { + if (linkData == null) return null; + + final link = linkData['link']; + if (link == null) return null; + + PendingDynamicLinkDataAndroid? androidData; + if (linkData['android'] != null) { + final Map data = linkData['android']; + androidData = PendingDynamicLinkDataAndroid( + data['clickTimestamp'], + data['minimumVersion'], + ); + } + + PendingDynamicLinkDataIOS? iosData; + if (linkData['ios'] != null) { + final Map data = linkData['ios']; + iosData = PendingDynamicLinkDataIOS(data['minimumVersion']); + } + + return PendingDynamicLinkData( + Uri.parse(link), + androidData, + iosData, + ); + } + + @override + Future getInitialLink() async { + final Map? linkData = + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getInitialLink'); + + return getPendingDynamicLinkDataFromMap(linkData); + } + + @override + Future getDynamicLink(Uri url) async { + final Map? linkData = await channel + .invokeMapMethod('FirebaseDynamicLinks#getDynamicLink', + {'url': url.toString()}); + return getPendingDynamicLinkDataFromMap(linkData); + } + + @override + Stream onLink() { + StreamSubscription? snapshotStream; + late StreamController controller; // ignore: close_sinks + + controller = StreamController.broadcast( + onListen: () async { + //TODO setup event channel. Make sure this all works. + final observerId = + await channel.invokeMethod('FirebaseDynamicLinks#onLink'); + + snapshotStream = onLinkChannel(observerId!).receiveBroadcastStream( + { + 'appName': app.name, + }, + ).listen((event) { + controller.add(getPendingDynamicLinkDataFromMap(event)); + }, onError: (error, stack) { + controller.addError(convertPlatformException(error), stack); + }); + }, + onCancel: () { + snapshotStream?.cancel(); + }, + ); + + return controller.stream; + } + + // Future _handleMethod(MethodCall call) async { + // switch (call.method) { + // case 'onLinkSuccess': + // PendingDynamicLinkData? linkData; + // if (call.arguments != null) { + // final Map? data = + // call.arguments.cast(); + // linkData = getPendingDynamicLinkDataFromMap(data); + // } + // return _onLinkSuccess!(linkData); + // case 'onLinkError': + // final Map data = + // call.arguments.cast(); + //TODO use stream handler instead + // final OnLinkErrorException e = OnLinkErrorException._( + // data['code'], data['message'], data['details']); + // return _onLinkError!(e); + // } + // } +} + +//TODO use exception in PI. Remove this. +// /// This object is returned by the handler when an error occurs. +// class OnLinkErrorException extends PlatformException { +// OnLinkErrorException._(String code, String? message, dynamic details) +// : super(code: code, message: message, details: details); +// } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart new file mode 100644 index 000000000000..1099bc9283e5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -0,0 +1,41 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/services.dart'; + +/// Catches a [PlatformException] and returns an [Exception]. +/// +/// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. +Exception convertPlatformException(Object exception) { + if (exception is! Exception || exception is! PlatformException) { + throw exception; + } + + return platformExceptionToFirebaseException(exception); +} + +/// Converts a [PlatformException] into a [FirebaseException]. +/// +/// A [PlatformException] can only be converted to a [FirebaseException] if the +/// `details` of the exception exist. Firebase returns specific codes and messages +/// which can be converted into user friendly exceptions. +FirebaseException platformExceptionToFirebaseException( + PlatformException platformException) { + Map? details = platformException.details != null + ? Map.from(platformException.details) + : null; + + String code = 'unknown'; + String message = platformException.message ?? ''; + + if (details != null) { + code = details['code'] ?? code; + message = details['message'] ?? message; + } + + return FirebaseException( + plugin: 'firebase_dynamic_links', code: code, message: message); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart new file mode 100644 index 000000000000..fdd74c19b57b --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart @@ -0,0 +1,19 @@ +/// Options class for defining navigation behavior of the Dynamic Link. +class NavigationInfoParameters { + const NavigationInfoParameters({this.forcedRedirectEnabled}); + + /// Whether forced non-interactive redirect it to be used. + /// + /// Forced non-interactive redirect occurs when link is tapped on mobile + /// device. + /// + /// Default behavior is to disable force redirect and show interstitial page + /// where user tap will initiate navigation to the App (or AppStore if not + /// installed). Disabled force redirect normally improves reliability of the + /// click. + final bool? forcedRedirectEnabled; + + Map get data => { + 'forcedRedirectEnabled': forcedRedirectEnabled, + }; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart new file mode 100644 index 000000000000..92d7c6b241b9 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -0,0 +1,21 @@ +import 'pending_dynamic_link_data_android.dart'; +import 'pending_dynamic_link_data_ios.dart'; +/// Provides data from received dynamic link. +class PendingDynamicLinkData { + const PendingDynamicLinkData(this.link, this.android, this.ios); + + /// Provides Android specific data from received dynamic link. + /// + /// Can be null if [link] equals null or dynamic link was not received on an + /// Android device. + final PendingDynamicLinkDataAndroid? android; + + /// Provides iOS specific data from received dynamic link. + /// + /// Can be null if [link] equals null or dynamic link was not received on an + /// iOS device. + final PendingDynamicLinkDataIOS? ios; + + /// Deep link parameter of the dynamic link. + final Uri link; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart new file mode 100644 index 000000000000..ad15088278ec --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart @@ -0,0 +1,21 @@ +/// Provides android specific data from received dynamic link. +class PendingDynamicLinkDataAndroid { + const PendingDynamicLinkDataAndroid( + this.clickTimestamp, + this.minimumVersion, + ); + + /// The time the user clicked on the dynamic link. + /// + /// Equals the number of milliseconds that have elapsed since January 1, 1970. + final int? clickTimestamp; + + /// The minimum version of your app that can open the link. + /// + /// The minimum Android app version requested to process the dynamic link that + /// can be compared directly with versionCode. + /// + /// If the installed app is an older version, the user is taken to the Play + /// Store to upgrade the app. + final int? minimumVersion; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart new file mode 100644 index 000000000000..04ad0db88bba --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -0,0 +1,12 @@ +/// Provides iOS specific data from received dynamic link. +class PendingDynamicLinkDataIOS { + const PendingDynamicLinkDataIOS(this.minimumVersion); + + /// The minimum version of your app that can open the link. + /// + /// It is app developer's responsibility to open AppStore when received link + /// declares higher [minimumVersion] than currently installed. + final String? minimumVersion; +} + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart new file mode 100644 index 000000000000..2afbf5ff05cf --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart @@ -0,0 +1,49 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import '../../firebase_dynamic_links_platform_interface.dart'; + +abstract class DynamicLinkBuilderPlatform extends PlatformInterface { + /// Constructor. + DynamicLinkBuilderPlatform(this.dynamicLinks) : super(token: _token); + + /// The [FirebaseAuthPlatform] instance. + final FirebaseDynamicLinksPlatform dynamicLinks; + + static final Object _token = Object(); + + /// Throws an [AssertionError] if [instance] does not extend + /// [DynamicLinkBuilderPlatform]. + /// + /// This is used by the app-facing [DynamicLinkBuilder] to ensure that + /// the object in which it's going to delegate calls has been + /// constructed properly. + static void verifyExtends(DynamicLinkBuilderPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + } + + /// Shortens a Dynamic Link URL. + /// + /// This method may be used for shortening a custom URL that was not generated + /// using [DynamicLinkBuilder]. + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + throw UnimplementedError('shortenUrl() is not implemented'); + } + + /// Generate a long Dynamic Link URL. + Future buildUrl() async { + throw UnimplementedError('buildUrl() is not implemented'); + } + + /// Generate a short Dynamic Link URL. + Future buildShortLink() async { + throw UnimplementedError('buildShortLink() is not implemented'); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart new file mode 100644 index 000000000000..233555b21212 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -0,0 +1,86 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:meta/meta.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import '../../firebase_dynamic_links_platform_interface.dart'; +import '../method_channel/method_channel_firebase_dynamic_links.dart'; + +// import '../persistence_settings.dart'; +// import '../method_channel/method_channel_firestore.dart'; + +/// Defines an interface to work with Dynamic Links across platforms +abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { + /// The [FirebaseApp] this instance was initialized with. + @protected + final FirebaseApp? appInstance; + + /// Create an instance using [app] + FirebaseDynamicLinksPlatform({this.appInstance}) : super(token: _token); + + /// Returns the [FirebaseApp] for the current instance. + FirebaseApp get app { + return appInstance ?? Firebase.app(); + } + + static final Object _token = Object(); + + /// Create an instance using [app] using the existing implementation + factory FirebaseDynamicLinksPlatform.instanceFor({required FirebaseApp app}) { + return FirebaseDynamicLinksPlatform.instance.delegateFor(app: app); + } + + /// The current default [FirebaseDynamicLinksPlatform] instance. + /// + /// It will always default to [MethodChannelFirebaseDynamicLinks] + /// if no other implementation was provided. + static FirebaseDynamicLinksPlatform get instance { + return _instance ??= MethodChannelFirebaseDynamicLinks(app: Firebase.app()); + } + + static FirebaseDynamicLinksPlatform? _instance; + + /// Sets the [FirebaseFirestorePlatform.instance] + static set instance(FirebaseDynamicLinksPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Enables delegates to create new instances of themselves if a none default + /// [FirebaseApp] instance is required by the user. + @protected + FirebaseDynamicLinksPlatform delegateFor({required FirebaseApp app}) { + throw UnimplementedError('delegateFor() is not implemented'); + } + + Future getInitialLink(){ + throw UnimplementedError('getInitialLink() is not implemented'); + } + + Future getDynamicLink(Uri url) async { + throw UnimplementedError('getDynamicLink() is not implemented'); + } + + /// Configures onLink listeners: it has two methods for success and failure. + Stream onLink() { + throw UnimplementedError('onLink() is not implemented'); + } + + @override + //ignore: avoid_equals_and_hash_code_on_mutable_classes + bool operator ==(Object other) => + other is FirebaseDynamicLinksPlatform && other.app.name == app.name; + + @override + //ignore: avoid_equals_and_hash_code_on_mutable_classes + int get hashCode => toString().hashCode; + + @override + String toString() => '$FirebaseDynamicLinksPlatform(app: ${app.name})'; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart new file mode 100644 index 000000000000..c39673aa60c9 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -0,0 +1,10 @@ +/// Response from creating a short dynamic link with [DynamicLinkBuilder]. +class ShortDynamicLink { + const ShortDynamicLink(this.shortUrl, this.warnings); + + /// Short url value. + final Uri shortUrl; + + /// Information about potential warnings on link creation. + final List? warnings; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart new file mode 100644 index 000000000000..5d04fc6e7fcc --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart @@ -0,0 +1,2 @@ +/// For specifying length for short Dynamic Links. +enum ShortDynamicLinkPathLength { unguessable, short } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart new file mode 100644 index 000000000000..3872bb7f11a7 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart @@ -0,0 +1,19 @@ +/// The Dynamic Link Social Meta Tag parameters. +class SocialMetaTagParameters { + SocialMetaTagParameters({this.description, this.imageUrl, this.title}); + + /// The description to use when the Dynamic Link is shared in a social post. + final String? description; + + /// The URL to an image related to this link. + final Uri? imageUrl; + + /// The title to use when the Dynamic Link is shared in a social post. + final String? title; + + Map get data => { + 'description': description, + 'imageUrl': imageUrl?.toString(), + 'title': title, + }; +} diff --git a/packages/firebase_dynamic_links/ios/Assets/.gitkeep b/packages/firebase_dynamic_links/ios/Assets/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h deleted file mode 100644 index f905bbbd03e0..000000000000 --- a/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -@interface FLTFirebaseDynamicLinksPlugin : NSObject -@end diff --git a/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m deleted file mode 100644 index 0831fe6b0a23..000000000000 --- a/packages/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "FLTFirebaseDynamicLinksPlugin.h" - -#import - -static FlutterError *getFlutterError(NSError *error) { - return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code] - message:error.domain - details:error.localizedDescription]; -} - -static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) { - if (dynamicLink != nil) { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - dictionary[@"link"] = dynamicLink.url.absoluteString; - - NSMutableDictionary *iosData = [[NSMutableDictionary alloc] init]; - if (dynamicLink.minimumAppVersion) { - iosData[@"minimumVersion"] = dynamicLink.minimumAppVersion; - } - dictionary[@"ios"] = iosData; - return dictionary; - } else { - return nil; - } -} - -static NSMutableDictionary *getDictionaryFromFlutterError(FlutterError *error) { - if (error == nil) { - return nil; - } - - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - dictionary[@"code"] = error.code; - dictionary[@"message"] = error.message; - dictionary[@"details"] = error.details; - return dictionary; -} - -@interface FLTFirebaseDynamicLinksPlugin () -@property(nonatomic, retain) FlutterMethodChannel *channel; -@property(nonatomic, retain) FIRDynamicLink *initialLink; -@property(nonatomic, retain) FlutterError *flutterError; -@property(nonatomic) BOOL initiated; -@end - -@implementation FLTFirebaseDynamicLinksPlugin -+ (void)registerWithRegistrar:(NSObject *)registrar { - FlutterMethodChannel *channel = - [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/firebase_dynamic_links" - binaryMessenger:[registrar messenger]]; - FLTFirebaseDynamicLinksPlugin *instance = - [[FLTFirebaseDynamicLinksPlugin alloc] initWithChannel:channel]; - [registrar addMethodCallDelegate:instance channel:channel]; - [registrar addApplicationDelegate:instance]; - - SEL sel = NSSelectorFromString(@"registerLibrary:withVersion:"); - if ([FIRApp respondsToSelector:sel]) { - [FIRApp performSelector:sel withObject:LIBRARY_NAME withObject:LIBRARY_VERSION]; - } -} - -- (instancetype)initWithChannel:(FlutterMethodChannel *)channel { - self = [super init]; - if (self) { - _initiated = NO; - _channel = channel; - if (![FIRApp appNamed:@"__FIRAPP_DEFAULT"]) { - NSLog(@"Configuring the default Firebase app..."); - [FIRApp configure]; - NSLog(@"Configured the default Firebase app %@.", [FIRApp defaultApp].name); - } - } - return self; -} - -- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([@"DynamicLinkParameters#buildUrl" isEqualToString:call.method]) { - FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; - result([components.url absoluteString]); - } else if ([@"DynamicLinkParameters#buildShortLink" isEqualToString:call.method]) { - FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; - [components shortenWithCompletion:[self createShortLinkCompletion:result]]; - } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { - FIRDynamicLinkComponentsOptions *options = [self setupOptions:call.arguments]; - NSURL *url = [NSURL URLWithString:call.arguments[@"url"]]; - [FIRDynamicLinkComponents shortenURL:url - options:options - completion:[self createShortLinkCompletion:result]]; - } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { - _initiated = YES; - NSMutableDictionary *dict = [self getInitialLink]; - if (dict == nil && self.flutterError) { - result(self.flutterError); - } else { - result(dict); - } - } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { - NSURL *shortLink = [NSURL URLWithString:call.arguments[@"url"]]; - FIRDynamicLinkUniversalLinkHandler completion = - ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { - if (error) { - result(getFlutterError(error)); - } else { - result(getDictionaryFromDynamicLink(dynamicLink)); - } - }; - [[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion]; - } else { - result(FlutterMethodNotImplemented); - } -} - -- (NSMutableDictionary *)getInitialLink { - return getDictionaryFromDynamicLink(_initialLink); -} - -- (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { - if (_initiated) { - if (error) { - FlutterError *flutterError = getFlutterError(error); - [_channel invokeMethod:@"onLinkError" arguments:getDictionaryFromFlutterError(flutterError)]; - } else { - NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); - [_channel invokeMethod:@"onLinkSuccess" arguments:dictionary]; - } - } else { - if (error) { - _flutterError = getFlutterError(error); - } else if (dynamicLink.url != nil || _initialLink == nil) { - // We'd like to overwrite initial link only if it's - // the first time or if we overwrite it with url that is not nil - _initialLink = dynamicLink; - } - } -} - -- (void)checkForDynamicLink:(NSURL *)url { - FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - if (dynamicLink) { - [self onDeepLinkResult:dynamicLink error:nil]; - } -} - -- (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - options:(NSDictionary *)options { - [self checkForDynamicLink:url]; - // Results of this are ORed and NO doesn't affect other delegate interceptors' result. - return NO; -} - -- (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation { - [self checkForDynamicLink:url]; - // Results of this are ORed and NO doesn't affect other delegate interceptors' result. - return NO; -} - -- (BOOL)application:(UIApplication *)application - continueUserActivity:(NSUserActivity *)userActivity - restorationHandler:(nonnull void (^)(NSArray *_Nullable))restorationHandler { - __block BOOL retried = NO; - void (^completionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); - void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink, - NSError *_Nullable error); - weakCompletionBlock = completionBlock = ^(FIRDynamicLink *_Nullable dynamicLink, - NSError *_Nullable error) { - if (!error && dynamicLink && dynamicLink.url) { - [self onDeepLinkResult:dynamicLink error:nil]; - } - - // Per Apple Tech Support, a network failure could occur when returning from background on - // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 So - // we'll retry the request once - if (error && !retried && [NSPOSIXErrorDomain isEqualToString:error.domain] && - error.code == 53) { - retried = YES; - [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL - completion:weakCompletionBlock]; - } - // We could send this to Dart and maybe have a onDynamicLinkError stream but there's also - // a good chance the `userActivity.webpageURL` might not be for a Firebase dynamic link, - // which needs consideration - so we'll log this for now, logging will get picked up by - // Crashlytics automatically if its integrated. - if (error) - NSLog( - @"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a universal " - @"link: %@", - error); - }; - - [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL - completion:completionBlock]; - - // Results of this are ORed and NO doesn't affect other delegate interceptors' result. - return NO; -} - -- (FIRDynamicLinkShortenerCompletion)createShortLinkCompletion:(FlutterResult)result { - return ^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error) { - if (error) { - result(getFlutterError(error)); - } else { - if (warnings == nil) { - warnings = [NSMutableArray array]; - } - result(@{@"url" : [shortURL absoluteString], @"warnings" : warnings}); - } - }; -} - -- (FIRDynamicLinkComponentsOptions *)setupOptions:(NSDictionary *)arguments { - FIRDynamicLinkComponentsOptions *options; - if (![arguments[@"dynamicLinkParametersOptions"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"dynamicLinkParametersOptions"]; - - options = [FIRDynamicLinkComponentsOptions options]; - - NSNumber *shortDynamicLinkPathLength = params[@"shortDynamicLinkPathLength"]; - if (![shortDynamicLinkPathLength isEqual:[NSNull null]]) { - switch (shortDynamicLinkPathLength.intValue) { - case 0: - options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; - break; - case 1: - options.pathLength = FIRShortDynamicLinkPathLengthShort; - break; - default: - break; - } - } - } - - return options; -} - -- (FIRDynamicLinkComponents *)setupParameters:(NSDictionary *)arguments { - NSURL *link = [NSURL URLWithString:arguments[@"link"]]; - NSString *uriPrefix = arguments[@"uriPrefix"]; - - FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link - domainURIPrefix:uriPrefix]; - - if (![arguments[@"androidParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"androidParameters"]; - - FIRDynamicLinkAndroidParameters *androidParams = - [FIRDynamicLinkAndroidParameters parametersWithPackageName:params[@"packageName"]]; - - NSString *fallbackUrl = params[@"fallbackUrl"]; - NSNumber *minimumVersion = params[@"minimumVersion"]; - - if (![fallbackUrl isEqual:[NSNull null]]) - androidParams.fallbackURL = [NSURL URLWithString:fallbackUrl]; - if (![minimumVersion isEqual:[NSNull null]]) - androidParams.minimumVersion = ((NSNumber *)minimumVersion).integerValue; - - components.androidParameters = androidParams; - } - - if (![arguments[@"dynamicLinkComponentsOptions"] isEqual:[NSNull null]]) { - components.options = [self setupOptions:arguments]; - } - - if (![arguments[@"googleAnalyticsParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"googleAnalyticsParameters"]; - - FIRDynamicLinkGoogleAnalyticsParameters *googleAnalyticsParameters = - [FIRDynamicLinkGoogleAnalyticsParameters parameters]; - - NSString *campaign = params[@"campaign"]; - NSString *content = params[@"content"]; - NSString *medium = params[@"medium"]; - NSString *source = params[@"source"]; - NSString *term = params[@"term"]; - - if (![campaign isEqual:[NSNull null]]) googleAnalyticsParameters.campaign = campaign; - if (![content isEqual:[NSNull null]]) googleAnalyticsParameters.content = content; - if (![medium isEqual:[NSNull null]]) googleAnalyticsParameters.medium = medium; - if (![source isEqual:[NSNull null]]) googleAnalyticsParameters.source = source; - if (![term isEqual:[NSNull null]]) googleAnalyticsParameters.term = term; - - components.analyticsParameters = googleAnalyticsParameters; - } - - if (![arguments[@"iosParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"iosParameters"]; - - FIRDynamicLinkIOSParameters *iosParameters = - [FIRDynamicLinkIOSParameters parametersWithBundleID:params[@"bundleId"]]; - - NSString *appStoreID = params[@"appStoreId"]; - NSString *customScheme = params[@"customScheme"]; - NSString *fallbackURL = params[@"fallbackUrl"]; - NSString *iPadBundleID = params[@"ipadBundleId"]; - NSString *iPadFallbackURL = params[@"ipadFallbackUrl"]; - NSString *minimumAppVersion = params[@"minimumVersion"]; - - if (![appStoreID isEqual:[NSNull null]]) iosParameters.appStoreID = appStoreID; - if (![customScheme isEqual:[NSNull null]]) iosParameters.customScheme = customScheme; - if (![fallbackURL isEqual:[NSNull null]]) - iosParameters.fallbackURL = [NSURL URLWithString:fallbackURL]; - if (![iPadBundleID isEqual:[NSNull null]]) iosParameters.iPadBundleID = iPadBundleID; - if (![iPadFallbackURL isEqual:[NSNull null]]) - iosParameters.iPadFallbackURL = [NSURL URLWithString:iPadFallbackURL]; - if (![minimumAppVersion isEqual:[NSNull null]]) - iosParameters.minimumAppVersion = minimumAppVersion; - - components.iOSParameters = iosParameters; - } - - if (![arguments[@"itunesConnectAnalyticsParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"itunesConnectAnalyticsParameters"]; - - FIRDynamicLinkItunesConnectAnalyticsParameters *itunesConnectAnalyticsParameters = - [FIRDynamicLinkItunesConnectAnalyticsParameters parameters]; - - NSString *affiliateToken = params[@"affiliateToken"]; - NSString *campaignToken = params[@"campaignToken"]; - NSString *providerToken = params[@"providerToken"]; - - if (![affiliateToken isEqual:[NSNull null]]) - itunesConnectAnalyticsParameters.affiliateToken = affiliateToken; - if (![campaignToken isEqual:[NSNull null]]) - itunesConnectAnalyticsParameters.campaignToken = campaignToken; - if (![providerToken isEqual:[NSNull null]]) - itunesConnectAnalyticsParameters.providerToken = providerToken; - - components.iTunesConnectParameters = itunesConnectAnalyticsParameters; - } - - if (![arguments[@"navigationInfoParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"navigationInfoParameters"]; - - FIRDynamicLinkNavigationInfoParameters *navigationInfoParameters = - [FIRDynamicLinkNavigationInfoParameters parameters]; - - NSNumber *forcedRedirectEnabled = params[@"forcedRedirectEnabled"]; - if (![forcedRedirectEnabled isEqual:[NSNull null]]) - navigationInfoParameters.forcedRedirectEnabled = [forcedRedirectEnabled boolValue]; - - components.navigationInfoParameters = navigationInfoParameters; - } - - if (![arguments[@"socialMetaTagParameters"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"socialMetaTagParameters"]; - - FIRDynamicLinkSocialMetaTagParameters *socialMetaTagParameters = - [FIRDynamicLinkSocialMetaTagParameters parameters]; - - NSString *descriptionText = params[@"description"]; - NSString *imageURL = params[@"imageUrl"]; - NSString *title = params[@"title"]; - - if (![descriptionText isEqual:[NSNull null]]) - socialMetaTagParameters.descriptionText = descriptionText; - if (![imageURL isEqual:[NSNull null]]) - socialMetaTagParameters.imageURL = [NSURL URLWithString:imageURL]; - if (![title isEqual:[NSNull null]]) socialMetaTagParameters.title = title; - - components.socialMetaTagParameters = socialMetaTagParameters; - } - - return components; -} - -@end diff --git a/packages/firebase_dynamic_links/ios/firebase_dynamic_links.podspec b/packages/firebase_dynamic_links/ios/firebase_dynamic_links.podspec deleted file mode 100644 index ec91d04c6800..000000000000 --- a/packages/firebase_dynamic_links/ios/firebase_dynamic_links.podspec +++ /dev/null @@ -1,39 +0,0 @@ -require 'yaml' - -pubspec = YAML.load_file(File.join('..', 'pubspec.yaml')) -library_version = pubspec['version'].gsub('+', '-') - -if defined?($FirebaseSDKVersion) - Pod::UI.puts "#{pubspec['name']}: Using user specified Firebase SDK version '#{$FirebaseSDKVersion}'" - firebase_sdk_version = $FirebaseSDKVersion -else - firebase_core_script = File.join(File.expand_path('..', File.expand_path('..', File.dirname(__FILE__))), 'firebase_core/ios/firebase_sdk_version.rb') - if File.exist?(firebase_core_script) - require firebase_core_script - firebase_sdk_version = firebase_sdk_version! - Pod::UI.puts "#{pubspec['name']}: Using Firebase SDK version '#{firebase_sdk_version}' defined in 'firebase_core'" - end -end - -Pod::Spec.new do |s| - s.name = pubspec['name'] - s.version = library_version - s.summary = pubspec['description'] - s.description = pubspec['description'] - s.homepage = pubspec['homepage'] - s.license = { :file => '../LICENSE' } - s.author = 'The Chromium Authors' - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - s.ios.deployment_target = '10.0' - s.static_framework = true - s.dependency 'firebase_core' - s.dependency 'Firebase/DynamicLinks', firebase_sdk_version - - s.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => "LIBRARY_VERSION=\\@\\\"#{library_version}\\\" LIBRARY_NAME=\\@\\\"flutter-fire-dl\\\"", - 'DEFINES_MODULE' => 'YES' - } -end diff --git a/packages/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/lib/firebase_dynamic_links.dart deleted file mode 100644 index e5953b1b37e3..000000000000 --- a/packages/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ /dev/null @@ -1,14 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -library firebase_dynamic_links; - -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; - -part 'src/dynamic_link_parameters.dart'; -part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/lib/src/dynamic_link_parameters.dart deleted file mode 100644 index 5b9b69949755..000000000000 --- a/packages/firebase_dynamic_links/lib/src/dynamic_link_parameters.dart +++ /dev/null @@ -1,325 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -part of firebase_dynamic_links; - -/// The class used for Dynamic Link URL generation. -/// -/// Supports creation of short and long Dynamic Link URLs. Short URLs will have -/// a domain and a randomized path. Long URLs will have a domain and a query -/// that contains all of the Dynamic Link parameters. -class DynamicLinkParameters { - DynamicLinkParameters({ - this.androidParameters, - required this.uriPrefix, - this.dynamicLinkParametersOptions, - this.googleAnalyticsParameters, - this.iosParameters, - this.itunesConnectAnalyticsParameters, - required this.link, - this.navigationInfoParameters, - this.socialMetaTagParameters, - }); - - /// Android parameters for a generated Dynamic Link URL. - final AndroidParameters? androidParameters; - - /// Domain URI Prefix of your App. - // This value must be your assigned domain from the Firebase console. - // (e.g. https://xyz.page.link) - // - // The domain URI prefix must start with a valid HTTPS scheme (https://). - final String uriPrefix; - - /// Defines behavior for generating Dynamic Link URLs. - final DynamicLinkParametersOptions? dynamicLinkParametersOptions; - - /// Analytics parameters for a generated Dynamic Link URL. - final GoogleAnalyticsParameters? googleAnalyticsParameters; - - /// iOS parameters for a generated Dynamic Link URL. - final IosParameters? iosParameters; - - /// iTunes Connect parameters for a generated Dynamic Link URL. - final ItunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; - - /// The link the target app will open. - /// - /// You can specify any URL the app can handle, such as a link to the app’s - /// content, or a URL that initiates some app-specific logic such as crediting - /// the user with a coupon, or displaying a specific welcome screen. - /// This link must be a well-formatted URL, be properly URL-encoded, and use - /// the HTTP or HTTPS scheme. - final Uri link; - - /// Navigation Info parameters for a generated Dynamic Link URL. - final NavigationInfoParameters? navigationInfoParameters; - - /// Social Meta Tag parameters for a generated Dynamic Link URL. - final SocialMetaTagParameters? socialMetaTagParameters; - - /// Shortens a Dynamic Link URL. - /// - /// This method may be used for shortening a custom URL that was not generated - /// using [DynamicLinkParameters]. - static Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { - final Map? reply = await FirebaseDynamicLinks.channel - .invokeMapMethod( - 'DynamicLinkParameters#shortenUrl', { - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?._data, - }); - return _parseShortLink(reply!); - } - - Map get _data => { - 'androidParameters': androidParameters?._data, - 'uriPrefix': uriPrefix, - 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?._data, - 'googleAnalyticsParameters': googleAnalyticsParameters?._data, - 'iosParameters': iosParameters?._data, - 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?._data, - 'link': link.toString(), - 'navigationInfoParameters': navigationInfoParameters?._data, - 'socialMetaTagParameters': socialMetaTagParameters?._data, - }; - - /// Generate a long Dynamic Link URL. - Future buildUrl() async { - final String? url = await FirebaseDynamicLinks.channel - .invokeMethod('DynamicLinkParameters#buildUrl', _data); - return Uri.parse(url!); - } - - /// Generate a short Dynamic Link. - Future buildShortLink() async { - final Map? reply = await FirebaseDynamicLinks.channel - .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', _data); - return _parseShortLink(reply!); - } - - static ShortDynamicLink _parseShortLink(Map reply) { - final List? warnings = reply['warnings']; - return ShortDynamicLink._(Uri.parse(reply['url']), warnings?.cast()); - } -} - -/// Response from creating a short dynamic link with [DynamicLinkParameters]. -class ShortDynamicLink { - ShortDynamicLink._(this.shortUrl, this.warnings); - - /// Short url value. - final Uri shortUrl; - - /// Information about potential warnings on link creation. - final List? warnings; -} - -/// The Dynamic Link Android parameters. -class AndroidParameters { - AndroidParameters( - {this.fallbackUrl, this.minimumVersion, required this.packageName}); - - /// The link to open when the app isn’t installed. - /// - /// Specify this to do something other than install the app from the Play - /// Store when the app isn’t installed, such as open the mobile web version of - /// the content, or display a promotional page for the app. - final Uri? fallbackUrl; - - /// The version of the minimum version of your app that can open the link. - /// - /// If the installed app is an older version, the user is taken to the Play - /// Store to upgrade the app. - final int? minimumVersion; - - /// The Android app’s package name. - final String packageName; - - Map get _data => { - 'fallbackUrl': fallbackUrl?.toString(), - 'minimumVersion': minimumVersion, - 'packageName': packageName, - }; -} - -/// For specifying length for short Dynamic Links. -enum ShortDynamicLinkPathLength { unguessable, short } - -/// Options class for defining how Dynamic Link URLs are generated. -class DynamicLinkParametersOptions { - DynamicLinkParametersOptions({this.shortDynamicLinkPathLength}); - - /// Specifies the length of the path component of a short Dynamic Link. - final ShortDynamicLinkPathLength? shortDynamicLinkPathLength; - - Map get _data => { - 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, - }; -} - -/// The Dynamic Link analytics parameters. -class GoogleAnalyticsParameters { - GoogleAnalyticsParameters({ - required String this.campaign, - this.content, - required String this.medium, - required String this.source, - this.term, - }); - - GoogleAnalyticsParameters.empty() - : campaign = null, - content = null, - medium = null, - source = null, - term = null; - - /// The utm_campaign analytics parameter. - final String? campaign; - - /// The utm_content analytics parameter. - final String? content; - - /// The utm_medium analytics parameter. - final String? medium; - - /// The utm_source analytics parameter. - final String? source; - - /// The utm_term analytics parameter. - final String? term; - - Map get _data => { - 'campaign': campaign, - 'content': content, - 'medium': medium, - 'source': source, - 'term': term, - }; -} - -/// The Dynamic Link iOS parameters. -class IosParameters { - IosParameters({ - this.appStoreId, - required this.bundleId, - this.customScheme, - this.fallbackUrl, - this.ipadBundleId, - this.ipadFallbackUrl, - this.minimumVersion, - }); - - /// The appStore ID of the iOS app in AppStore. - final String? appStoreId; - - /// The bundle ID of the iOS app to use to open the link. - final String bundleId; - - /// The target app’s custom URL scheme. - /// - /// Defined to be something other than the app’s bundle ID. - final String? customScheme; - - /// The link to open when the app isn’t installed. - /// - /// Specify this to do something other than install the app from the App Store - /// when the app isn’t installed, such as open the mobile web version of the - /// content, or display a promotional page for the app. - final Uri? fallbackUrl; - - /// The bundle ID of the iOS app to use on iPads to open the link. - /// - /// This is only required if there are separate iPhone and iPad applications. - final String? ipadBundleId; - - /// The link to open on iPads when the app isn’t installed. - /// - /// Specify this to do something other than install the app from the App Store - /// when the app isn’t installed, such as open the web version of the content, - /// or display a promotional page for the app. - final Uri? ipadFallbackUrl; - - /// The the minimum version of your app that can open the link. - /// - /// It is app’s developer responsibility to open AppStore when received link - /// declares higher [minimumVersion] than currently installed. - final String? minimumVersion; - - Map get _data => { - 'appStoreId': appStoreId, - 'bundleId': bundleId, - 'customScheme': customScheme, - 'fallbackUrl': fallbackUrl?.toString(), - 'ipadBundleId': ipadBundleId, - 'ipadFallbackUrl': ipadFallbackUrl?.toString(), - 'minimumVersion': minimumVersion, - }; -} - -/// The Dynamic Link iTunes Connect parameters. -class ItunesConnectAnalyticsParameters { - ItunesConnectAnalyticsParameters( - {this.affiliateToken, this.campaignToken, this.providerToken}); - - /// The iTunes Connect affiliate token. - final String? affiliateToken; - - /// The iTunes Connect campaign token. - final String? campaignToken; - - /// The iTunes Connect provider token. - final String? providerToken; - - Map get _data => { - 'affiliateToken': affiliateToken, - 'campaignToken': campaignToken, - 'providerToken': providerToken, - }; -} - -/// Options class for defining navigation behavior of the Dynamic Link. -class NavigationInfoParameters { - NavigationInfoParameters({this.forcedRedirectEnabled}); - - /// Whether forced non-interactive redirect it to be used. - /// - /// Forced non-interactive redirect occurs when link is tapped on mobile - /// device. - /// - /// Default behavior is to disable force redirect and show interstitial page - /// where user tap will initiate navigation to the App (or AppStore if not - /// installed). Disabled force redirect normally improves reliability of the - /// click. - final bool? forcedRedirectEnabled; - - Map get _data => { - 'forcedRedirectEnabled': forcedRedirectEnabled, - }; -} - -/// The Dynamic Link Social Meta Tag parameters. -class SocialMetaTagParameters { - SocialMetaTagParameters({this.description, this.imageUrl, this.title}); - - /// The description to use when the Dynamic Link is shared in a social post. - final String? description; - - /// The URL to an image related to this link. - final Uri? imageUrl; - - /// The title to use when the Dynamic Link is shared in a social post. - final String? title; - - Map get _data => { - 'description': description, - 'imageUrl': imageUrl?.toString(), - 'title': title, - }; -} diff --git a/packages/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart deleted file mode 100644 index 02a296129106..000000000000 --- a/packages/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ /dev/null @@ -1,164 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -part of firebase_dynamic_links; - -typedef OnLinkSuccessCallback = Future Function( - PendingDynamicLinkData? linkData); -typedef OnLinkErrorCallback = Future Function( - OnLinkErrorException error); - -/// Firebase Dynamic Links API. -/// -/// You can get an instance by calling [FirebaseDynamicLinks.instance]. -class FirebaseDynamicLinks { - FirebaseDynamicLinks._(); - - @visibleForTesting - static const MethodChannel channel = - MethodChannel('plugins.flutter.io/firebase_dynamic_links'); - - /// Singleton of [FirebaseDynamicLinks]. - static final FirebaseDynamicLinks instance = FirebaseDynamicLinks._(); - - OnLinkSuccessCallback? _onLinkSuccess; - OnLinkErrorCallback? _onLinkError; - - /// Attempts to retrieve the dynamic link which launched the app. - /// - /// This method always returns a Future. That Future completes to null if - /// there is no pending dynamic link or any call to this method after the - /// the first attempt. - Future getInitialLink() async { - final Map? linkData = - await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink'); - return getPendingDynamicLinkDataFromMap(linkData); - } - - Future getDynamicLink(Uri url) async { - final Map? linkData = await FirebaseDynamicLinks.channel - .invokeMapMethod('FirebaseDynamicLinks#getDynamicLink', - {'url': url.toString()}); - return getPendingDynamicLinkDataFromMap(linkData); - } - - PendingDynamicLinkData? getPendingDynamicLinkDataFromMap( - Map? linkData) { - if (linkData == null) return null; - - final link = linkData['link']; - if (link == null) return null; - - PendingDynamicLinkDataAndroid? androidData; - if (linkData['android'] != null) { - final Map data = linkData['android']; - androidData = PendingDynamicLinkDataAndroid._( - data['clickTimestamp'], - data['minimumVersion'], - ); - } - - PendingDynamicLinkDataIOS? iosData; - if (linkData['ios'] != null) { - final Map data = linkData['ios']; - iosData = PendingDynamicLinkDataIOS._(data['minimumVersion']); - } - - return PendingDynamicLinkData._( - Uri.parse(link), - androidData, - iosData, - ); - } - - /// Configures onLink listeners: it has two methods for success and failure. - void onLink({ - OnLinkSuccessCallback? onSuccess, - OnLinkErrorCallback? onError, - }) { - _onLinkSuccess = onSuccess; - _onLinkError = onError; - channel.setMethodCallHandler(_handleMethod); - } - - Future _handleMethod(MethodCall call) async { - switch (call.method) { - case 'onLinkSuccess': - PendingDynamicLinkData? linkData; - if (call.arguments != null) { - final Map? data = - call.arguments.cast(); - linkData = getPendingDynamicLinkDataFromMap(data); - } - return _onLinkSuccess!(linkData); - case 'onLinkError': - final Map data = - call.arguments.cast(); - final OnLinkErrorException e = OnLinkErrorException._( - data['code'], data['message'], data['details']); - return _onLinkError!(e); - } - } -} - -/// Provides data from received dynamic link. -class PendingDynamicLinkData { - PendingDynamicLinkData._(this.link, this.android, this.ios); - - /// Provides Android specific data from received dynamic link. - /// - /// Can be null if [link] equals null or dynamic link was not received on an - /// Android device. - final PendingDynamicLinkDataAndroid? android; - - /// Provides iOS specific data from received dynamic link. - /// - /// Can be null if [link] equals null or dynamic link was not received on an - /// iOS device. - final PendingDynamicLinkDataIOS? ios; - - /// Deep link parameter of the dynamic link. - final Uri link; -} - -/// Provides android specific data from received dynamic link. -class PendingDynamicLinkDataAndroid { - PendingDynamicLinkDataAndroid._( - this.clickTimestamp, - this.minimumVersion, - ); - - /// The time the user clicked on the dynamic link. - /// - /// Equals the number of milliseconds that have elapsed since January 1, 1970. - final int? clickTimestamp; - - /// The minimum version of your app that can open the link. - /// - /// The minimum Android app version requested to process the dynamic link that - /// can be compared directly with versionCode. - /// - /// If the installed app is an older version, the user is taken to the Play - /// Store to upgrade the app. - final int? minimumVersion; -} - -/// Provides iOS specific data from received dynamic link. -class PendingDynamicLinkDataIOS { - PendingDynamicLinkDataIOS._(this.minimumVersion); - - /// The minimum version of your app that can open the link. - /// - /// It is app developer's responsibility to open AppStore when received link - /// declares higher [minimumVersion] than currently installed. - final String? minimumVersion; -} - -/// This object is returned by the handler when an error occurs. -class OnLinkErrorException extends PlatformException { - OnLinkErrorException._(String code, String? message, dynamic details) - : super(code: code, message: message, details: details); -} diff --git a/packages/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/pubspec.yaml deleted file mode 100644 index ff704c7b4498..000000000000 --- a/packages/firebase_dynamic_links/pubspec.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: firebase_dynamic_links -description: - Flutter plugin for Google Dynamic Links for Firebase, an app solution for creating - and handling links across multiple platforms. -version: 2.0.11 -homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links -repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links - -environment: - sdk: '>=2.12.0 <3.0.0' - flutter: ">=1.12.13+hotfix.5" - -dependencies: - firebase_core: ^1.8.0 - flutter: - sdk: flutter - -dev_dependencies: - flutter_test: - sdk: flutter - url_launcher: ^6.0.2 - -flutter: - plugin: - platforms: - android: - package: io.flutter.plugins.firebasedynamiclinks - pluginClass: FirebaseDynamicLinksPlugin - ios: - pluginClass: FLTFirebaseDynamicLinksPlugin diff --git a/packages/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/test/firebase_dynamic_links_test.dart deleted file mode 100644 index 8e193cd8c2a1..000000000000 --- a/packages/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ /dev/null @@ -1,675 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; - -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - group('$FirebaseDynamicLinks', () { - final List log = []; - - setUp(() { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - final Map returnUrl = { - 'url': 'google.com', - 'warnings': ['This is only a test link'], - }; - switch (methodCall.method) { - case 'DynamicLinkParameters#buildUrl': - return 'google.com'; - case 'DynamicLinkParameters#buildShortLink': - return returnUrl; - case 'DynamicLinkParameters#shortenUrl': - return returnUrl; - case 'FirebaseDynamicLinks#getInitialLink': - return { - 'link': 'https://google.com', - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }; - case 'FirebaseDynamicLinks#getDynamicLink': - return { - 'link': 'https://google.com', - }; - default: - return null; - } - }); - log.clear(); - }); - - group('getInitialLink', () { - test('link can be parsed', () async { - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - expect(data!.link, Uri.parse('https://google.com')); - - expect(data.android!.clickTimestamp, 1234567); - expect(data.android!.minimumVersion, 12); - - expect(data.ios!.minimumVersion, 'Version 12'); - - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); - }); - - // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() - // might return null link. In such a case we want to ignore the deep-link. - test('for null link, returns null', () async { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - switch (methodCall.method) { - case 'FirebaseDynamicLinks#getInitialLink': - return { - 'link': null, - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }; - default: - return null; - } - }); - - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - expect(data, isNull); - - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); - }); - - test('for null result, returns null', () async { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - switch (methodCall.method) { - case 'FirebaseDynamicLinks#getInitialLink': - return null; - default: - return null; - } - }); - - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - expect(data, isNull); - - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); - }); - }); - - test('getDynamicLink', () async { - final Uri argument = Uri.parse('short-link'); - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getDynamicLink(argument); - - expect(data!.link.host, 'google.com'); - - expect(log, [ - isMethodCall('FirebaseDynamicLinks#getDynamicLink', - arguments: { - 'url': argument.toString(), - }) - ]); - }); - - group('$DynamicLinkParameters', () { - test('shortenUrl', () async { - final Uri url = Uri.parse('google.com'); - final DynamicLinkParametersOptions options = - DynamicLinkParametersOptions( - shortDynamicLinkPathLength: - ShortDynamicLinkPathLength.unguessable); - - await DynamicLinkParameters.shortenUrl(url, options); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#shortenUrl', - arguments: { - 'url': url.toString(), - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, - }, - ), - ]); - }); - - test('$AndroidParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - androidParameters: AndroidParameters( - fallbackUrl: Uri.parse('test-url'), - minimumVersion: 1, - packageName: 'test-package', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': { - 'fallbackUrl': 'test-url', - 'minimumVersion': 1, - 'packageName': 'test-package', - }, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': { - 'fallbackUrl': 'test-url', - 'minimumVersion': 1, - 'packageName': 'test-package', - }, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$DynamicLinkParametersOptions', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.short.index, - }, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.short.index, - }, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$ShortDynamicLinkPathLength', () { - expect(ShortDynamicLinkPathLength.unguessable.index, 0); - expect(ShortDynamicLinkPathLength.short.index, 1); - }); - - test('$GoogleAnalyticsParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'where', - content: 'is', - medium: 'my', - source: 'cat', - term: 'friend', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': { - 'campaign': 'where', - 'content': 'is', - 'medium': 'my', - 'source': 'cat', - 'term': 'friend', - }, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': { - 'campaign': 'where', - 'content': 'is', - 'medium': 'my', - 'source': 'cat', - 'term': 'friend', - }, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$IosParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - iosParameters: IosParameters( - appStoreId: 'is', - bundleId: 'this', - customScheme: 'the', - fallbackUrl: Uri.parse('place'), - ipadBundleId: 'to', - ipadFallbackUrl: Uri.parse('find'), - minimumVersion: 'potatoes', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': { - 'appStoreId': 'is', - 'bundleId': 'this', - 'customScheme': 'the', - 'fallbackUrl': 'place', - 'ipadBundleId': 'to', - 'ipadFallbackUrl': 'find', - 'minimumVersion': 'potatoes', - }, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': { - 'appStoreId': 'is', - 'bundleId': 'this', - 'customScheme': 'the', - 'fallbackUrl': 'place', - 'ipadBundleId': 'to', - 'ipadFallbackUrl': 'find', - 'minimumVersion': 'potatoes', - }, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$ItunesConnectAnalyticsParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - affiliateToken: 'hello', - campaignToken: 'mister', - providerToken: 'rose', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'hello', - 'campaignToken': 'mister', - 'providerToken': 'rose', - }, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'hello', - 'campaignToken': 'mister', - 'providerToken': 'rose', - }, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$NavigationInfoParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - navigationInfoParameters: - NavigationInfoParameters(forcedRedirectEnabled: true), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$SocialMetaTagParameters', () async { - final DynamicLinkParameters components = DynamicLinkParameters( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - socialMetaTagParameters: SocialMetaTagParameters( - description: 'describe', - imageUrl: Uri.parse('thisimage'), - title: 'bro', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': { - 'description': 'describe', - 'imageUrl': 'thisimage', - 'title': 'bro', - }, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': { - 'description': 'describe', - 'imageUrl': 'thisimage', - 'title': 'bro', - }, - }, - ), - ]); - }); - }); - - group('onLink', () { - OnLinkSuccessCallback? onSuccess; - OnLinkErrorCallback? onError; - final List successLog = - []; - final List errorLog = []; - setUp(() { - onSuccess = (linkData) async { - successLog.add(linkData); - }; - onError = (error) async { - errorLog.add(error); - }; - successLog.clear(); - errorLog.clear(); - }); - - Future callMethodHandler(String method, dynamic arguments) { - const channel = FirebaseDynamicLinks.channel; - final methodCall = MethodCall(method, arguments); - final data = channel.codec.encodeMethodCall(methodCall); - final Completer completer = Completer(); - channel.binaryMessenger.handlePlatformMessage( - channel.name, - data, - (data) { - completer.complete(null); - }, - ); - return completer.future; - } - - test('onSuccess', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', { - 'link': 'https://google.com', - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }); - - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]!; - - expect(success.link, Uri.parse('https://google.com')); - - expect(success.android!.clickTimestamp, 1234567); - expect(success.android!.minimumVersion, 12); - - expect(success.ios!.minimumVersion, 'Version 12'); - }); - - test('onSuccess with null link', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', { - 'link': null, - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }); - - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]; - - expect(success, isNull); - }); - - test('onSuccess with null', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', null); - - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]; - - expect(success, isNull); - }); - - test('onError', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkError', { - 'code': 'code', - 'message': 'message', - 'details': 'details', - }); - - expect(successLog, hasLength(0)); - expect(errorLog, hasLength(1)); - final failure = errorLog[0]; - expect(failure.code, 'code'); - expect(failure.message, 'message'); - expect(failure.details, 'details'); - }); - }); - }); -} From 7ba3e5ad4e17d2bd22e6aacd805c4314291d33ab Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 28 Oct 2021 11:12:44 +0100 Subject: [PATCH 002/125] refactor(dynamic_links): separate link builder from params --- ...base_dynamic_links_platform_interface.dart | 2 + .../src/build_dynamic_link_parameters.dart | 81 +++++++++++++++++++ .../method_channel_dynamic_link_builder.dart | 74 ++--------------- ...method_channel_firebase_dynamic_links.dart | 6 ++ ...atform_interface_dynamic_link_builder.dart | 4 +- ...form_interface_firebase_dynamic_links.dart | 5 ++ 6 files changed, 101 insertions(+), 71 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart index c59aa0f582a4..1bd734a4f798 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -6,6 +6,7 @@ library firebase_dynamic_links_platform_interface; export 'src/platform_interface/platform_interface_firebase_dynamic_links.dart'; +export 'src/platform_interface/platform_interface_dynamic_link_builder.dart'; export 'src/pending_dynamic_link_data.dart'; export 'src/pending_dynamic_link_data_android.dart'; export 'src/pending_dynamic_link_data_ios.dart'; @@ -18,3 +19,4 @@ export 'src/itunes_connect_analytics_parameters.dart'; export 'src/navigation_info_parameters.dart'; export 'src/social_meta_tag_parameters.dart'; export 'src/android_parameters.dart'; +export 'src/build_dynamic_link_parameters.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart new file mode 100644 index 000000000000..8801cda42f22 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart @@ -0,0 +1,81 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; + +import '../firebase_dynamic_links_platform_interface.dart'; + +/// Interface that defines the all the parameters required to build a dynamic link +class BuildDynamicLinkParameters { + // ignore: public_member_api_docs + @protected + BuildDynamicLinkParameters({ + this.androidParameters, + required this.uriPrefix, + this.dynamicLinkParametersOptions, + this.googleAnalyticsParameters, + this.iosParameters, + this.itunesConnectAnalyticsParameters, + required this.link, + this.navigationInfoParameters, + this.socialMetaTagParameters, + }); + + /// Android parameters for a generated Dynamic Link URL. + final AndroidParameters? androidParameters; + + /// Domain URI Prefix of your App. + // This value must be your assigned domain from the Firebase console. + // (e.g. https://xyz.page.link) + // + // The domain URI prefix must start with a valid HTTPS scheme (https://). + final String uriPrefix; + + /// Defines behavior for generating Dynamic Link URLs. + final DynamicLinkParametersOptions? dynamicLinkParametersOptions; + + /// Analytics parameters for a generated Dynamic Link URL. + final GoogleAnalyticsParameters? googleAnalyticsParameters; + + /// iOS parameters for a generated Dynamic Link URL. + final IosParameters? iosParameters; + + /// iTunes Connect parameters for a generated Dynamic Link URL. + final ItunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; + + /// The link the target app will open. + /// + /// You can specify any URL the app can handle, such as a link to the app’s + /// content, or a URL that initiates some app-specific logic such as crediting + /// the user with a coupon, or displaying a specific welcome screen. + /// This link must be a well-formatted URL, be properly URL-encoded, and use + /// the HTTP or HTTPS scheme. + final Uri link; + + /// Navigation Info parameters for a generated Dynamic Link URL. + final NavigationInfoParameters? navigationInfoParameters; + + /// Social Meta Tag parameters for a generated Dynamic Link URL. + final SocialMetaTagParameters? socialMetaTagParameters; + + /// Returns the current instance as a [Map]. + Map asMap() => { + 'androidParameters': androidParameters?.data, + 'uriPrefix': uriPrefix, + 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, + 'googleAnalyticsParameters': googleAnalyticsParameters?.data, + 'iosParameters': iosParameters?.data, + 'itunesConnectAnalyticsParameters': + itunesConnectAnalyticsParameters?.data, + 'link': link.toString(), + 'navigationInfoParameters': navigationInfoParameters?.data, + 'socialMetaTagParameters': socialMetaTagParameters?.data, + }; + + @override + String toString() { + return '$BuildDynamicLinkParameters($asMap)'; + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart index fb3b546751d5..9bdbb0abbcd2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart @@ -10,22 +10,8 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/src/platform_interface/platform_interface_dynamic_link_builder.dart'; import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; -/// The entry point for accessing a Dynamic Links instance. -/// -/// You can get an instance by calling [FirebaseDynamicLinks.instance]. class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { - /// Create an instance of [MethodChannelDynamicLinkBuilder] with optional [FirebaseApp] - MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks, { - this.androidParameters, - required this.uriPrefix, - this.dynamicLinkParametersOptions, - this.googleAnalyticsParameters, - this.iosParameters, - this.itunesConnectAnalyticsParameters, - required this.link, - this.navigationInfoParameters, - this.socialMetaTagParameters, - }) : super(dynamicLinks); + MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks) : super(dynamicLinks); /// Attaches generic default values to method channel arguments. Map _withChannelDefaults(Map other) { @@ -49,17 +35,17 @@ class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { } @override - Future buildUrl() async { + Future buildUrl(BuildDynamicLinkParameters parameters) async { final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('DynamicLinkParameters#buildUrl', _withChannelDefaults(_data)); + .invokeMethod('DynamicLinkParameters#buildUrl', _withChannelDefaults(parameters.asMap())); return Uri.parse(url!); } @override - Future buildShortLink() async { + Future buildShortLink(BuildDynamicLinkParameters parameters) async { final Map? reply = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', _withChannelDefaults(_data)); + 'DynamicLinkParameters#buildShortLink', _withChannelDefaults(parameters.asMap())); return _parseShortLink(reply!); } @@ -68,54 +54,4 @@ class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { final List? warnings = reply['warnings']; return ShortDynamicLink(Uri.parse(reply['url']), warnings?.cast()); } - - /// Android parameters for a generated Dynamic Link URL. - final AndroidParameters? androidParameters; - - /// Domain URI Prefix of your App. - // This value must be your assigned domain from the Firebase console. - // (e.g. https://xyz.page.link) - // - // The domain URI prefix must start with a valid HTTPS scheme (https://). - final String uriPrefix; - - /// Defines behavior for generating Dynamic Link URLs. - final DynamicLinkParametersOptions? dynamicLinkParametersOptions; - - /// Analytics parameters for a generated Dynamic Link URL. - final GoogleAnalyticsParameters? googleAnalyticsParameters; - - /// iOS parameters for a generated Dynamic Link URL. - final IosParameters? iosParameters; - - /// iTunes Connect parameters for a generated Dynamic Link URL. - final ItunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; - - /// The link the target app will open. - /// - /// You can specify any URL the app can handle, such as a link to the app’s - /// content, or a URL that initiates some app-specific logic such as crediting - /// the user with a coupon, or displaying a specific welcome screen. - /// This link must be a well-formatted URL, be properly URL-encoded, and use - /// the HTTP or HTTPS scheme. - final Uri link; - - /// Navigation Info parameters for a generated Dynamic Link URL. - final NavigationInfoParameters? navigationInfoParameters; - - /// Social Meta Tag parameters for a generated Dynamic Link URL. - final SocialMetaTagParameters? socialMetaTagParameters; - - Map get _data => { - 'androidParameters': androidParameters?.data, - 'uriPrefix': uriPrefix, - 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, - 'googleAnalyticsParameters': googleAnalyticsParameters?.data, - 'iosParameters': iosParameters?.data, - 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?.data, - 'link': link.toString(), - 'navigationInfoParameters': navigationInfoParameters?.data, - 'socialMetaTagParameters': socialMetaTagParameters?.data, - }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index cc99fe95f2fa..65162b24d99e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_dynamic_link_builder.dart'; import 'package:flutter/services.dart'; import 'utils/exception.dart'; @@ -118,6 +119,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return controller.stream; } + @override + MethodChannelDynamicLinkBuilder createLink(){ + return MethodChannelDynamicLinkBuilder(this); + } + // Future _handleMethod(MethodCall call) async { // switch (call.method) { // case 'onLinkSuccess': diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart index 2afbf5ff05cf..209a62ca3d03 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart @@ -38,12 +38,12 @@ abstract class DynamicLinkBuilderPlatform extends PlatformInterface { } /// Generate a long Dynamic Link URL. - Future buildUrl() async { + Future buildUrl(BuildDynamicLinkParameters parameters) async { throw UnimplementedError('buildUrl() is not implemented'); } /// Generate a short Dynamic Link URL. - Future buildShortLink() async { + Future buildShortLink(BuildDynamicLinkParameters parameters) async { throw UnimplementedError('buildShortLink() is not implemented'); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 233555b21212..7d761d3a4c8d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/platform_interface/platform_interface_dynamic_link_builder.dart'; import 'package:meta/meta.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -72,6 +73,10 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('onLink() is not implemented'); } + DynamicLinkBuilderPlatform createLink(){ + throw UnimplementedError('createLink() is not implemented'); + } + @override //ignore: avoid_equals_and_hash_code_on_mutable_classes bool operator ==(Object other) => From 83510e04093f00640fe8621cf0866a44e9c6e844 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 28 Oct 2021 17:06:32 +0100 Subject: [PATCH 003/125] refactor(dynamic_links, android): as part of rework --- .../firebasedynamiclinks/Constants.java | 6 + .../FirebaseDynamicLinksPlugin.java | 429 ++++++++++++++++++ .../GetLinkStreamHandler.java | 60 +++ .../plugins/firebasedynamiclinks/Utils.java | 46 ++ .../lib/src/dynamic_link.dart | 7 + .../method_channel_dynamic_link_builder.dart | 10 +- ...method_channel_firebase_dynamic_links.dart | 64 +-- .../lib/src/short_dynamic_link.dart | 5 +- 8 files changed, 589 insertions(+), 38 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java new file mode 100644 index 000000000000..a6d23e052198 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java @@ -0,0 +1,6 @@ +package io.flutter.plugins.firebasedynamiclinks; + +public class Constants { + public static final String APP_NAME = "appName"; + public static final String DEFAULT_ERROR_CODE = "firebase_dynamic_links"; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java new file mode 100644 index 000000000000..7ab68ec43d8b --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -0,0 +1,429 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebasedynamiclinks; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.android.gms.tasks.Task; +import com.google.android.gms.tasks.TaskCompletionSource; +import com.google.android.gms.tasks.Tasks; +import com.google.firebase.FirebaseApp; +import com.google.firebase.dynamiclinks.DynamicLink; +import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; +import com.google.firebase.dynamiclinks.PendingDynamicLinkData; +import com.google.firebase.dynamiclinks.ShortDynamicLink; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.embedding.engine.plugins.activity.ActivityAware; +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.EventChannel.StreamHandler; +import io.flutter.plugin.common.PluginRegistry.NewIntentListener; +import io.flutter.plugins.firebase.core.FlutterFirebasePlugin; +import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + + +public class FirebaseDynamicLinksPlugin + implements FlutterFirebasePlugin, FlutterPlugin, ActivityAware, MethodCallHandler, NewIntentListener { + private final AtomicReference activity = new AtomicReference<>(null); + + private MethodChannel channel; + @Nullable + private BinaryMessenger messenger; + + private final Map streamHandlers = new HashMap<>(); + + + private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; + + + private static MethodChannel createChannel(final BinaryMessenger messenger) { + return new MethodChannel(messenger, "plugins.flutter.io/firebase_dynamic_links"); + } + + private void initInstance(BinaryMessenger messenger) { + channel = new MethodChannel(messenger, METHOD_CHANNEL_NAME); + channel.setMethodCallHandler(this); + FlutterFirebasePluginRegistry.registerPlugin(METHOD_CHANNEL_NAME, this); + + this.messenger = messenger; + } + + + @Override + public void onAttachedToEngine(FlutterPluginBinding binding) { + initInstance(binding.getBinaryMessenger()); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + channel = null; + messenger = null; +//TODO add this for listening to events +// removeEventListeners(); + } + + @Override + public void onAttachedToActivity(ActivityPluginBinding binding) { + activity.set(binding.getActivity()); + //TODO make sure I'm using this feature. if not, remove. + binding.addOnNewIntentListener(this); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + detachToActivity(); + } + + @Override + public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { + activity.set(binding.getActivity()); + binding.addOnNewIntentListener(this); + } + + private void detachToActivity() { + activity.set(null); + } + + @Override + public void onDetachedFromActivity() { + detachToActivity(); + } + + static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments) { + String appName = (String) Objects.requireNonNull(arguments.get(Constants.APP_NAME)); + FirebaseApp app = FirebaseApp.getInstance(appName); + + return FirebaseDynamicLinks.getInstance(app); + } + + //TODO make sure I'm using this properly + @Override + public boolean onNewIntent(Intent intent) { + FirebaseDynamicLinks.getInstance() + .getDynamicLink(intent) + .addOnSuccessListener( + new OnSuccessListener() { + @Override + public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { + if (pendingDynamicLinkData != null) { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + channel.invokeMethod("onLinkSuccess", dynamicLink); + } + } + }) + .addOnFailureListener( + new OnFailureListener() { + @Override + public void onFailure(Exception e) { + Map exception = new HashMap<>(); + exception.put("code", e.getClass().getSimpleName()); + exception.put("message", e.getMessage()); + exception.put("details", null); + channel.invokeMethod("onLinkError", exception); + } + }); + + return false; + } + + + @Override + public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result result) { + Task methodCallTask; + DynamicLink.Builder urlBuilder = setupParameters(call.arguments()); + FirebaseDynamicLinks dynamicLinks = getDynamicLinkInstance(call.arguments()); + + switch (call.method) { + case "DynamicLinkBuilder#buildUrl": + String url = buildUrl(call.arguments()); + result.success(url); + return; + case "DynamicLinkBuilder#buildShortLink": + methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); + break; + case "DynamicLinkBuilder#shortenUrl": + urlBuilder.setLongLink(Uri.parse(call.argument("url"))); + methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); + break; + case "FirebaseDynamicLinks#getDynamicLink": + case "FirebaseDynamicLinks#getInitialLink": + methodCallTask = getDynamicLink(dynamicLinks, call.argument("url")); + break; + case "FirebaseDynamicLinks#onLink": + methodCallTask = registerGetLinkListener(Objects.requireNonNull(call.argument(Constants.APP_NAME)), dynamicLinks); + break; + default: + result.notImplemented(); + return; + } + + + methodCallTask.addOnCompleteListener( + task -> { + if (task.isSuccessful()) { + result.success(task.getResult()); + } else { + Exception exception = task.getException(); + result.error( + Constants.DEFAULT_ERROR_CODE, + exception != null ? exception.getMessage() : null, + Utils.getExceptionDetails(exception)); + } + }); + } + + private String buildUrl(Map arguments) { + DynamicLink.Builder urlBuilder = setupParameters(arguments); + + return urlBuilder.buildDynamicLink().getUri().toString(); + } + + private Task> buildShortLink(DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { + return Tasks.call( + cachedThreadPool, + () -> { + Integer suffix = null; + + if (dynamicLinkParametersOptions != null) { + Integer shortDynamicLinkPathLength = + (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); + if (shortDynamicLinkPathLength != null) { + switch (shortDynamicLinkPathLength) { + case 0: + suffix = ShortDynamicLink.Suffix.UNGUESSABLE; + break; + case 1: + suffix = ShortDynamicLink.Suffix.SHORT; + break; + default: + break; + } + } + } + + Map result = new HashMap<>(); + ShortDynamicLink shortLink; + if (suffix != null) { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); + } else { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); + } + List warnings = new ArrayList<>(); + + for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { + warnings.add(warning.getMessage()); + } + + result.put("url", shortLink.getShortLink()); + result.put("warnings", warnings); + result.put("previewLink", shortLink.getPreviewLink()); + + return result; + } + ); + } + + private Task> getDynamicLink(FirebaseDynamicLinks dynamicLinks, @Nullable String url) { + return Tasks.call( + cachedThreadPool, + () -> { + PendingDynamicLinkData pendingDynamicLink; + + if (url != null) { + pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); + } else { + // If there's no activity or initial Intent, then there's no initial dynamic link. + if (activity.get() == null || activity.get().getIntent() == null) { + return null; + } + pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); + } + + return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + } + ); + } + + private DynamicLink.Builder setupParameters(Map arguments) { + DynamicLink.Builder dynamicLinkBuilder = FirebaseDynamicLinks.getInstance().createDynamicLink(); + + String uriPrefix = (String) arguments.get("uriPrefix"); + String link = (String) arguments.get("link"); + + dynamicLinkBuilder.setDomainUriPrefix(uriPrefix); + dynamicLinkBuilder.setLink(Uri.parse(link)); + + Map androidParameters = (Map) arguments.get("androidParameters"); + if (androidParameters != null) { + String packageName = valueFor("packageName", androidParameters); + String fallbackUrl = valueFor("fallbackUrl", androidParameters); + Integer minimumVersion = valueFor("minimumVersion", androidParameters); + + DynamicLink.AndroidParameters.Builder builder = + new DynamicLink.AndroidParameters.Builder(packageName); + + if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); + if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); + + dynamicLinkBuilder.setAndroidParameters(builder.build()); + } + + Map googleAnalyticsParameters = (Map) arguments.get("googleAnalyticsParameters"); + if (googleAnalyticsParameters != null) { + String campaign = valueFor("campaign", googleAnalyticsParameters); + String content = valueFor("content", googleAnalyticsParameters); + String medium = valueFor("medium", googleAnalyticsParameters); + String source = valueFor("source", googleAnalyticsParameters); + String term = valueFor("term", googleAnalyticsParameters); + + DynamicLink.GoogleAnalyticsParameters.Builder builder = + new DynamicLink.GoogleAnalyticsParameters.Builder(); + + if (campaign != null) builder.setCampaign(campaign); + if (content != null) builder.setContent(content); + if (medium != null) builder.setMedium(medium); + if (source != null) builder.setSource(source); + if (term != null) builder.setTerm(term); + + dynamicLinkBuilder.setGoogleAnalyticsParameters(builder.build()); + } + + Map iosParameters = (Map) arguments.get("iosParameters"); + if (iosParameters != null) { + String bundleId = valueFor("bundleId", iosParameters); + String appStoreId = valueFor("appStoreId", iosParameters); + String customScheme = valueFor("customScheme", iosParameters); + String fallbackUrl = valueFor("fallbackUrl", iosParameters); + String ipadBundleId = valueFor("ipadBundleId", iosParameters); + String ipadFallbackUrl = valueFor("ipadFallbackUrl", iosParameters); + String minimumVersion = valueFor("minimumVersion", iosParameters); + + DynamicLink.IosParameters.Builder builder = new DynamicLink.IosParameters.Builder(bundleId); + + if (appStoreId != null) builder.setAppStoreId(appStoreId); + if (customScheme != null) builder.setCustomScheme(customScheme); + if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); + if (ipadBundleId != null) builder.setIpadBundleId(ipadBundleId); + if (ipadFallbackUrl != null) builder.setIpadFallbackUrl(Uri.parse(ipadFallbackUrl)); + if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); + + dynamicLinkBuilder.setIosParameters(builder.build()); + } + + Map itunesConnectAnalyticsParameters = (Map) + arguments.get("itunesConnectAnalyticsParameters"); + if (itunesConnectAnalyticsParameters != null) { + String affiliateToken = valueFor("affiliateToken", itunesConnectAnalyticsParameters); + String campaignToken = valueFor("campaignToken", itunesConnectAnalyticsParameters); + String providerToken = valueFor("providerToken", itunesConnectAnalyticsParameters); + + DynamicLink.ItunesConnectAnalyticsParameters.Builder builder = + new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); + + if (affiliateToken != null) builder.setAffiliateToken(affiliateToken); + if (campaignToken != null) builder.setCampaignToken(campaignToken); + if (providerToken != null) builder.setProviderToken(providerToken); + + dynamicLinkBuilder.setItunesConnectAnalyticsParameters(builder.build()); + } + + Map navigationInfoParameters = (Map) arguments.get("navigationInfoParameters"); + if (navigationInfoParameters != null) { + Boolean forcedRedirectEnabled = valueFor("forcedRedirectEnabled", navigationInfoParameters); + + DynamicLink.NavigationInfoParameters.Builder builder = + new DynamicLink.NavigationInfoParameters.Builder(); + + if (forcedRedirectEnabled != null) builder.setForcedRedirectEnabled(forcedRedirectEnabled); + + dynamicLinkBuilder.setNavigationInfoParameters(builder.build()); + } + + Map socialMetaTagParameters = (Map) arguments.get("socialMetaTagParameters"); + if (socialMetaTagParameters != null) { + String description = valueFor("description", socialMetaTagParameters); + String imageUrl = valueFor("imageUrl", socialMetaTagParameters); + String title = valueFor("title", socialMetaTagParameters); + + DynamicLink.SocialMetaTagParameters.Builder builder = + new DynamicLink.SocialMetaTagParameters.Builder(); + + if (description != null) builder.setDescription(description); + if (imageUrl != null) builder.setImageUrl(Uri.parse(imageUrl)); + if (title != null) builder.setTitle(title); + + dynamicLinkBuilder.setSocialMetaTagParameters(builder.build()); + } + + return dynamicLinkBuilder; + } + + private Task registerGetLinkListener(@NonNull String appName, FirebaseDynamicLinks dynamicLinks) { + return Tasks.call( + cachedThreadPool, + () -> { + final GetLinkStreamHandler handler = new GetLinkStreamHandler(dynamicLinks); + final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; + final EventChannel channel = new EventChannel(messenger, name); + channel.setStreamHandler(handler); + streamHandlers.put(channel, handler); + return name; + }); + } + + private static T valueFor(String key, Map map) { + @SuppressWarnings("unchecked") + T result = (T) map.get(key); + return result; + } + + @Override + public Task> getPluginConstantsForFirebaseApp(FirebaseApp firebaseApp) { + return null; + } + + @Override + public Task didReinitializeFirebaseCore() { + return Tasks.call( + cachedThreadPool, + () -> { + removeEventListeners(); + return null; + }); + } + + private void removeEventListeners(){ + for (EventChannel eventChannel : streamHandlers.keySet()) { + StreamHandler streamHandler = streamHandlers.get(eventChannel); + assert streamHandler != null; + streamHandler.onCancel(null); + eventChannel.setStreamHandler(null); + } + streamHandlers.clear(); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java new file mode 100644 index 000000000000..8e7573f7be7e --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java @@ -0,0 +1,60 @@ +package io.flutter.plugins.firebasedynamiclinks; + +import android.content.Intent; + +import androidx.annotation.NonNull; + +import com.google.android.gms.tasks.OnFailureListener; +import com.google.android.gms.tasks.OnSuccessListener; +import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; +import com.google.firebase.dynamiclinks.PendingDynamicLinkData; + +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.EventChannel.StreamHandler; + +import java.util.HashMap; +import java.util.Map; + +import io.flutter.plugin.common.PluginRegistry.NewIntentListener; + +public class GetLinkStreamHandler implements NewIntentListener, StreamHandler { + + + private EventChannel.EventSink events; + private final FirebaseDynamicLinks dynamicLinks; + + public GetLinkStreamHandler(FirebaseDynamicLinks dynamicLinks) { + this.dynamicLinks = dynamicLinks; + } + + @Override + public boolean onNewIntent(Intent intent) { + dynamicLinks + .getDynamicLink(intent) + .addOnSuccessListener( + pendingDynamicLinkData -> { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + + events.success(dynamicLink); + }) + .addOnFailureListener( + exception -> events.error( + Constants.DEFAULT_ERROR_CODE, + exception.getMessage(), + Utils.getExceptionDetails(exception) + )); + + return false; + } + + @Override + public void onListen(Object arguments, EventChannel.EventSink events) { + this.events = events; + } + + @Override + public void onCancel(Object arguments) { + + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java new file mode 100644 index 000000000000..5c5666e792b2 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java @@ -0,0 +1,46 @@ +package io.flutter.plugins.firebasedynamiclinks; + +import android.net.Uri; + +import androidx.annotation.Nullable; + +import com.google.firebase.dynamiclinks.PendingDynamicLinkData; + +import java.util.HashMap; +import java.util.Map; + +public class Utils { + static Map getExceptionDetails(@Nullable Exception exception) { + Map details = new HashMap<>(); + details.put("code", "unknown"); + if (exception != null) { + details.put("message", exception.getMessage()); + } else { + details.put("message", "An unknown error has occurred."); + } + return details; + } + + static Map getMapFromPendingDynamicLinkData( + PendingDynamicLinkData pendingDynamicLinkData) { + Map dynamicLink = new HashMap<>(); + + Uri link = pendingDynamicLinkData.getLink(); + dynamicLink.put("link", link != null ? link.toString() : null); + + Map utmParameters = new HashMap<>(); + + for(String key : pendingDynamicLinkData.getUtmParameters().keySet()){ + utmParameters.put(key, pendingDynamicLinkData.getUtmParameters().get(key).toString()); + } + + dynamicLink.put("utmParameters", utmParameters); + + Map androidData = new HashMap<>(); + androidData.put("clickTimestamp", pendingDynamicLinkData.getClickTimestamp()); + androidData.put("minimumVersion", pendingDynamicLinkData.getMinimumAppVersion()); + + dynamicLink.put("android", androidData); + return dynamicLink; + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart new file mode 100644 index 000000000000..c73cd3e2f63f --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart @@ -0,0 +1,7 @@ +/// Response from creating a dynamic link with [DynamicLinkBuilder]. +class DynamicLink { + const DynamicLink(this.url); + + /// url value. + final Uri url; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart index 9bdbb0abbcd2..fc0f00d06189 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart @@ -43,15 +43,15 @@ class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { @override Future buildShortLink(BuildDynamicLinkParameters parameters) async { - final Map? reply = await MethodChannelFirebaseDynamicLinks.channel + final Map? response = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( 'DynamicLinkParameters#buildShortLink', _withChannelDefaults(parameters.asMap())); - return _parseShortLink(reply!); + return _parseShortLink(response!); } - ShortDynamicLink _parseShortLink(Map reply) { - final List? warnings = reply['warnings']; - return ShortDynamicLink(Uri.parse(reply['url']), warnings?.cast()); + ShortDynamicLink _parseShortLink(Map response) { + final List? warnings = response['warnings']; + return ShortDynamicLink(Uri.parse(response['url']), warnings?.cast(), response['previewLink']); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 65162b24d99e..5a5f67e93fea 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -30,9 +30,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ); /// The [EventChannel] used for onLink - static EventChannel onLinkChannel(String id) { + static EventChannel onLinkChannel(String name) { return EventChannel( - 'plugins.flutter.io/firebase_dynamic_links/onLink/$id', + name, channel.codec, ); } @@ -93,19 +93,19 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Stream onLink() { StreamSubscription? snapshotStream; - late StreamController controller; // ignore: close_sinks + late StreamController + controller; // ignore: close_sinks controller = StreamController.broadcast( onListen: () async { - //TODO setup event channel. Make sure this all works. - final observerId = - await channel.invokeMethod('FirebaseDynamicLinks#onLink'); - - snapshotStream = onLinkChannel(observerId!).receiveBroadcastStream( - { - 'appName': app.name, - }, - ).listen((event) { + // ignore: cast_nullable_to_non_nullable + String name = await channel.invokeMethod( + 'FirebaseDynamicLinks#onLink', { + 'appName': app.name, + }) as String; + + snapshotStream = + onLinkChannel(name).receiveBroadcastStream().listen((event) { controller.add(getPendingDynamicLinkDataFromMap(event)); }, onError: (error, stack) { controller.addError(convertPlatformException(error), stack); @@ -120,29 +120,29 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - MethodChannelDynamicLinkBuilder createLink(){ + MethodChannelDynamicLinkBuilder createLink() { return MethodChannelDynamicLinkBuilder(this); } - // Future _handleMethod(MethodCall call) async { - // switch (call.method) { - // case 'onLinkSuccess': - // PendingDynamicLinkData? linkData; - // if (call.arguments != null) { - // final Map? data = - // call.arguments.cast(); - // linkData = getPendingDynamicLinkDataFromMap(data); - // } - // return _onLinkSuccess!(linkData); - // case 'onLinkError': - // final Map data = - // call.arguments.cast(); - //TODO use stream handler instead - // final OnLinkErrorException e = OnLinkErrorException._( - // data['code'], data['message'], data['details']); - // return _onLinkError!(e); - // } - // } +// Future _handleMethod(MethodCall call) async { +// switch (call.method) { +// case 'onLinkSuccess': +// PendingDynamicLinkData? linkData; +// if (call.arguments != null) { +// final Map? data = +// call.arguments.cast(); +// linkData = getPendingDynamicLinkDataFromMap(data); +// } +// return _onLinkSuccess!(linkData); +// case 'onLinkError': +// final Map data = +// call.arguments.cast(); +//TODO use stream handler instead +// final OnLinkErrorException e = OnLinkErrorException._( +// data['code'], data['message'], data['details']); +// return _onLinkError!(e); +// } +// } } //TODO use exception in PI. Remove this. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index c39673aa60c9..fa09b750a837 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -1,10 +1,13 @@ /// Response from creating a short dynamic link with [DynamicLinkBuilder]. class ShortDynamicLink { - const ShortDynamicLink(this.shortUrl, this.warnings); + const ShortDynamicLink(this.shortUrl, this.warnings, this.previewLink); /// Short url value. final Uri shortUrl; + /// Gets the preview link to show the link flow chart.. + final Uri previewLink; + /// Information about potential warnings on link creation. final List? warnings; } From 2e53ad013e8f6aed039e6d44c8beed30163b0434 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 28 Oct 2021 17:07:00 +0100 Subject: [PATCH 004/125] chore(dynamic_links): updating directory structure --- .../firebase_dynamic_links/CHANGELOG.md | 294 ++++++++ .../firebase_dynamic_links/LICENSE | 27 + .../firebase_dynamic_links/README.md | 189 +++++ .../android/build.gradle | 58 ++ .../android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 11 + .../FlutterFirebaseAppRegistrar.java | 21 + .../android/user-agent.gradle | 22 + .../firebase_dynamic_links/example/.metadata | 8 + .../firebase_dynamic_links/example/README.md | 12 + .../example/analysis_options.yaml | 8 + .../example/android/app/build.gradle | 52 ++ .../example/android/app/google-services.json | 113 +++ .../gradle/wrapper/gradle-wrapper.properties | 5 + .../android/app/src/main/AndroidManifest.xml | 41 ++ .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 17 + .../example/android/build.gradle | 31 + .../example/android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../example/android/settings.gradle | 11 + .../ios/Flutter/AppFrameworkInfo.plist | 30 + .../example/ios/Flutter/Debug.xcconfig | 2 + .../example/ios/Flutter/Release.xcconfig | 2 + .../ios/Runner.xcodeproj/project.pbxproj | 505 +++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 93 +++ .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../example/ios/Runner/AppDelegate.h | 6 + .../example/ios/Runner/AppDelegate.m | 13 + .../AppIcon.appiconset/Contents.json | 122 ++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 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 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 + .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../ios/Runner/GoogleService-Info.plist | 42 ++ .../example/ios/Runner/Info.plist | 62 ++ .../example/ios/Runner/Runner.entitlements | 5 + .../example/ios/Runner/main.m | 9 + .../example/lib/main.dart | 172 +++++ .../example/pubspec.yaml | 33 + .../firebase_dynamic_links_e2e.dart | 73 ++ .../firebase_dynamic_links_e2e_test.dart | 9 + .../ios/Assets/.gitkeep | 0 .../Classes/FLTFirebaseDynamicLinksPlugin.h | 8 + .../Classes/FLTFirebaseDynamicLinksPlugin.m | 373 ++++++++++ .../ios/firebase_dynamic_links.podspec | 39 + .../lib/firebase_dynamic_links.dart | 18 + .../lib/src/dynamic_link_builder.dart | 34 + .../lib/src/firebase_dynamic_links.dart | 76 ++ .../firebase_dynamic_links/pubspec.yaml | 37 + .../test/firebase_dynamic_links_test.dart | 675 ++++++++++++++++++ .../pubspec.yaml | 23 + 77 files changed, 3519 insertions(+) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/LICENSE create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/README.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/settings.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/user-agent.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/.metadata create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/README.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/build.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle.properties create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/settings.gradle create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.h create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.m create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/main.m create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Assets/.gitkeep create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/firebase_dynamic_links.podspec create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md new file mode 100644 index 000000000000..13e1ae582b74 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -0,0 +1,294 @@ +## 2.0.11 + + - **REFACTOR**: remove deprecated Flutter Android v1 Embedding usages, including in example app (#7158). + +## 2.0.10 + + - **DOCS**: changed "ibn" to "ibi" iOS param name in long dynamic link example (#7081). + - **CHORE**: update gradle version across packages (#7054). + +## 2.0.9 + + - Update a dependency to the latest release. + +## 2.0.8 + + - **STYLE**: enable additional lint rules (#6832). + - **FIX**: Use angle bracket import consistently when importing Firebase.h for iOS (#5891). + - **DOCS**: fix readme example (#6790). + +## 2.0.7 + + - Update a dependency to the latest release. + +## 2.0.6 + + - Update a dependency to the latest release. + +## 2.0.5 + + - Update a dependency to the latest release. + +## 2.0.4 + + - Update a dependency to the latest release. + +## 2.0.3 + + - **DOCS**: Add missing homepage/repository links (#6054). + +## 2.0.2 + + - **TEST**: rewrite integration test to test for parameters explicitly. + - **REFACTOR**: upgrade example to v2 Android embedding. + - **FIX**: fix broken ios code from #4354. + - **FIX**: retry handling iOS universal link on network failure (#4354). + - **DOCS**: Open Android App directly without opening link in Browser. (#3127). + - **CI**: setup `firebase_dynamic_links` ci workflow. + +## 2.0.1 + + - **DOCS**: remove codelab link from readme. + +## 2.0.0 + + - Graduate package to a stable release. See pre-releases prior to this version for changelog entries. + +## 2.0.0-dev.1 + + - Update a dependency to the latest release. + +## 2.0.0-dev.0 + +> Note: This release has breaking changes. + + - **DOCS**: remove incorrect ARCHS in ios examples (#5450). + - **CHORE**: publish packages (#5429). + - **CHORE**: merge all analysis_options.yaml into one (#5329). + - **CHORE**: publish packages. + - **CHORE**: enable lints for firebase_dynamic_links (#5256). + - **BREAKING** **FEAT**: Migrate firebase_dynamic_links to sound null safety (#5368). + +## 0.8.0 + + - This version is not null-safe but has been created to allow compatibility with other null-safe FlutterFire packages such as `firebase_core`. + +## 0.7.0 + + - **FIX**: Add missing sdk version constraints inside pubspec.yaml (#4604). + - **CHORE**: harmonize dependencies and version handling. + - **BREAKING** **FEAT**: forward port to firebase-ios-sdk v7.3.0. + - Due to this SDK upgrade, iOS 10 is now the minimum supported version by FlutterFire. Please update your build target version. + +## 0.6.3 + + - **FEAT**: bump android `com.android.tools.build` & `'com.google.gms:google-services` versions (#4269). + - **CHORE**: publish packages. + - **CHORE**: bump gradle wrapper to 5.6.4 (#4158). + +## 0.6.2 + + - **FEAT**: bump compileSdkVersion to 29 (#3975). + - **FEAT**: bump `compileSdkVersion` to 29 in preparation for upcoming Play Store requirement. + - **CHORE**: publish packages. + - **CHORE**: publish packages. + +## 0.6.1 + + - **FIX**: fixed issue with overwriting correct url with null one (#3567). + - **FEAT**: bump compileSdkVersion to 29 (#3975). + - **FEAT**: update Firebase iOS SDK version to 6.33.0 (from 6.26.0). + +## 0.6.0+2 + + - Update a dependency to the latest release. + +## 0.6.0+1 + + - **FIX**: local dependencies in example apps (#3319). + - **CHORE**: intellij cleanup (#3326). + +## 0.6.0 + +* Depend on new `firebase_core` plugin. +* Firebase iOS SDK versions are now locked to use the same version defined in + `firebase_core`. +* Firebase Android SDK versions are now using the Firebase Bill of Materials (BoM) + to specify individual SDK versions. BoM version is also sourced from + `firebase_core`. + +## 0.5.3 + +* Fix for passing null/nil link between native libraries and flutter code. + +## 0.5.2 + +* Fix for race-condition issue on iOS during initialization process + +## 0.5.1 + +* Update lower bound of dart dependency to 2.0.0. + +## 0.5.0+12 + +* Fix for missing UserAgent.h compilation failures. + +## 0.5.0+11 + +* Replace deprecated `getFlutterEngine` call on Android. + +## 0.5.0+10 + +* Make the pedantic dev_dependency explicit. + +## 0.5.0+9 + +* Remove the deprecated `author:` field from pubspec.yaml +* Migrate the plugin to the pubspec platforms manifest. +* Bump the minimum Flutter version to 1.10.0. + +## 0.5.0+8 + +* Support v2 embedding. This will remain compatible with the original embedding and won't require app migration. + +## 0.5.0+7 + +* Add `getDynamicLink` to support expanding from short links. + +## 0.5.0+6 + +* Updated README instructions for contributing for consistency with other Flutterfire plugins. + +## 0.5.0+5 + +* Remove AndroidX warning. + +## 0.5.0+4 + +* Fix example app build by updating version of `url_launcher` that is compatible with androidx apps. + +## 0.5.0+3 + +* Don't crash if registrar.activity() is not there. + +## 0.5.0+2 + +* Change the OnLinkError object to be a real exception. + +## 0.5.0+1 + +* Update documentation to reflect new repository location. +* Update unit tests to call `TestWidgetsFlutterBinding.ensureInitialized`. + +## 0.5.0 + +* **Breaking change**. Changed architecture and method names to be able to differentiate between +the dynamic link which opened the app and links clicked during app execution (active and background). +`retrieveDynamicLink` has been replaced with two different functions: +- `getInitialLink` a future to retrieve the link that opened the app +- `onLink` a callback to listen to links opened while the app is active or in background + +## 0.4.0+6 + +* Update google-services Android gradle plugin to 4.3.0 in documentation and examples. + +## 0.4.0+5 + +* Fix the bug below properly by allowing the activity to be null (but still registering the plugin). If activity is null, we don't get a latestIntent, instead we expect the intent listener to grab it. + +## 0.4.0+4 + +* Fixed bug on Android when a headless plugin tries to register this plugin causing a crash due no activity from the registrar. + +## 0.4.0+3 + +* Automatically use version from pubspec.yaml when reporting usage to Firebase. + +## 0.4.0+2 + +* Add missing template type parameter to `invokeMethod` calls. +* Bump minimum Flutter version to 1.5.0. +* Replace invokeMethod with invokeMapMethod wherever necessary. + +## 0.4.0+1 + +* Fixed bug where link persists after starting an app with a Dynamic Link. +* Fixed bug where retrieving a link would fail when app was already running. + +## 0.4.0 + +* Update dependency on firebase_core to 0.4.0. + +## 0.3.0. + +* Update Android dependencies to 16.1.7. +* **Breaking change**. Dynamic link parameter `domain` replaced with `uriPrefix`. + +## 0.2.1 + +* Throw `PlatformException` if there is an error retrieving dynamic link. + +## 0.2.0+4 + +* Fix crash when receiving `ShortDynamicLink` warnings. + +## 0.2.0+3 + +* Log messages about automatic configuration of the default app are now less confusing. + +## 0.2.0+2 + +* Remove categories. + +## 0.2.0+1 + +* Log a more detailed warning at build time about the previous AndroidX + migration. + +## 0.2.0 + +* **Breaking change**. Migrate from the deprecated original Android Support + Library to AndroidX. This shouldn't result in any functional changes, but it + requires any Android apps using this plugin to [also + migrate](https://developer.android.com/jetpack/androidx/migrate) if they're + using the original support library. + +## 0.1.1 + +* Update example to create a clickable and copyable link. + +## 0.1.0+2 + +* Change android `invites` dependency to `dynamic links` dependency. + +## 0.1.0+1 + +* Bump Android dependencies to latest. + +## 0.1.0 + +* **Breaking Change** Calls to retrieve dynamic links on iOS always returns null after first call. + +## 0.0.6 + +* Bump Android and Firebase dependency versions. + +## 0.0.5 + +* Added capability to receive dynamic links. + +## 0.0.4 + +* Fixed dynamic link dartdoc generation. + +## 0.0.3 + +* Fixed incorrect homepage link in pubspec. + +## 0.0.2 + +* Updated Gradle tooling to match Android Studio 3.1.2. + +## 0.0.1 + +* Initial release with api to create long or short dynamic links. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/LICENSE b/packages/firebase_dynamic_links/firebase_dynamic_links/LICENSE new file mode 100644 index 000000000000..b9f0ba5d5188 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md new file mode 100644 index 000000000000..e320725e17bf --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md @@ -0,0 +1,189 @@ +# Google Dynamic Links for Firebase + +[![pub package](https://img.shields.io/pub/v/firebase_dynamic_links.svg)](https://pub.dev/packages/firebase_dynamic_links) + +A Flutter plugin to use the [Google Dynamic Links for Firebase API](https://firebase.google.com/docs/dynamic-links/). + +With Dynamic Links, your users get the best available experience for the platform they open your link on. If a user opens a Dynamic Link on iOS or Android, they can be taken directly to the linked content in your native app. If a user opens the same Dynamic Link in a desktop browser, they can be taken to the equivalent content on your website. + +In addition, Dynamic Links work across app installs: if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link. + +For Flutter plugins for other Firebase products, see [README.md](https://github.com/FirebaseExtended/flutterfire/blob/master/README.md). + +## Usage + +To use this plugin, add `firebase_dynamic_links` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). You must also configure firebase dynamic links for each platform project: Android and iOS (see the example folder for details). + +## Create Dynamic Links + +You create a Dynamic Link either by using the Firebase console, using a REST API, iOS or Android Builder API, Flutter API, or by forming a URL by adding Dynamic Link parameters to a URI prefix specific to your app. These parameters specify the links you want to open, depending on the user's platform and whether your app is installed. + +Below are instructions to create Dynamic Links using Flutter with the Firebase Dynamic Links API. This API accepts either a long Dynamic Link or an object containing Dynamic Link parameters, and returns a URL like the following example: + +``` +https://example.page.link/WXYZ +``` + +You can create a Dynamic Link programmatically by setting the following parameters and using the `DynamicLinkParameters.buildUrl()` method. + +```dart +final DynamicLinkParameters parameters = DynamicLinkParameters( + uriPrefix: 'https://abc123.app.goo.gl', + link: Uri.parse('https://example.com/'), + androidParameters: AndroidParameters( + packageName: 'com.example.android', + minimumVersion: 125, + ), + iosParameters: IosParameters( + bundleId: 'com.example.ios', + minimumVersion: '1.0.1', + appStoreId: '123456789', + ), + googleAnalyticsParameters: GoogleAnalyticsParameters( + campaign: 'example-promo', + medium: 'social', + source: 'orkut', + ), + itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( + providerToken: '123456', + campaignToken: 'example-promo', + ), + socialMetaTagParameters: SocialMetaTagParameters( + title: 'Example of a Dynamic Link', + description: 'This link works whether app is installed or not!', + ), +); + +final Uri dynamicUrl = await parameters.buildUrl(); +``` + +To create a short Dynamic Link, build `DynamicLinkParameters` the same way, but use the `DynamicLinkParameters.buildShortLink()` method. + +```dart +final ShortDynamicLink shortDynamicLink = await parameters.buildShortLink(); +final Uri shortUrl = shortDynamicLink.shortUrl; +``` + +To shorten a long Dynamic Link, use the DynamicLinkParameters.shortenUrl method. + +```dart +final ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl( + Uri.parse('https://example.page.link/?link=https://example.com/&apn=com.example.android&ibi=com.example.ios'), + DynamicLinkParametersOptions(ShortDynamicLinkPathLength.unguessable), +); + +final Uri shortUrl = shortenedLink.shortUrl; +``` + +## Handle Received Dynamic Links + +You can receive a Dynamic Link containing a deep link that takes the user to specific content within your app: + +1. In the [Firebase Console](https://console.firebase.google.com), open the Dynamic Links section. + - Accept the terms of service if you are prompted to do so. + - Take note of your project's Dynamic Links URL prefix, which is displayed at the top of the Dynamic Links page. You need your project's Dynamic Links URL prefix to programmatically create Dynamic Links. Unless you are using a custom domain, a Dynamic Links URL prefix looks like `https://YOUR_SUBDOMAIN.page.link`. + +Receiving dynamic links on *iOS* requires a couple more steps than *Android*. If you only want to receive dynamic links on *Android*, skip to step 5. You can also follow a video on the next two steps [here.](https://youtu.be/KLBjAg6HvG0?t=60) + +2. In the **Info** tab of your *iOS* app's Xcode project: + - Create a new **URL Type** to be used for Dynamic Links. + - Set the **Identifier** field to a unique value and the **URL Schemes** field to be your bundle identifier, which is the default URL scheme used by Dynamic Links. + +3. In the **Capabilities** tab of your app's Xcode project, enable **Associated Domains** and add the following to the **Associated Domains** list: + +``` +applinks:YOUR_URL_PREFIX +``` + +Remember not to include `https://` or any slashes or paths in your prefix + +4. **If you are using a custom domain** create an key in your `Info.plist` file called `FirebaseDynamicLinksCustomDomains` and set it to your app's Dynamic Link URL prefixes. For example: + +```xml +FirebaseDynamicLinksCustomDomains + + https://example.com/promos + https://example.com/links/share + +``` +5. If you want to open android app directly without redirecting to Chrome or Any other Browser you can put an `intent-filter` in your `AndroidManifest.xml` file. It will open the system dialogue to open link with your app or other browsers. Users can then directly choose to open the link in your app. + +Note: This step is optional and in case we do not implement this then link will open in chrome at first and then will eventually open your application. +```xml + + + + + + + +``` +6. To receive a dynamic link, call the `getInitialLink()` method from `FirebaseDynamicLinks` which gets the link that opened the app (or null if it was not opened via a dynamic link) +and configure listeners for link callbacks when the application is active or in background calling `onLink`. + +```dart +void main() { + runApp(MaterialApp( + title: 'Dynamic Links Example', + routes: { + '/': (BuildContext context) => MyHomeWidget(), // Default home route + '/helloworld': (BuildContext context) => MyHelloWorldWidget(), + }, + )); +} + +class MyHomeWidgetState extends State { + . + . + . + @override + void initState() { + super.initState(); + this.initDynamicLinks(); + } + + void initDynamicLinks() async { + FirebaseDynamicLinks.instance.onLink( + onSuccess: (PendingDynamicLinkData? dynamicLink) async { + final Uri? deepLink = dynamicLink?.link; + + if (deepLink != null) { + Navigator.pushNamed(context, deepLink.path); + } + }, + onError: (OnLinkErrorException e) async { + print('onLinkError'); + print(e.message); + } + ); + + final PendingDynamicLinkData? data = await FirebaseDynamicLinks.instance.getInitialLink(); + final Uri? deepLink = data?.link; + + if (deepLink != null) { + Navigator.pushNamed(context, deepLink.path); + } + } + . + . + . +} +``` + +If your app did not open from a dynamic link, `getInitialLink()` will return `null`. + +## Getting Started + +See the `example` directory for a complete sample app using Google Dynamic Links for Firebase. + +## Issues and feedback + +Please file FlutterFire specific issues, bugs, or feature requests in our [issue tracker](https://github.com/FirebaseExtended/flutterfire/issues/new). + +Plugin issues that are not specific to Flutterfire can be filed in the [Flutter issue tracker](https://github.com/flutter/flutter/issues/new). + +To contribute a change to this plugin, +please review our [contribution guide](https://github.com/FirebaseExtended/flutterfire/blob/master/CONTRIBUTING.md) +and open a [pull request](https://github.com/FirebaseExtended/flutterfire/pulls). diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle new file mode 100644 index 000000000000..74d3a390fd14 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle @@ -0,0 +1,58 @@ +group 'io.flutter.plugins.firebasedynamiclinks' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.0.2' + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: 'com.android.library' + +def firebaseCoreProject = findProject(':firebase_core') +if (firebaseCoreProject == null) { + throw new GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') +} else if (!firebaseCoreProject.properties['FirebaseSDKVersion']) { + throw new GradleException('A newer version of the firebase_core FlutterFire plugin is required, please update your firebase_core pubspec dependency.') +} + +def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { + if (!rootProject.ext.has('FlutterFire')) return firebaseCoreProject.properties[name] + if (!rootProject.ext.get('FlutterFire')[name]) return firebaseCoreProject.properties[name] + return rootProject.ext.get('FlutterFire').get(name) +} + +android { + compileSdkVersion 31 + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } + dependencies { + api firebaseCoreProject + implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}") + implementation 'com.google.firebase:firebase-dynamic-links' + } +} + +apply from: file("./user-agent.gradle") + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/settings.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/android/settings.gradle new file mode 100644 index 000000000000..2a833554f85c --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'firebase_dynamic_links' diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..663e4f0f3de9 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java new file mode 100644 index 000000000000..dbf3822c7a24 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java @@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebasedynamiclinks; + +import androidx.annotation.Keep; +import com.google.firebase.components.Component; +import com.google.firebase.components.ComponentRegistrar; +import com.google.firebase.platforminfo.LibraryVersionComponent; +import java.util.Collections; +import java.util.List; + +@Keep +public class FlutterFirebaseAppRegistrar implements ComponentRegistrar { + @Override + public List> getComponents() { + return Collections.>singletonList( + LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION)); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/user-agent.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/android/user-agent.gradle new file mode 100644 index 000000000000..06d7f9075b82 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/user-agent.gradle @@ -0,0 +1,22 @@ +import java.util.regex.Matcher +import java.util.regex.Pattern + +String libraryVersionName = "UNKNOWN" +String libraryName = "flutter-fire-dl" +File pubspec = new File(project.projectDir.parentFile, 'pubspec.yaml') + +if (pubspec.exists()) { + String yaml = pubspec.text + // Using \s*['|"]?([^\n|'|"]*)['|"]? to extract version number. + Matcher versionMatcher = Pattern.compile("^version:\\s*['|\"]?([^\\n|'|\"]*)['|\"]?\$", Pattern.MULTILINE).matcher(yaml) + if (versionMatcher.find()) libraryVersionName = versionMatcher.group(1).replaceAll("\\+", "-") +} + +android { + defaultConfig { + // BuildConfig.VERSION_NAME + buildConfigField 'String', 'LIBRARY_VERSION', "\"${libraryVersionName}\"" + // BuildConfig.LIBRARY_NAME + buildConfigField 'String', 'LIBRARY_NAME', "\"${libraryName}\"" + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/.metadata b/packages/firebase_dynamic_links/firebase_dynamic_links/example/.metadata new file mode 100644 index 000000000000..866a061a7a7f --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/.metadata @@ -0,0 +1,8 @@ +# 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: f408bb06f9361793ca85493c38d809ee1e2f7e30 + channel: master diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links/example/README.md new file mode 100644 index 000000000000..e098704eddc5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/README.md @@ -0,0 +1,12 @@ +# firebase_dynamic_links_example + +Demonstrates how to use the firebase_dynamic_links plugin. + +## *Important* + +The example app for this plugin only receives links on Android. Xcode has signing requirements that must be configured with an iOS app developer team id. Check the `firebase_dynamic_links/README.md` for more details. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.io/). diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml new file mode 100644 index 000000000000..98eee62ba0f0 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml @@ -0,0 +1,8 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# in the LICENSE file. +include: ../../../analysis_options.yaml +linter: + rules: + public_member_api_docs: false + avoid_print: false \ No newline at end of file diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle new file mode 100644 index 000000000000..61748d009e2c --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle @@ -0,0 +1,52 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 29 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "io.flutter.plugins.firebasedynamiclinksexample" + minSdkVersion 16 + targetSdkVersion 29 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json new file mode 100644 index 000000000000..7123ea9b2ebd --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json @@ -0,0 +1,113 @@ +{ + "project_info": { + "project_number": "479882132969", + "firebase_url": "https://my-flutter-proj.firebaseio.com", + "project_id": "my-flutter-proj", + "storage_bucket": "my-flutter-proj.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:479882132969:android:632cdf3fc0a17139", + "android_client_info": { + "package_name": "io.flutter.plugins.firebasedynamiclinksexample" + } + }, + "oauth_client": [ + { + "client_id": "479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.flutter.plugins.firebasedynamiclinksexample", + "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" + } + }, + { + "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 2, + "other_platform_oauth_client": [ + { + "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "cvbxvzv" + } + }, + { + "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", + "client_type": 3 + } + ] + }, + "ads_service": { + "status": 2 + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:479882132969:android:215a22700e1b466b", + "android_client_info": { + "package_name": "io.flutter.plugins.firebaseperformanceexample" + } + }, + "oauth_client": [ + { + "client_id": "479882132969-8h4kiv8m7ho4tvn6uuujsfcrf69unuf7.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "io.flutter.plugins.firebaseperformanceexample", + "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" + } + }, + { + "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" + } + ], + "services": { + "analytics_service": { + "status": 1 + }, + "appinvite_service": { + "status": 2, + "other_platform_oauth_client": [ + { + "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "cvbxvzv" + } + }, + { + "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", + "client_type": 3 + } + ] + }, + "ads_service": { + "status": 2 + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..186b71557c50 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..3906eecd9efa --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000000..304732f88420 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000000..11beaaf68414 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/build.gradle new file mode 100644 index 000000000000..649f806eb474 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.2' + classpath 'com.google.gms:google-services:4.3.4' + } +} + +allprojects { + repositories { + google() + jcenter() + mavenLocal() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle.properties b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle.properties new file mode 100644 index 000000000000..38c8d4544ff1 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..297f2fec363f --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/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-7.0.2-all.zip diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/settings.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/settings.gradle new file mode 100644 index 000000000000..44e62bcf06ae --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000000..6c2de8086bcd --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000000..e8efba114687 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000000..399e9340e6f6 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..9a7df42960b3 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,505 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */; }; + 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 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 = ""; }; + 20643451FF253CB176AF9580 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 23C87C2196BFAAA7E465A745 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 8FE60D1A20C0962300E3A541 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; 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; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 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 = ( + 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 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 */, + C265487490C4649DB6EB38D8 /* Pods */, + FB89BCA43D68B61E6BC59A86 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 8FE60D1A20C0962300E3A541 /* Runner.entitlements */, + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + C265487490C4649DB6EB38D8 /* Pods */ = { + isa = PBXGroup; + children = ( + 20643451FF253CB176AF9580 /* Pods-Runner.debug.xcconfig */, + 23C87C2196BFAAA7E465A745 /* Pods-Runner.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + FB89BCA43D68B61E6BC59A86 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + DFB8FA600F7B599A94289A9E /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.SafariKeychain = { + enabled = 0; + }; + }; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */, + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig 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; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../Flutter/Flutter.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; + DFB8FA600F7B599A94289A9E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase 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 */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..1263ac84b105 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..21a3cc14c74e --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.h b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.h new file mode 100644 index 000000000000..36e21bbf9cf4 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.m b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.m new file mode 100644 index 000000000000..59a72e90be12 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..d36b1fab2d9d --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" : "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" : "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" + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d43d11e66f4de3da27ed045ca4fe38ad8b48094 GIT binary patch literal 11112 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 P-1+_A+?hGkL;m(J7kc&K literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 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 literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/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/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/packages/firebase_dynamic_links/firebase_dynamic_links/example/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/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000000..89c2725b70f1 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/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/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000000..f2e259c7c939 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000000..f3c28516fb38 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist new file mode 100644 index 000000000000..ac0d4c98b0d0 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,42 @@ + + + + + AD_UNIT_ID_FOR_BANNER_TEST + ca-app-pub-3940256099942544/2934735716 + AD_UNIT_ID_FOR_INTERSTITIAL_TEST + ca-app-pub-3940256099942544/4411468910 + CLIENT_ID + 479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9 + ANDROID_CLIENT_ID + 479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com + API_KEY + AIzaSyBECOwLTAN6PU4Aet1b2QLGIb3kRK8Xjew + GCM_SENDER_ID + 479882132969 + PLIST_VERSION + 1 + BUNDLE_ID + com.google.FirebaseCppDynamicLinksTestApp.dev + PROJECT_ID + my-flutter-proj + STORAGE_BUCKET + my-flutter-proj.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:479882132969:ios:36e157824ba4dd3d + DATABASE_URL + https://my-flutter-proj.firebaseio.com + + \ No newline at end of file diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist new file mode 100644 index 000000000000..f24bc9d4f80d --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + firebase_dynamic_links_example + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + Bundle ID + CFBundleURLSchemes + + com.google.FirebaseCppDynamicLinksTestApp.dev + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements new file mode 100644 index 000000000000..0c67376ebacb --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/main.m b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/main.m new file mode 100644 index 000000000000..dff6597e4513 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart new file mode 100644 index 000000000000..c665f9d1ed47 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -0,0 +1,172 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:url_launcher/url_launcher.dart'; + +void main() { + runApp(MaterialApp( + title: 'Dynamic Links Example', + routes: { + '/': (BuildContext context) => _MainScreen(), + '/helloworld': (BuildContext context) => _DynamicLinkScreen(), + }, + )); +} + +class _MainScreen extends StatefulWidget { + @override + State createState() => _MainScreenState(); +} + +class _MainScreenState extends State<_MainScreen> { + String? _linkMessage; + bool _isCreatingLink = false; + String _testString = + 'To test: long press link and then copy and click from a non-browser ' + "app. Make sure this isn't being tested on iOS simulator and iOS xcode " + 'is properly setup. Look at firebase_dynamic_links/README.md for more ' + 'details.'; + + @override + void initState() { + super.initState(); + initDynamicLinks(); + } + + Future initDynamicLinks() async { + FirebaseDynamicLinks.instance.onLink( + onSuccess: (PendingDynamicLinkData? dynamicLink) async { + final Uri? deepLink = dynamicLink?.link; + + if (deepLink != null) { + // ignore: unawaited_futures + Navigator.pushNamed(context, deepLink.path); + } + }, onError: (OnLinkErrorException e) async { + print('onLinkError'); + print(e.message); + }); + + final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getInitialLink(); + final Uri? deepLink = data?.link; + + if (deepLink != null) { + // ignore: unawaited_futures + Navigator.pushNamed(context, deepLink.path); + } + } + + Future _createDynamicLink(bool short) async { + setState(() { + _isCreatingLink = true; + }); + + final DynamicLinkBuilder parameters = DynamicLinkBuilder( + uriPrefix: 'https://cx4k7.app.goo.gl', + link: Uri.parse('https://dynamic.link.example/helloworld'), + androidParameters: AndroidParameters( + packageName: 'io.flutter.plugins.firebasedynamiclinksexample', + minimumVersion: 0, + ), + dynamicLinkParametersOptions: DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: IosParameters( + bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev', + minimumVersion: '0', + ), + ); + + Uri url; + if (short) { + final ShortDynamicLink shortLink = await parameters.buildShortLink(); + url = shortLink.shortUrl; + } else { + url = await parameters.buildUrl(); + } + + setState(() { + _linkMessage = url.toString(); + _isCreatingLink = false; + }); + } + + @override + Widget build(BuildContext context) { + return Material( + child: Scaffold( + appBar: AppBar( + title: const Text('Dynamic Links Example'), + ), + body: Builder(builder: (BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: !_isCreatingLink + ? () => _createDynamicLink(false) + : null, + child: const Text('Get Long Link'), + ), + ElevatedButton( + onPressed: !_isCreatingLink + ? () => _createDynamicLink(true) + : null, + child: const Text('Get Short Link'), + ), + ], + ), + InkWell( + onTap: () async { + if (_linkMessage != null) { + await launch(_linkMessage!); + } + }, + onLongPress: () { + Clipboard.setData(ClipboardData(text: _linkMessage)); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Copied Link!')), + ); + }, + child: Text( + _linkMessage ?? '', + style: const TextStyle(color: Colors.blue), + ), + ), + Text(_linkMessage == null ? '' : _testString) + ], + ), + ); + }), + ), + ); + } +} + +class _DynamicLinkScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Material( + child: Scaffold( + appBar: AppBar( + title: const Text('Hello World DeepLink'), + ), + body: const Center( + child: Text('Hello, World!'), + ), + ), + ); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml new file mode 100644 index 000000000000..d5bbc2a7f8d4 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -0,0 +1,33 @@ +name: firebase_dynamic_links_example +description: Demonstrates how to use the firebase_dynamic_links plugin. + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: ">=1.12.0" + +dependencies: + firebase_core: + path: ../../../firebase_core/firebase_core + firebase_dynamic_links: + path: ../ + flutter: + sdk: flutter + url_launcher: ^6.0.2 + +dependency_overrides: + firebase_core: + path: ../../../firebase_core/firebase_core + firebase_core_platform_interface: + path: ../../../firebase_core/firebase_core_platform_interface + firebase_core_web: + path: ../../../firebase_core/firebase_core_web + +dev_dependencies: + drive: 0.1.0 + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart new file mode 100644 index 000000000000..d82ca21c2738 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart @@ -0,0 +1,73 @@ +// ignore_for_file: require_trailing_commas +// @dart = 2.9 +// Copyright 2020, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:drive/drive.dart' as drive; +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void testsMain() { + group('DynamicLinks', () { + test('buildUrl', () async { + const String androidPackageName = + 'io.flutter.plugins.firebasedynamiclinksexample'; + const String iosBundleId = + 'com.google.FirebaseCppDynamicLinksTestApp.dev'; + const String urlHost = 'cx4k7.app.goo.gl'; + const String link = 'https://dynamic.link.example/helloworld'; + + final DynamicLinkBuilder parameters = DynamicLinkBuilder( + uriPrefix: 'https://$urlHost', + link: Uri.parse(link), + androidParameters: AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + dynamicLinkParametersOptions: DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: IosParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await parameters.buildUrl(); + + // androidParameters.minimumVersion + expect( + uri.queryParameters['amv'], + '1', + ); + // iosParameters.minimumVersion + expect( + uri.queryParameters['imv'], + '2', + ); + // androidParameters.packageName + expect( + uri.queryParameters['apn'], + androidPackageName, + ); + // iosParameters.bundleId + expect( + uri.queryParameters['ibi'], + iosBundleId, + ); + // link + expect( + uri.queryParameters['link'], + Uri.encodeFull(link), + ); + // uriPrefix + expect( + uri.host, + urlHost, + ); + }); + }); +} + +void main() => drive.main(testsMain); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart new file mode 100644 index 000000000000..9ea0d073c35e --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart @@ -0,0 +1,9 @@ +// ignore_for_file: require_trailing_commas +// @dart = 2.9 +// Copyright 2020, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:drive/drive_driver.dart' as drive; + +void main() => drive.main(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Assets/.gitkeep b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Assets/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h new file mode 100644 index 000000000000..f905bbbd03e0 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h @@ -0,0 +1,8 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +@interface FLTFirebaseDynamicLinksPlugin : NSObject +@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m new file mode 100644 index 000000000000..0831fe6b0a23 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -0,0 +1,373 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "FLTFirebaseDynamicLinksPlugin.h" + +#import + +static FlutterError *getFlutterError(NSError *error) { + return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code] + message:error.domain + details:error.localizedDescription]; +} + +static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) { + if (dynamicLink != nil) { + NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; + dictionary[@"link"] = dynamicLink.url.absoluteString; + + NSMutableDictionary *iosData = [[NSMutableDictionary alloc] init]; + if (dynamicLink.minimumAppVersion) { + iosData[@"minimumVersion"] = dynamicLink.minimumAppVersion; + } + dictionary[@"ios"] = iosData; + return dictionary; + } else { + return nil; + } +} + +static NSMutableDictionary *getDictionaryFromFlutterError(FlutterError *error) { + if (error == nil) { + return nil; + } + + NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; + dictionary[@"code"] = error.code; + dictionary[@"message"] = error.message; + dictionary[@"details"] = error.details; + return dictionary; +} + +@interface FLTFirebaseDynamicLinksPlugin () +@property(nonatomic, retain) FlutterMethodChannel *channel; +@property(nonatomic, retain) FIRDynamicLink *initialLink; +@property(nonatomic, retain) FlutterError *flutterError; +@property(nonatomic) BOOL initiated; +@end + +@implementation FLTFirebaseDynamicLinksPlugin ++ (void)registerWithRegistrar:(NSObject *)registrar { + FlutterMethodChannel *channel = + [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/firebase_dynamic_links" + binaryMessenger:[registrar messenger]]; + FLTFirebaseDynamicLinksPlugin *instance = + [[FLTFirebaseDynamicLinksPlugin alloc] initWithChannel:channel]; + [registrar addMethodCallDelegate:instance channel:channel]; + [registrar addApplicationDelegate:instance]; + + SEL sel = NSSelectorFromString(@"registerLibrary:withVersion:"); + if ([FIRApp respondsToSelector:sel]) { + [FIRApp performSelector:sel withObject:LIBRARY_NAME withObject:LIBRARY_VERSION]; + } +} + +- (instancetype)initWithChannel:(FlutterMethodChannel *)channel { + self = [super init]; + if (self) { + _initiated = NO; + _channel = channel; + if (![FIRApp appNamed:@"__FIRAPP_DEFAULT"]) { + NSLog(@"Configuring the default Firebase app..."); + [FIRApp configure]; + NSLog(@"Configured the default Firebase app %@.", [FIRApp defaultApp].name); + } + } + return self; +} + +- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { + if ([@"DynamicLinkParameters#buildUrl" isEqualToString:call.method]) { + FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; + result([components.url absoluteString]); + } else if ([@"DynamicLinkParameters#buildShortLink" isEqualToString:call.method]) { + FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; + [components shortenWithCompletion:[self createShortLinkCompletion:result]]; + } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { + FIRDynamicLinkComponentsOptions *options = [self setupOptions:call.arguments]; + NSURL *url = [NSURL URLWithString:call.arguments[@"url"]]; + [FIRDynamicLinkComponents shortenURL:url + options:options + completion:[self createShortLinkCompletion:result]]; + } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { + _initiated = YES; + NSMutableDictionary *dict = [self getInitialLink]; + if (dict == nil && self.flutterError) { + result(self.flutterError); + } else { + result(dict); + } + } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { + NSURL *shortLink = [NSURL URLWithString:call.arguments[@"url"]]; + FIRDynamicLinkUniversalLinkHandler completion = + ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { + if (error) { + result(getFlutterError(error)); + } else { + result(getDictionaryFromDynamicLink(dynamicLink)); + } + }; + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion]; + } else { + result(FlutterMethodNotImplemented); + } +} + +- (NSMutableDictionary *)getInitialLink { + return getDictionaryFromDynamicLink(_initialLink); +} + +- (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { + if (_initiated) { + if (error) { + FlutterError *flutterError = getFlutterError(error); + [_channel invokeMethod:@"onLinkError" arguments:getDictionaryFromFlutterError(flutterError)]; + } else { + NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); + [_channel invokeMethod:@"onLinkSuccess" arguments:dictionary]; + } + } else { + if (error) { + _flutterError = getFlutterError(error); + } else if (dynamicLink.url != nil || _initialLink == nil) { + // We'd like to overwrite initial link only if it's + // the first time or if we overwrite it with url that is not nil + _initialLink = dynamicLink; + } + } +} + +- (void)checkForDynamicLink:(NSURL *)url { + FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; + if (dynamicLink) { + [self onDeepLinkResult:dynamicLink error:nil]; + } +} + +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + options:(NSDictionary *)options { + [self checkForDynamicLink:url]; + // Results of this are ORed and NO doesn't affect other delegate interceptors' result. + return NO; +} + +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + [self checkForDynamicLink:url]; + // Results of this are ORed and NO doesn't affect other delegate interceptors' result. + return NO; +} + +- (BOOL)application:(UIApplication *)application + continueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(nonnull void (^)(NSArray *_Nullable))restorationHandler { + __block BOOL retried = NO; + void (^completionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); + void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink, + NSError *_Nullable error); + weakCompletionBlock = completionBlock = ^(FIRDynamicLink *_Nullable dynamicLink, + NSError *_Nullable error) { + if (!error && dynamicLink && dynamicLink.url) { + [self onDeepLinkResult:dynamicLink error:nil]; + } + + // Per Apple Tech Support, a network failure could occur when returning from background on + // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 So + // we'll retry the request once + if (error && !retried && [NSPOSIXErrorDomain isEqualToString:error.domain] && + error.code == 53) { + retried = YES; + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL + completion:weakCompletionBlock]; + } + // We could send this to Dart and maybe have a onDynamicLinkError stream but there's also + // a good chance the `userActivity.webpageURL` might not be for a Firebase dynamic link, + // which needs consideration - so we'll log this for now, logging will get picked up by + // Crashlytics automatically if its integrated. + if (error) + NSLog( + @"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a universal " + @"link: %@", + error); + }; + + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL + completion:completionBlock]; + + // Results of this are ORed and NO doesn't affect other delegate interceptors' result. + return NO; +} + +- (FIRDynamicLinkShortenerCompletion)createShortLinkCompletion:(FlutterResult)result { + return ^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error) { + if (error) { + result(getFlutterError(error)); + } else { + if (warnings == nil) { + warnings = [NSMutableArray array]; + } + result(@{@"url" : [shortURL absoluteString], @"warnings" : warnings}); + } + }; +} + +- (FIRDynamicLinkComponentsOptions *)setupOptions:(NSDictionary *)arguments { + FIRDynamicLinkComponentsOptions *options; + if (![arguments[@"dynamicLinkParametersOptions"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"dynamicLinkParametersOptions"]; + + options = [FIRDynamicLinkComponentsOptions options]; + + NSNumber *shortDynamicLinkPathLength = params[@"shortDynamicLinkPathLength"]; + if (![shortDynamicLinkPathLength isEqual:[NSNull null]]) { + switch (shortDynamicLinkPathLength.intValue) { + case 0: + options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; + break; + case 1: + options.pathLength = FIRShortDynamicLinkPathLengthShort; + break; + default: + break; + } + } + } + + return options; +} + +- (FIRDynamicLinkComponents *)setupParameters:(NSDictionary *)arguments { + NSURL *link = [NSURL URLWithString:arguments[@"link"]]; + NSString *uriPrefix = arguments[@"uriPrefix"]; + + FIRDynamicLinkComponents *components = [FIRDynamicLinkComponents componentsWithLink:link + domainURIPrefix:uriPrefix]; + + if (![arguments[@"androidParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"androidParameters"]; + + FIRDynamicLinkAndroidParameters *androidParams = + [FIRDynamicLinkAndroidParameters parametersWithPackageName:params[@"packageName"]]; + + NSString *fallbackUrl = params[@"fallbackUrl"]; + NSNumber *minimumVersion = params[@"minimumVersion"]; + + if (![fallbackUrl isEqual:[NSNull null]]) + androidParams.fallbackURL = [NSURL URLWithString:fallbackUrl]; + if (![minimumVersion isEqual:[NSNull null]]) + androidParams.minimumVersion = ((NSNumber *)minimumVersion).integerValue; + + components.androidParameters = androidParams; + } + + if (![arguments[@"dynamicLinkComponentsOptions"] isEqual:[NSNull null]]) { + components.options = [self setupOptions:arguments]; + } + + if (![arguments[@"googleAnalyticsParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"googleAnalyticsParameters"]; + + FIRDynamicLinkGoogleAnalyticsParameters *googleAnalyticsParameters = + [FIRDynamicLinkGoogleAnalyticsParameters parameters]; + + NSString *campaign = params[@"campaign"]; + NSString *content = params[@"content"]; + NSString *medium = params[@"medium"]; + NSString *source = params[@"source"]; + NSString *term = params[@"term"]; + + if (![campaign isEqual:[NSNull null]]) googleAnalyticsParameters.campaign = campaign; + if (![content isEqual:[NSNull null]]) googleAnalyticsParameters.content = content; + if (![medium isEqual:[NSNull null]]) googleAnalyticsParameters.medium = medium; + if (![source isEqual:[NSNull null]]) googleAnalyticsParameters.source = source; + if (![term isEqual:[NSNull null]]) googleAnalyticsParameters.term = term; + + components.analyticsParameters = googleAnalyticsParameters; + } + + if (![arguments[@"iosParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"iosParameters"]; + + FIRDynamicLinkIOSParameters *iosParameters = + [FIRDynamicLinkIOSParameters parametersWithBundleID:params[@"bundleId"]]; + + NSString *appStoreID = params[@"appStoreId"]; + NSString *customScheme = params[@"customScheme"]; + NSString *fallbackURL = params[@"fallbackUrl"]; + NSString *iPadBundleID = params[@"ipadBundleId"]; + NSString *iPadFallbackURL = params[@"ipadFallbackUrl"]; + NSString *minimumAppVersion = params[@"minimumVersion"]; + + if (![appStoreID isEqual:[NSNull null]]) iosParameters.appStoreID = appStoreID; + if (![customScheme isEqual:[NSNull null]]) iosParameters.customScheme = customScheme; + if (![fallbackURL isEqual:[NSNull null]]) + iosParameters.fallbackURL = [NSURL URLWithString:fallbackURL]; + if (![iPadBundleID isEqual:[NSNull null]]) iosParameters.iPadBundleID = iPadBundleID; + if (![iPadFallbackURL isEqual:[NSNull null]]) + iosParameters.iPadFallbackURL = [NSURL URLWithString:iPadFallbackURL]; + if (![minimumAppVersion isEqual:[NSNull null]]) + iosParameters.minimumAppVersion = minimumAppVersion; + + components.iOSParameters = iosParameters; + } + + if (![arguments[@"itunesConnectAnalyticsParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"itunesConnectAnalyticsParameters"]; + + FIRDynamicLinkItunesConnectAnalyticsParameters *itunesConnectAnalyticsParameters = + [FIRDynamicLinkItunesConnectAnalyticsParameters parameters]; + + NSString *affiliateToken = params[@"affiliateToken"]; + NSString *campaignToken = params[@"campaignToken"]; + NSString *providerToken = params[@"providerToken"]; + + if (![affiliateToken isEqual:[NSNull null]]) + itunesConnectAnalyticsParameters.affiliateToken = affiliateToken; + if (![campaignToken isEqual:[NSNull null]]) + itunesConnectAnalyticsParameters.campaignToken = campaignToken; + if (![providerToken isEqual:[NSNull null]]) + itunesConnectAnalyticsParameters.providerToken = providerToken; + + components.iTunesConnectParameters = itunesConnectAnalyticsParameters; + } + + if (![arguments[@"navigationInfoParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"navigationInfoParameters"]; + + FIRDynamicLinkNavigationInfoParameters *navigationInfoParameters = + [FIRDynamicLinkNavigationInfoParameters parameters]; + + NSNumber *forcedRedirectEnabled = params[@"forcedRedirectEnabled"]; + if (![forcedRedirectEnabled isEqual:[NSNull null]]) + navigationInfoParameters.forcedRedirectEnabled = [forcedRedirectEnabled boolValue]; + + components.navigationInfoParameters = navigationInfoParameters; + } + + if (![arguments[@"socialMetaTagParameters"] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[@"socialMetaTagParameters"]; + + FIRDynamicLinkSocialMetaTagParameters *socialMetaTagParameters = + [FIRDynamicLinkSocialMetaTagParameters parameters]; + + NSString *descriptionText = params[@"description"]; + NSString *imageURL = params[@"imageUrl"]; + NSString *title = params[@"title"]; + + if (![descriptionText isEqual:[NSNull null]]) + socialMetaTagParameters.descriptionText = descriptionText; + if (![imageURL isEqual:[NSNull null]]) + socialMetaTagParameters.imageURL = [NSURL URLWithString:imageURL]; + if (![title isEqual:[NSNull null]]) socialMetaTagParameters.title = title; + + components.socialMetaTagParameters = socialMetaTagParameters; + } + + return components; +} + +@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/firebase_dynamic_links.podspec b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/firebase_dynamic_links.podspec new file mode 100644 index 000000000000..ec91d04c6800 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/firebase_dynamic_links.podspec @@ -0,0 +1,39 @@ +require 'yaml' + +pubspec = YAML.load_file(File.join('..', 'pubspec.yaml')) +library_version = pubspec['version'].gsub('+', '-') + +if defined?($FirebaseSDKVersion) + Pod::UI.puts "#{pubspec['name']}: Using user specified Firebase SDK version '#{$FirebaseSDKVersion}'" + firebase_sdk_version = $FirebaseSDKVersion +else + firebase_core_script = File.join(File.expand_path('..', File.expand_path('..', File.dirname(__FILE__))), 'firebase_core/ios/firebase_sdk_version.rb') + if File.exist?(firebase_core_script) + require firebase_core_script + firebase_sdk_version = firebase_sdk_version! + Pod::UI.puts "#{pubspec['name']}: Using Firebase SDK version '#{firebase_sdk_version}' defined in 'firebase_core'" + end +end + +Pod::Spec.new do |s| + s.name = pubspec['name'] + s.version = library_version + s.summary = pubspec['description'] + s.description = pubspec['description'] + s.homepage = pubspec['homepage'] + s.license = { :file => '../LICENSE' } + s.author = 'The Chromium Authors' + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.ios.deployment_target = '10.0' + s.static_framework = true + s.dependency 'firebase_core' + s.dependency 'Firebase/DynamicLinks', firebase_sdk_version + + s.pod_target_xcconfig = { + 'GCC_PREPROCESSOR_DEFINITIONS' => "LIBRARY_VERSION=\\@\\\"#{library_version}\\\" LIBRARY_NAME=\\@\\\"flutter-fire-dl\\\"", + 'DEFINES_MODULE' => 'YES' + } +end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart new file mode 100644 index 000000000000..a7b7b5413ef9 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -0,0 +1,18 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +library firebase_dynamic_links; + +import 'dart:async'; + +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart' + show FirebasePluginPlatform; + +part 'src/dynamic_link_builder.dart'; +part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart new file mode 100644 index 000000000000..f2c9f2aa2df5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart @@ -0,0 +1,34 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of firebase_dynamic_links; + +/// The class used for Dynamic Link URL generation. +/// +/// Supports creation of short and long Dynamic Link URLs. +class DynamicLinkBuilder { + DynamicLinkBuilder._(this.dynamicLink, this._delegate) { + DynamicLinkBuilderPlatform.verifyExtends(_delegate); + } + + DynamicLinkBuilderPlatform _delegate; + FirebaseDynamicLinks dynamicLink; + + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + return _delegate.shortenUrl(url, options); + } + + Future buildUrl(BuildDynamicLinkParameters parameters) async { + return _delegate.buildUrl(parameters); + } + + Future buildShortLink(BuildDynamicLinkParameters parameters) async { + return _delegate.buildShortLink(parameters); + } +} + + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart new file mode 100644 index 000000000000..25a2da455bc5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -0,0 +1,76 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +part of firebase_dynamic_links; + +/// Firebase Dynamic Links API. +/// +/// You can get an instance by calling [FirebaseDynamicLinks.instance]. +class FirebaseDynamicLinks extends FirebasePluginPlatform { + FirebaseDynamicLinks._({required this.app}) + : super(app.name, 'plugins.flutter.io/firebase_dynamic_links'); + + static final Map _cachedInstances = {}; + + /// Returns an instance using the default [FirebaseApp]. + static FirebaseDynamicLinks get instance { + return FirebaseDynamicLinks.instanceFor( + app: Firebase.app(), + ); + } + + /// Returns an instance using a specified [FirebaseApp]. + static FirebaseDynamicLinks instanceFor({required FirebaseApp app}) { + if (_cachedInstances.containsKey(app.name)) { + return _cachedInstances[app.name]!; + } + + FirebaseDynamicLinks newInstance = FirebaseDynamicLinks._(app: app); + _cachedInstances[app.name] = newInstance; + + return newInstance; + } + + // Cached and lazily loaded instance of [FirebaseDynamicLinksPlatform] to avoid + // creating a [MethodChannelFirebaseDynamicLinks] when not needed or creating an + // instance with the default app before a user specifies an app. + FirebaseDynamicLinksPlatform? _delegatePackingProperty; + + FirebaseDynamicLinksPlatform get _delegate { + return _delegatePackingProperty ??= + FirebaseDynamicLinksPlatform.instanceFor(app: app); + } + + /// The [FirebaseApp] for this current [FirebaseDynamicLinks] instance. + FirebaseApp app; + + /// Attempts to retrieve the dynamic link which launched the app. + /// + /// This method always returns a Future. That Future completes to null if + /// there is no pending dynamic link or any call to this method after the + /// the first attempt. + Future getInitialLink() async { + return _delegate.getInitialLink(); + } + + /// Determine if the app has a pending dynamic link and provide access to + /// the dynamic link parameters. A pending dynamic link may have been + /// previously captured when a user clicked on a dynamic link, or + /// may be present in the dynamicLinkUri parameter. If both are present, + /// the previously captured dynamic link will take precedence. The captured + /// data will be removed after first access. + Future getDynamicLink(Uri url) async { + return _delegate.getDynamicLink(url); + } + + /// Listen to a stream for the latest dynamic link events + Stream onLink() { + return _delegate.onLink(); + } + + DynamicLinkBuilder createLink() { + return DynamicLinkBuilder._(this, _delegate.createLink()); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml new file mode 100644 index 000000000000..88f258774eee --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml @@ -0,0 +1,37 @@ +name: firebase_dynamic_links +description: + Flutter plugin for Google Dynamic Links for Firebase, an app solution for creating + and handling links across multiple platforms. +version: 2.0.11 +homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links +repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: ">=1.12.13+hotfix.5" + +dependencies: + firebase_core: ^1.8.0 + firebase_core_platform_interface: ^4.0.1 + flutter: + sdk: flutter + meta: ^1.3.0 + +dev_dependencies: + flutter_test: + sdk: flutter + mockito: ^5.0.0 + url_launcher: ^6.0.2 + +dependency_overrides: + firebase_dynamic_links_platform_interface: + path: ../firebase_dynamic_links_platform_interface + +flutter: + plugin: + platforms: + android: + package: io.flutter.plugins.firebasedynamiclinks + pluginClass: FirebaseDynamicLinksPlugin + ios: + pluginClass: FLTFirebaseDynamicLinksPlugin diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart new file mode 100644 index 000000000000..9879812c5856 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -0,0 +1,675 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$FirebaseDynamicLinks', () { + final List log = []; + + setUp(() { + FirebaseDynamicLinks.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + final Map returnUrl = { + 'url': 'google.com', + 'warnings': ['This is only a test link'], + }; + switch (methodCall.method) { + case 'DynamicLinkParameters#buildUrl': + return 'google.com'; + case 'DynamicLinkParameters#buildShortLink': + return returnUrl; + case 'DynamicLinkParameters#shortenUrl': + return returnUrl; + case 'FirebaseDynamicLinks#getInitialLink': + return { + 'link': 'https://google.com', + 'android': { + 'clickTimestamp': 1234567, + 'minimumVersion': 12, + }, + 'ios': { + 'minimumVersion': 'Version 12', + }, + }; + case 'FirebaseDynamicLinks#getDynamicLink': + return { + 'link': 'https://google.com', + }; + default: + return null; + } + }); + log.clear(); + }); + + group('getInitialLink', () { + test('link can be parsed', () async { + final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getInitialLink(); + + expect(data!.link, Uri.parse('https://google.com')); + + expect(data.android!.clickTimestamp, 1234567); + expect(data.android!.minimumVersion, 12); + + expect(data.ios!.minimumVersion, 'Version 12'); + + expect(log, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + + // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() + // might return null link. In such a case we want to ignore the deep-link. + test('for null link, returns null', () async { + FirebaseDynamicLinks.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'FirebaseDynamicLinks#getInitialLink': + return { + 'link': null, + 'android': { + 'clickTimestamp': 1234567, + 'minimumVersion': 12, + }, + 'ios': { + 'minimumVersion': 'Version 12', + }, + }; + default: + return null; + } + }); + + final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getInitialLink(); + + expect(data, isNull); + + expect(log, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + + test('for null result, returns null', () async { + FirebaseDynamicLinks.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + log.add(methodCall); + switch (methodCall.method) { + case 'FirebaseDynamicLinks#getInitialLink': + return null; + default: + return null; + } + }); + + final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getInitialLink(); + + expect(data, isNull); + + expect(log, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + }); + + test('getDynamicLink', () async { + final Uri argument = Uri.parse('short-link'); + final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getDynamicLink(argument); + + expect(data!.link.host, 'google.com'); + + expect(log, [ + isMethodCall('FirebaseDynamicLinks#getDynamicLink', + arguments: { + 'url': argument.toString(), + }) + ]); + }); + + group('$DynamicLinkBuilder', () { + test('shortenUrl', () async { + final Uri url = Uri.parse('google.com'); + final DynamicLinkParametersOptions options = + DynamicLinkParametersOptions( + shortDynamicLinkPathLength: + ShortDynamicLinkPathLength.unguessable); + + await DynamicLinkBuilder.shortenUrl(url, options); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#shortenUrl', + arguments: { + 'url': url.toString(), + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, + }, + }, + ), + ]); + }); + + test('$AndroidParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + androidParameters: AndroidParameters( + fallbackUrl: Uri.parse('test-url'), + minimumVersion: 1, + packageName: 'test-package', + ), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': { + 'fallbackUrl': 'test-url', + 'minimumVersion': 1, + 'packageName': 'test-package', + }, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': { + 'fallbackUrl': 'test-url', + 'minimumVersion': 1, + 'packageName': 'test-package', + }, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$DynamicLinkParametersOptions', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + dynamicLinkParametersOptions: DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.short.index, + }, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.short.index, + }, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$ShortDynamicLinkPathLength', () { + expect(ShortDynamicLinkPathLength.unguessable.index, 0); + expect(ShortDynamicLinkPathLength.short.index, 1); + }); + + test('$GoogleAnalyticsParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + googleAnalyticsParameters: GoogleAnalyticsParameters( + campaign: 'where', + content: 'is', + medium: 'my', + source: 'cat', + term: 'friend', + ), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': { + 'campaign': 'where', + 'content': 'is', + 'medium': 'my', + 'source': 'cat', + 'term': 'friend', + }, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': { + 'campaign': 'where', + 'content': 'is', + 'medium': 'my', + 'source': 'cat', + 'term': 'friend', + }, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$IosParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + iosParameters: IosParameters( + appStoreId: 'is', + bundleId: 'this', + customScheme: 'the', + fallbackUrl: Uri.parse('place'), + ipadBundleId: 'to', + ipadFallbackUrl: Uri.parse('find'), + minimumVersion: 'potatoes', + ), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': { + 'appStoreId': 'is', + 'bundleId': 'this', + 'customScheme': 'the', + 'fallbackUrl': 'place', + 'ipadBundleId': 'to', + 'ipadFallbackUrl': 'find', + 'minimumVersion': 'potatoes', + }, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': { + 'appStoreId': 'is', + 'bundleId': 'this', + 'customScheme': 'the', + 'fallbackUrl': 'place', + 'ipadBundleId': 'to', + 'ipadFallbackUrl': 'find', + 'minimumVersion': 'potatoes', + }, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$ItunesConnectAnalyticsParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( + affiliateToken: 'hello', + campaignToken: 'mister', + providerToken: 'rose', + ), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'hello', + 'campaignToken': 'mister', + 'providerToken': 'rose', + }, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'hello', + 'campaignToken': 'mister', + 'providerToken': 'rose', + }, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$NavigationInfoParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + navigationInfoParameters: + NavigationInfoParameters(forcedRedirectEnabled: true), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': null, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': null, + }, + ), + ]); + }); + + test('$SocialMetaTagParameters', () async { + final DynamicLinkBuilder components = DynamicLinkBuilder( + uriPrefix: 'https://test-domain/', + link: Uri.parse('test-link.com'), + socialMetaTagParameters: SocialMetaTagParameters( + description: 'describe', + imageUrl: Uri.parse('thisimage'), + title: 'bro', + ), + ); + + await components.buildUrl(); + await components.buildShortLink(); + + expect(log, [ + isMethodCall( + 'DynamicLinkParameters#buildUrl', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': { + 'description': 'describe', + 'imageUrl': 'thisimage', + 'title': 'bro', + }, + }, + ), + isMethodCall( + 'DynamicLinkParameters#buildShortLink', + arguments: { + 'androidParameters': null, + 'uriPrefix': 'https://test-domain/', + 'dynamicLinkParametersOptions': null, + 'googleAnalyticsParameters': null, + 'iosParameters': null, + 'itunesConnectAnalyticsParameters': null, + 'link': 'test-link.com', + 'navigationInfoParameters': null, + 'socialMetaTagParameters': { + 'description': 'describe', + 'imageUrl': 'thisimage', + 'title': 'bro', + }, + }, + ), + ]); + }); + }); + + group('onLink', () { + OnLinkSuccessCallback? onSuccess; + OnLinkErrorCallback? onError; + final List successLog = + []; + final List errorLog = []; + setUp(() { + onSuccess = (linkData) async { + successLog.add(linkData); + }; + onError = (error) async { + errorLog.add(error); + }; + successLog.clear(); + errorLog.clear(); + }); + + Future callMethodHandler(String method, dynamic arguments) { + const channel = FirebaseDynamicLinks.channel; + final methodCall = MethodCall(method, arguments); + final data = channel.codec.encodeMethodCall(methodCall); + final Completer completer = Completer(); + channel.binaryMessenger.handlePlatformMessage( + channel.name, + data, + (data) { + completer.complete(null); + }, + ); + return completer.future; + } + + test('onSuccess', () async { + FirebaseDynamicLinks.instance + .onLink(onSuccess: onSuccess, onError: onError); + await callMethodHandler('onLinkSuccess', { + 'link': 'https://google.com', + 'android': { + 'clickTimestamp': 1234567, + 'minimumVersion': 12, + }, + 'ios': { + 'minimumVersion': 'Version 12', + }, + }); + + expect(successLog, hasLength(1)); + expect(errorLog, hasLength(0)); + final success = successLog[0]!; + + expect(success.link, Uri.parse('https://google.com')); + + expect(success.android!.clickTimestamp, 1234567); + expect(success.android!.minimumVersion, 12); + + expect(success.ios!.minimumVersion, 'Version 12'); + }); + + test('onSuccess with null link', () async { + FirebaseDynamicLinks.instance + .onLink(onSuccess: onSuccess, onError: onError); + await callMethodHandler('onLinkSuccess', { + 'link': null, + 'android': { + 'clickTimestamp': 1234567, + 'minimumVersion': 12, + }, + 'ios': { + 'minimumVersion': 'Version 12', + }, + }); + + expect(successLog, hasLength(1)); + expect(errorLog, hasLength(0)); + final success = successLog[0]; + + expect(success, isNull); + }); + + test('onSuccess with null', () async { + FirebaseDynamicLinks.instance + .onLink(onSuccess: onSuccess, onError: onError); + await callMethodHandler('onLinkSuccess', null); + + expect(successLog, hasLength(1)); + expect(errorLog, hasLength(0)); + final success = successLog[0]; + + expect(success, isNull); + }); + + test('onError', () async { + FirebaseDynamicLinks.instance + .onLink(onSuccess: onSuccess, onError: onError); + await callMethodHandler('onLinkError', { + 'code': 'code', + 'message': 'message', + 'details': 'details', + }); + + expect(successLog, hasLength(0)); + expect(errorLog, hasLength(1)); + final failure = errorLog[0]; + expect(failure.code, 'code'); + expect(failure.message, 'message'); + expect(failure.details, 'details'); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml new file mode 100644 index 000000000000..9e4e7a8cdc31 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml @@ -0,0 +1,23 @@ +name: firebase_dynamic_links_platform_interface +description: A common platform interface for the firebase_dynamic_links plugin. +version: 0.0.1 +homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface +repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface + +environment: + sdk: ">=2.12.0 <3.0.0" + flutter: ">=1.9.1+hotfix.5" + +dependencies: + firebase_core: ^1.8.0 + flutter: + sdk: flutter + meta: ^1.3.0 + plugin_platform_interface: ^2.0.0 + + +dev_dependencies: + firebase_core_platform_interface: ^4.0.1 + flutter_test: + sdk: flutter + mockito: ^5.0.0 From dbb6061afcaeed9eba0fe27dde40de098245bd71 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 2 Nov 2021 10:49:27 +0000 Subject: [PATCH 005/125] refactor(dynamic_links, android): rewire streamHandler --- .../FirebaseDynamicLinksPlugin.java | 265 ++++++++---------- .../GetLinkStreamHandler.java | 49 ++-- .../plugins/firebasedynamiclinks/Utils.java | 7 +- 3 files changed, 135 insertions(+), 186 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index 7ab68ec43d8b..430e9323c248 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -7,36 +7,27 @@ import android.app.Activity; import android.content.Intent; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import com.google.android.gms.tasks.OnCompleteListener; -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.TaskCompletionSource; import com.google.android.gms.tasks.Tasks; import com.google.firebase.FirebaseApp; import com.google.firebase.dynamiclinks.DynamicLink; import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; import com.google.firebase.dynamiclinks.PendingDynamicLinkData; import com.google.firebase.dynamiclinks.ShortDynamicLink; - import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.EventChannel.StreamHandler; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; -import io.flutter.plugin.common.EventChannel.StreamHandler; import io.flutter.plugin.common.PluginRegistry.NewIntentListener; import io.flutter.plugins.firebase.core.FlutterFirebasePlugin; import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -44,25 +35,21 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; - public class FirebaseDynamicLinksPlugin - implements FlutterFirebasePlugin, FlutterPlugin, ActivityAware, MethodCallHandler, NewIntentListener { + implements FlutterFirebasePlugin, + FlutterPlugin, + ActivityAware, + MethodCallHandler, + NewIntentListener { private final AtomicReference activity = new AtomicReference<>(null); private MethodChannel channel; - @Nullable - private BinaryMessenger messenger; - - private final Map streamHandlers = new HashMap<>(); + @Nullable private BinaryMessenger messenger; + private final Map streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; - - private static MethodChannel createChannel(final BinaryMessenger messenger) { - return new MethodChannel(messenger, "plugins.flutter.io/firebase_dynamic_links"); - } - private void initInstance(BinaryMessenger messenger) { channel = new MethodChannel(messenger, METHOD_CHANNEL_NAME); channel.setMethodCallHandler(this); @@ -71,7 +58,6 @@ private void initInstance(BinaryMessenger messenger) { this.messenger = messenger; } - @Override public void onAttachedToEngine(FlutterPluginBinding binding) { initInstance(binding.getBinaryMessenger()); @@ -82,14 +68,12 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { channel.setMethodCallHandler(null); channel = null; messenger = null; -//TODO add this for listening to events -// removeEventListeners(); + removeEventListeners(); } @Override public void onAttachedToActivity(ActivityPluginBinding binding) { activity.set(binding.getActivity()); - //TODO make sure I'm using this feature. if not, remove. binding.addOnNewIntentListener(this); } @@ -120,38 +104,15 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments return FirebaseDynamicLinks.getInstance(app); } - //TODO make sure I'm using this properly @Override public boolean onNewIntent(Intent intent) { - FirebaseDynamicLinks.getInstance() - .getDynamicLink(intent) - .addOnSuccessListener( - new OnSuccessListener() { - @Override - public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) { - if (pendingDynamicLinkData != null) { - Map dynamicLink = - Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - channel.invokeMethod("onLinkSuccess", dynamicLink); - } - } - }) - .addOnFailureListener( - new OnFailureListener() { - @Override - public void onFailure(Exception e) { - Map exception = new HashMap<>(); - exception.put("code", e.getClass().getSimpleName()); - exception.put("message", e.getMessage()); - exception.put("details", null); - channel.invokeMethod("onLinkError", exception); - } - }); - + // Passes intent to every listener for different app instances the user may create + for (GetLinkStreamHandler instance : streamHandlers.values()) { + instance.sinkEvent(intent); + } return false; } - @Override public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result result) { Task methodCallTask; @@ -175,26 +136,27 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re methodCallTask = getDynamicLink(dynamicLinks, call.argument("url")); break; case "FirebaseDynamicLinks#onLink": - methodCallTask = registerGetLinkListener(Objects.requireNonNull(call.argument(Constants.APP_NAME)), dynamicLinks); + methodCallTask = + registerGetLinkListener( + Objects.requireNonNull(call.argument(Constants.APP_NAME)), dynamicLinks); break; default: result.notImplemented(); return; } - methodCallTask.addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - result.success(task.getResult()); - } else { - Exception exception = task.getException(); - result.error( - Constants.DEFAULT_ERROR_CODE, - exception != null ? exception.getMessage() : null, - Utils.getExceptionDetails(exception)); - } - }); + task -> { + if (task.isSuccessful()) { + result.success(task.getResult()); + } else { + Exception exception = task.getException(); + result.error( + Constants.DEFAULT_ERROR_CODE, + exception != null ? exception.getMessage() : null, + Utils.getExceptionDetails(exception)); + } + }); } private String buildUrl(Map arguments) { @@ -203,70 +165,71 @@ private String buildUrl(Map arguments) { return urlBuilder.buildDynamicLink().getUri().toString(); } - private Task> buildShortLink(DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { + private Task> buildShortLink( + DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { return Tasks.call( - cachedThreadPool, - () -> { - Integer suffix = null; - - if (dynamicLinkParametersOptions != null) { - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); - if (shortDynamicLinkPathLength != null) { - switch (shortDynamicLinkPathLength) { - case 0: - suffix = ShortDynamicLink.Suffix.UNGUESSABLE; - break; - case 1: - suffix = ShortDynamicLink.Suffix.SHORT; - break; - default: - break; + cachedThreadPool, + () -> { + Integer suffix = null; + + if (dynamicLinkParametersOptions != null) { + Integer shortDynamicLinkPathLength = + (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); + if (shortDynamicLinkPathLength != null) { + switch (shortDynamicLinkPathLength) { + case 0: + suffix = ShortDynamicLink.Suffix.UNGUESSABLE; + break; + case 1: + suffix = ShortDynamicLink.Suffix.SHORT; + break; + default: + break; + } } } - } - - Map result = new HashMap<>(); - ShortDynamicLink shortLink; - if (suffix != null) { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); - } else { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); - } - List warnings = new ArrayList<>(); - - for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { - warnings.add(warning.getMessage()); - } - - result.put("url", shortLink.getShortLink()); - result.put("warnings", warnings); - result.put("previewLink", shortLink.getPreviewLink()); - - return result; - } - ); + + Map result = new HashMap<>(); + ShortDynamicLink shortLink; + if (suffix != null) { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); + } else { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); + } + List warnings = new ArrayList<>(); + + for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { + warnings.add(warning.getMessage()); + } + + result.put("url", shortLink.getShortLink()); + result.put("warnings", warnings); + result.put("previewLink", shortLink.getPreviewLink()); + + return result; + }); } - private Task> getDynamicLink(FirebaseDynamicLinks dynamicLinks, @Nullable String url) { + private Task> getDynamicLink( + FirebaseDynamicLinks dynamicLinks, @Nullable String url) { return Tasks.call( - cachedThreadPool, - () -> { - PendingDynamicLinkData pendingDynamicLink; - - if (url != null) { - pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); - } else { - // If there's no activity or initial Intent, then there's no initial dynamic link. - if (activity.get() == null || activity.get().getIntent() == null) { - return null; + cachedThreadPool, + () -> { + PendingDynamicLinkData pendingDynamicLink; + + if (url != null) { + pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); + } else { + // If there's no activity or initial Intent, then there's no initial dynamic link. + if (activity.get() == null || activity.get().getIntent() == null) { + return null; + } + pendingDynamicLink = + Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } - pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); - } - return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); - } - ); + return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + }); } private DynamicLink.Builder setupParameters(Map arguments) { @@ -278,14 +241,15 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setDomainUriPrefix(uriPrefix); dynamicLinkBuilder.setLink(Uri.parse(link)); - Map androidParameters = (Map) arguments.get("androidParameters"); + Map androidParameters = + (Map) arguments.get("androidParameters"); if (androidParameters != null) { String packageName = valueFor("packageName", androidParameters); String fallbackUrl = valueFor("fallbackUrl", androidParameters); Integer minimumVersion = valueFor("minimumVersion", androidParameters); DynamicLink.AndroidParameters.Builder builder = - new DynamicLink.AndroidParameters.Builder(packageName); + new DynamicLink.AndroidParameters.Builder(packageName); if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); @@ -293,7 +257,8 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setAndroidParameters(builder.build()); } - Map googleAnalyticsParameters = (Map) arguments.get("googleAnalyticsParameters"); + Map googleAnalyticsParameters = + (Map) arguments.get("googleAnalyticsParameters"); if (googleAnalyticsParameters != null) { String campaign = valueFor("campaign", googleAnalyticsParameters); String content = valueFor("content", googleAnalyticsParameters); @@ -302,7 +267,7 @@ private DynamicLink.Builder setupParameters(Map arguments) { String term = valueFor("term", googleAnalyticsParameters); DynamicLink.GoogleAnalyticsParameters.Builder builder = - new DynamicLink.GoogleAnalyticsParameters.Builder(); + new DynamicLink.GoogleAnalyticsParameters.Builder(); if (campaign != null) builder.setCampaign(campaign); if (content != null) builder.setContent(content); @@ -335,15 +300,15 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setIosParameters(builder.build()); } - Map itunesConnectAnalyticsParameters = (Map) - arguments.get("itunesConnectAnalyticsParameters"); + Map itunesConnectAnalyticsParameters = + (Map) arguments.get("itunesConnectAnalyticsParameters"); if (itunesConnectAnalyticsParameters != null) { String affiliateToken = valueFor("affiliateToken", itunesConnectAnalyticsParameters); String campaignToken = valueFor("campaignToken", itunesConnectAnalyticsParameters); String providerToken = valueFor("providerToken", itunesConnectAnalyticsParameters); DynamicLink.ItunesConnectAnalyticsParameters.Builder builder = - new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); + new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); if (affiliateToken != null) builder.setAffiliateToken(affiliateToken); if (campaignToken != null) builder.setCampaignToken(campaignToken); @@ -352,26 +317,28 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setItunesConnectAnalyticsParameters(builder.build()); } - Map navigationInfoParameters = (Map) arguments.get("navigationInfoParameters"); + Map navigationInfoParameters = + (Map) arguments.get("navigationInfoParameters"); if (navigationInfoParameters != null) { Boolean forcedRedirectEnabled = valueFor("forcedRedirectEnabled", navigationInfoParameters); DynamicLink.NavigationInfoParameters.Builder builder = - new DynamicLink.NavigationInfoParameters.Builder(); + new DynamicLink.NavigationInfoParameters.Builder(); if (forcedRedirectEnabled != null) builder.setForcedRedirectEnabled(forcedRedirectEnabled); dynamicLinkBuilder.setNavigationInfoParameters(builder.build()); } - Map socialMetaTagParameters = (Map) arguments.get("socialMetaTagParameters"); + Map socialMetaTagParameters = + (Map) arguments.get("socialMetaTagParameters"); if (socialMetaTagParameters != null) { String description = valueFor("description", socialMetaTagParameters); String imageUrl = valueFor("imageUrl", socialMetaTagParameters); String title = valueFor("title", socialMetaTagParameters); DynamicLink.SocialMetaTagParameters.Builder builder = - new DynamicLink.SocialMetaTagParameters.Builder(); + new DynamicLink.SocialMetaTagParameters.Builder(); if (description != null) builder.setDescription(description); if (imageUrl != null) builder.setImageUrl(Uri.parse(imageUrl)); @@ -383,17 +350,18 @@ private DynamicLink.Builder setupParameters(Map arguments) { return dynamicLinkBuilder; } - private Task registerGetLinkListener(@NonNull String appName, FirebaseDynamicLinks dynamicLinks) { + private Task registerGetLinkListener( + @NonNull String appName, FirebaseDynamicLinks dynamicLinks) { return Tasks.call( - cachedThreadPool, - () -> { - final GetLinkStreamHandler handler = new GetLinkStreamHandler(dynamicLinks); - final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; - final EventChannel channel = new EventChannel(messenger, name); - channel.setStreamHandler(handler); - streamHandlers.put(channel, handler); - return name; - }); + cachedThreadPool, + () -> { + final GetLinkStreamHandler handler = new GetLinkStreamHandler(dynamicLinks); + final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; + final EventChannel channel = new EventChannel(messenger, name); + channel.setStreamHandler(handler); + streamHandlers.put(channel, handler); + return name; + }); } private static T valueFor(String key, Map map) { @@ -410,20 +378,21 @@ public Task> getPluginConstantsForFirebaseApp(FirebaseApp fi @Override public Task didReinitializeFirebaseCore() { return Tasks.call( - cachedThreadPool, - () -> { - removeEventListeners(); - return null; - }); + cachedThreadPool, + () -> { + removeEventListeners(); + return null; + }); } - private void removeEventListeners(){ + private void removeEventListeners() { for (EventChannel eventChannel : streamHandlers.keySet()) { StreamHandler streamHandler = streamHandlers.get(eventChannel); assert streamHandler != null; streamHandler.onCancel(null); eventChannel.setStreamHandler(null); } + streamHandlers.clear(); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java index 8e7573f7be7e..9bce7a995af4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java @@ -1,25 +1,12 @@ package io.flutter.plugins.firebasedynamiclinks; import android.content.Intent; - -import androidx.annotation.NonNull; - -import com.google.android.gms.tasks.OnFailureListener; -import com.google.android.gms.tasks.OnSuccessListener; import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import com.google.firebase.dynamiclinks.PendingDynamicLinkData; - import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel.StreamHandler; - -import java.util.HashMap; import java.util.Map; -import io.flutter.plugin.common.PluginRegistry.NewIntentListener; - -public class GetLinkStreamHandler implements NewIntentListener, StreamHandler { - - +public class GetLinkStreamHandler implements StreamHandler { private EventChannel.EventSink events; private final FirebaseDynamicLinks dynamicLinks; @@ -27,25 +14,21 @@ public GetLinkStreamHandler(FirebaseDynamicLinks dynamicLinks) { this.dynamicLinks = dynamicLinks; } - @Override - public boolean onNewIntent(Intent intent) { + public void sinkEvent(Intent intent) { dynamicLinks - .getDynamicLink(intent) - .addOnSuccessListener( - pendingDynamicLinkData -> { - Map dynamicLink = - Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - - events.success(dynamicLink); - }) - .addOnFailureListener( - exception -> events.error( - Constants.DEFAULT_ERROR_CODE, - exception.getMessage(), - Utils.getExceptionDetails(exception) - )); - - return false; + .getDynamicLink(intent) + .addOnSuccessListener( + pendingDynamicLinkData -> { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + events.success(dynamicLink); + }) + .addOnFailureListener( + exception -> + events.error( + Constants.DEFAULT_ERROR_CODE, + exception.getMessage(), + Utils.getExceptionDetails(exception))); } @Override @@ -55,6 +38,6 @@ public void onListen(Object arguments, EventChannel.EventSink events) { @Override public void onCancel(Object arguments) { - + // do nothing } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java index 5c5666e792b2..4fa5e8b17581 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java @@ -1,11 +1,8 @@ package io.flutter.plugins.firebasedynamiclinks; import android.net.Uri; - import androidx.annotation.Nullable; - import com.google.firebase.dynamiclinks.PendingDynamicLinkData; - import java.util.HashMap; import java.util.Map; @@ -22,7 +19,7 @@ static Map getExceptionDetails(@Nullable Exception exception) { } static Map getMapFromPendingDynamicLinkData( - PendingDynamicLinkData pendingDynamicLinkData) { + PendingDynamicLinkData pendingDynamicLinkData) { Map dynamicLink = new HashMap<>(); Uri link = pendingDynamicLinkData.getLink(); @@ -30,7 +27,7 @@ static Map getMapFromPendingDynamicLinkData( Map utmParameters = new HashMap<>(); - for(String key : pendingDynamicLinkData.getUtmParameters().keySet()){ + for (String key : pendingDynamicLinkData.getUtmParameters().keySet()) { utmParameters.put(key, pendingDynamicLinkData.getUtmParameters().get(key).toString()); } From 71adce8fe9efa1c913b34d58b04e52c43ff51819 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 2 Nov 2021 10:49:54 +0000 Subject: [PATCH 006/125] chore: format run formatter --- .../lib/src/dynamic_link_builder.dart | 6 ++--- .../lib/src/firebase_dynamic_links.dart | 2 +- .../lib/src/android_parameters.dart | 9 ++++---- .../src/build_dynamic_link_parameters.dart | 22 +++++++++---------- .../src/dynamic_link_parameter_options.dart | 5 +++-- .../lib/src/google_analytics_parameters.dart | 12 +++++----- .../lib/src/ios_parameters.dart | 16 +++++++------- .../itunes_connect_analytics_parameters.dart | 8 +++---- .../method_channel_dynamic_link_builder.dart | 21 +++++++++++------- .../lib/src/navigation_info_parameters.dart | 4 ++-- .../lib/src/pending_dynamic_link_data.dart | 1 + .../pending_dynamic_link_data_android.dart | 6 ++--- .../src/pending_dynamic_link_data_ios.dart | 2 -- ...atform_interface_dynamic_link_builder.dart | 3 ++- ...form_interface_firebase_dynamic_links.dart | 4 ++-- .../lib/src/social_meta_tag_parameters.dart | 8 +++---- .../Classes/FLTFirebaseRemoteConfigUtils.h | 2 +- 17 files changed, 67 insertions(+), 64 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart index f2c9f2aa2df5..ec0f21f39e85 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart @@ -25,10 +25,8 @@ class DynamicLinkBuilder { return _delegate.buildUrl(parameters); } - Future buildShortLink(BuildDynamicLinkParameters parameters) async { + Future buildShortLink( + BuildDynamicLinkParameters parameters) async { return _delegate.buildShortLink(parameters); } } - - - diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 25a2da455bc5..0dd72d68531d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -71,6 +71,6 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } DynamicLinkBuilder createLink() { - return DynamicLinkBuilder._(this, _delegate.createLink()); + return DynamicLinkBuilder._(this, _delegate.createLink()); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart index a7340f76cadc..e7f3b8d3b708 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -1,4 +1,3 @@ - /// The Dynamic Link Android parameters. class AndroidParameters { const AndroidParameters( @@ -21,8 +20,8 @@ class AndroidParameters { final String packageName; Map get data => { - 'fallbackUrl': fallbackUrl?.toString(), - 'minimumVersion': minimumVersion, - 'packageName': packageName, - }; + 'fallbackUrl': fallbackUrl?.toString(), + 'minimumVersion': minimumVersion, + 'packageName': packageName, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart index 8801cda42f22..bebd9a35f397 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart @@ -62,17 +62,17 @@ class BuildDynamicLinkParameters { /// Returns the current instance as a [Map]. Map asMap() => { - 'androidParameters': androidParameters?.data, - 'uriPrefix': uriPrefix, - 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, - 'googleAnalyticsParameters': googleAnalyticsParameters?.data, - 'iosParameters': iosParameters?.data, - 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?.data, - 'link': link.toString(), - 'navigationInfoParameters': navigationInfoParameters?.data, - 'socialMetaTagParameters': socialMetaTagParameters?.data, - }; + 'androidParameters': androidParameters?.data, + 'uriPrefix': uriPrefix, + 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, + 'googleAnalyticsParameters': googleAnalyticsParameters?.data, + 'iosParameters': iosParameters?.data, + 'itunesConnectAnalyticsParameters': + itunesConnectAnalyticsParameters?.data, + 'link': link.toString(), + 'navigationInfoParameters': navigationInfoParameters?.data, + 'socialMetaTagParameters': socialMetaTagParameters?.data, + }; @override String toString() { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart index 9fb57224449d..591b787ccc0e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart @@ -1,4 +1,5 @@ import 'short_dynamic_link_path_length.dart'; + /// Options class for defining how Dynamic Link URLs are generated. class DynamicLinkParametersOptions { const DynamicLinkParametersOptions({this.shortDynamicLinkPathLength}); @@ -7,6 +8,6 @@ class DynamicLinkParametersOptions { final ShortDynamicLinkPathLength? shortDynamicLinkPathLength; Map get data => { - 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, - }; + 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart index 7f13f847df1b..999e94e24a8b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart @@ -31,10 +31,10 @@ class GoogleAnalyticsParameters { final String? term; Map get data => { - 'campaign': campaign, - 'content': content, - 'medium': medium, - 'source': source, - 'term': term, - }; + 'campaign': campaign, + 'content': content, + 'medium': medium, + 'source': source, + 'term': term, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart index 515c20fdd1f4..0b8bc0594e91 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart @@ -47,12 +47,12 @@ class IosParameters { final String? minimumVersion; Map get data => { - 'appStoreId': appStoreId, - 'bundleId': bundleId, - 'customScheme': customScheme, - 'fallbackUrl': fallbackUrl?.toString(), - 'ipadBundleId': ipadBundleId, - 'ipadFallbackUrl': ipadFallbackUrl?.toString(), - 'minimumVersion': minimumVersion, - }; + 'appStoreId': appStoreId, + 'bundleId': bundleId, + 'customScheme': customScheme, + 'fallbackUrl': fallbackUrl?.toString(), + 'ipadBundleId': ipadBundleId, + 'ipadFallbackUrl': ipadFallbackUrl?.toString(), + 'minimumVersion': minimumVersion, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart index 2136d6de73dc..dbad99ab879d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -13,8 +13,8 @@ class ItunesConnectAnalyticsParameters { final String? providerToken; Map get data => { - 'affiliateToken': affiliateToken, - 'campaignToken': campaignToken, - 'providerToken': providerToken, - }; + 'affiliateToken': affiliateToken, + 'campaignToken': campaignToken, + 'providerToken': providerToken, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart index fc0f00d06189..7d3f0f973c1c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart @@ -11,7 +11,8 @@ import 'package:firebase_dynamic_links_platform_interface/src/platform_interface import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { - MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks) : super(dynamicLinks); + MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks) + : super(dynamicLinks); /// Attaches generic default values to method channel arguments. Map _withChannelDefaults(Map other) { @@ -37,21 +38,25 @@ class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { @override Future buildUrl(BuildDynamicLinkParameters parameters) async { final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('DynamicLinkParameters#buildUrl', _withChannelDefaults(parameters.asMap())); + .invokeMethod('DynamicLinkParameters#buildUrl', + _withChannelDefaults(parameters.asMap())); return Uri.parse(url!); } @override - Future buildShortLink(BuildDynamicLinkParameters parameters) async { - final Map? response = await MethodChannelFirebaseDynamicLinks.channel - .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', _withChannelDefaults(parameters.asMap())); + Future buildShortLink( + BuildDynamicLinkParameters parameters) async { + final Map? response = + await MethodChannelFirebaseDynamicLinks.channel + .invokeMapMethod( + 'DynamicLinkParameters#buildShortLink', + _withChannelDefaults(parameters.asMap())); return _parseShortLink(response!); } - ShortDynamicLink _parseShortLink(Map response) { final List? warnings = response['warnings']; - return ShortDynamicLink(Uri.parse(response['url']), warnings?.cast(), response['previewLink']); + return ShortDynamicLink( + Uri.parse(response['url']), warnings?.cast(), response['previewLink']); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart index fdd74c19b57b..0a3595d35d94 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart @@ -14,6 +14,6 @@ class NavigationInfoParameters { final bool? forcedRedirectEnabled; Map get data => { - 'forcedRedirectEnabled': forcedRedirectEnabled, - }; + 'forcedRedirectEnabled': forcedRedirectEnabled, + }; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart index 92d7c6b241b9..57b0437ab3ea 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -1,5 +1,6 @@ import 'pending_dynamic_link_data_android.dart'; import 'pending_dynamic_link_data_ios.dart'; + /// Provides data from received dynamic link. class PendingDynamicLinkData { const PendingDynamicLinkData(this.link, this.android, this.ios); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart index ad15088278ec..02fffd48a32a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart @@ -1,9 +1,9 @@ /// Provides android specific data from received dynamic link. class PendingDynamicLinkDataAndroid { const PendingDynamicLinkDataAndroid( - this.clickTimestamp, - this.minimumVersion, - ); + this.clickTimestamp, + this.minimumVersion, + ); /// The time the user clicked on the dynamic link. /// diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart index 04ad0db88bba..cbe4c4fe3c43 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -8,5 +8,3 @@ class PendingDynamicLinkDataIOS { /// declares higher [minimumVersion] than currently installed. final String? minimumVersion; } - - diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart index 209a62ca3d03..509a61f87e4d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart @@ -43,7 +43,8 @@ abstract class DynamicLinkBuilderPlatform extends PlatformInterface { } /// Generate a short Dynamic Link URL. - Future buildShortLink(BuildDynamicLinkParameters parameters) async { + Future buildShortLink( + BuildDynamicLinkParameters parameters) async { throw UnimplementedError('buildShortLink() is not implemented'); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 7d761d3a4c8d..8bda1ab1206e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -60,7 +60,7 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('delegateFor() is not implemented'); } - Future getInitialLink(){ + Future getInitialLink() { throw UnimplementedError('getInitialLink() is not implemented'); } @@ -73,7 +73,7 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('onLink() is not implemented'); } - DynamicLinkBuilderPlatform createLink(){ + DynamicLinkBuilderPlatform createLink() { throw UnimplementedError('createLink() is not implemented'); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart index 3872bb7f11a7..209bd7749a97 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart @@ -12,8 +12,8 @@ class SocialMetaTagParameters { final String? title; Map get data => { - 'description': description, - 'imageUrl': imageUrl?.toString(), - 'title': title, - }; + 'description': description, + 'imageUrl': imageUrl?.toString(), + 'title': title, + }; } diff --git a/packages/firebase_remote_config/firebase_remote_config/ios/Classes/FLTFirebaseRemoteConfigUtils.h b/packages/firebase_remote_config/firebase_remote_config/ios/Classes/FLTFirebaseRemoteConfigUtils.h index 7846cf25621c..b66b368582b8 100644 --- a/packages/firebase_remote_config/firebase_remote_config/ios/Classes/FLTFirebaseRemoteConfigUtils.h +++ b/packages/firebase_remote_config/firebase_remote_config/ios/Classes/FLTFirebaseRemoteConfigUtils.h @@ -1,8 +1,8 @@ // Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import #import +#import @interface FLTFirebaseRemoteConfigUtils : NSObject + (NSDictionary *)ErrorCodeAndMessageFromNSError:(NSError *)error; From 9d97169d3a1e92b5a811e7334201a68b66ca51e2 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:10:26 +0000 Subject: [PATCH 007/125] chore: not in android util --- .../java/io/flutter/plugins/firebasedynamiclinks/Utils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java index 4fa5e8b17581..6efd8638533c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java @@ -9,7 +9,9 @@ public class Utils { static Map getExceptionDetails(@Nullable Exception exception) { Map details = new HashMap<>(); - details.put("code", "unknown"); + // There aren't any Dynamic Link Exceptions in the reference: + // https://firebase.google.com/docs/reference/android/com/google/firebase/dynamiclinks/package-summary + details.put("code", "unknown"); if (exception != null) { details.put("message", exception.getMessage()); } else { From 644bd3c5c0b45b21cab214c16ece72d5eab0523e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:11:21 +0000 Subject: [PATCH 008/125] refactor(dynamic_links, android): implement onLink stream handler --- .../FirebaseDynamicLinksPlugin.java | 12 +++--- .../OnLinkStreamHandler.java | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index 430e9323c248..cc2ff4b1b7b7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -46,7 +46,7 @@ public class FirebaseDynamicLinksPlugin private MethodChannel channel; @Nullable private BinaryMessenger messenger; - private final Map streamHandlers = new HashMap<>(); + private final Map streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -107,7 +107,7 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments @Override public boolean onNewIntent(Intent intent) { // Passes intent to every listener for different app instances the user may create - for (GetLinkStreamHandler instance : streamHandlers.values()) { + for (OnLinkStreamHandler instance : streamHandlers.values()) { instance.sinkEvent(intent); } return false; @@ -137,7 +137,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re break; case "FirebaseDynamicLinks#onLink": methodCallTask = - registerGetLinkListener( + registerOnLinkListener( Objects.requireNonNull(call.argument(Constants.APP_NAME)), dynamicLinks); break; default: @@ -233,7 +233,7 @@ private Task> getDynamicLink( } private DynamicLink.Builder setupParameters(Map arguments) { - DynamicLink.Builder dynamicLinkBuilder = FirebaseDynamicLinks.getInstance().createDynamicLink(); + DynamicLink.Builder dynamicLinkBuilder = getDynamicLinkInstance(arguments).createDynamicLink(); String uriPrefix = (String) arguments.get("uriPrefix"); String link = (String) arguments.get("link"); @@ -350,12 +350,12 @@ private DynamicLink.Builder setupParameters(Map arguments) { return dynamicLinkBuilder; } - private Task registerGetLinkListener( + private Task registerOnLinkListener( @NonNull String appName, FirebaseDynamicLinks dynamicLinks) { return Tasks.call( cachedThreadPool, () -> { - final GetLinkStreamHandler handler = new GetLinkStreamHandler(dynamicLinks); + final OnLinkStreamHandler handler = new OnLinkStreamHandler(dynamicLinks); final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; final EventChannel channel = new EventChannel(messenger, name); channel.setStreamHandler(handler); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java new file mode 100644 index 000000000000..5a856b0ba1f7 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java @@ -0,0 +1,43 @@ +package io.flutter.plugins.firebasedynamiclinks; + +import android.content.Intent; +import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.EventChannel.StreamHandler; +import java.util.Map; + +public class OnLinkStreamHandler implements StreamHandler { + private EventChannel.EventSink events; + private final FirebaseDynamicLinks dynamicLinks; + + public OnLinkStreamHandler(FirebaseDynamicLinks dynamicLinks) { + this.dynamicLinks = dynamicLinks; + } + + public void sinkEvent(Intent intent) { + dynamicLinks + .getDynamicLink(intent) + .addOnSuccessListener( + pendingDynamicLinkData -> { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + events.success(dynamicLink); + }) + .addOnFailureListener( + exception -> + events.error( + Constants.DEFAULT_ERROR_CODE, + exception.getMessage(), + Utils.getExceptionDetails(exception))); + } + + @Override + public void onListen(Object arguments, EventChannel.EventSink events) { + this.events = events; + } + + @Override + public void onCancel(Object arguments) { + // do nothing + } +} From 43fdda1b45ca28f6f05a12456b7a9946fb57319e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:12:14 +0000 Subject: [PATCH 009/125] chore(dynamic_links, iOS): update folder structure --- .../Public}/FLTFirebaseDynamicLinksPlugin.h | 0 .../ios/Classes/FLTOnLinkStreamHandler.m | 54 +++++++++++++++++++ .../Classes/Private/FLTOnLinkStreamHandler.h | 27 ++++++++++ 3 files changed, 81 insertions(+) rename packages/firebase_dynamic_links/firebase_dynamic_links/{ios/Classes => example/ios/.symlinks/plugins/firebase_dynamic_links/ios/Classes/Public}/FLTFirebaseDynamicLinksPlugin.h (100%) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/.symlinks/plugins/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h similarity index 100% rename from packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h rename to packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/.symlinks/plugins/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m new file mode 100644 index 000000000000..83d88351dcff --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m @@ -0,0 +1,54 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "Private/FLTOnLinkStreamHandler.h" +#import "Public/FLTFirebaseDynamicLinksPlugin.h" + +@implementation FLTOnLinkStreamHandler { + FlutterEventSink events; +} + +- (instancetype)init { + self = [super init]; + + return self; +} + +- (void) sinkEvent { + +} + +- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventHandler { + events = eventHandler; +// bool __block initialAuthState = YES; +// +// _listener = +// [_auth addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { +// if (initialAuthState) { +// initialAuthState = NO; +// return; +// } +// +// if (user) { +// events(@{@"user" : [FLTFirebaseAuthPlugin getNSDictionaryFromUser:user]}); +// } else { +// events(@{ +// @"user" : [NSNull null], +// }); +// } +// }]; + + return nil; +} + +- (FlutterError *)onCancelWithArguments:(id)arguments { +// if (_listener) { +// [_auth removeAuthStateDidChangeListener:_listener]; +// } +// _listener = nil; +// + return nil; +} + +@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h new file mode 100644 index 000000000000..cf7a9f630b3a --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h @@ -0,0 +1,27 @@ + + +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +#if TARGET_OS_OSX +#import +#else +#import +#endif + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FLTOnLinkStreamHandler : NSObject + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END From ab3661682e4594ddd6829ca5051cefea5e4768a1 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:12:59 +0000 Subject: [PATCH 010/125] refactor(dynamic_links): previewLink is nullable --- .../lib/src/short_dynamic_link.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index fa09b750a837..b8c9c02dd010 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -5,8 +5,8 @@ class ShortDynamicLink { /// Short url value. final Uri shortUrl; - /// Gets the preview link to show the link flow chart.. - final Uri previewLink; + /// Gets the preview link to show the link flow chart. Android only. + final Uri? previewLink; /// Information about potential warnings on link creation. final List? warnings; From 6f225006848fb29283541ea12a93b73c2c3a4c60 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:13:18 +0000 Subject: [PATCH 011/125] format: run formatter --- ...method_channel_firebase_dynamic_links.dart | 43 ++++--------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 5a5f67e93fea..9f3cf2d3a201 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -76,8 +76,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future getInitialLink() async { final Map? linkData = - await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink'); + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getInitialLink'); return getPendingDynamicLinkDataFromMap(linkData); } @@ -86,7 +86,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Future getDynamicLink(Uri url) async { final Map? linkData = await channel .invokeMapMethod('FirebaseDynamicLinks#getDynamicLink', - {'url': url.toString()}); + {'url': url.toString()}); return getPendingDynamicLinkDataFromMap(linkData); } @@ -94,7 +94,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Stream onLink() { StreamSubscription? snapshotStream; late StreamController - controller; // ignore: close_sinks + controller; // ignore: close_sinks controller = StreamController.broadcast( onListen: () async { @@ -106,10 +106,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { snapshotStream = onLinkChannel(name).receiveBroadcastStream().listen((event) { - controller.add(getPendingDynamicLinkDataFromMap(event)); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + controller.add(getPendingDynamicLinkDataFromMap(event)); + }, onError: (error, stack) { + controller.addError(convertPlatformException(error), stack); + }); }, onCancel: () { snapshotStream?.cancel(); @@ -123,31 +123,4 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { MethodChannelDynamicLinkBuilder createLink() { return MethodChannelDynamicLinkBuilder(this); } - -// Future _handleMethod(MethodCall call) async { -// switch (call.method) { -// case 'onLinkSuccess': -// PendingDynamicLinkData? linkData; -// if (call.arguments != null) { -// final Map? data = -// call.arguments.cast(); -// linkData = getPendingDynamicLinkDataFromMap(data); -// } -// return _onLinkSuccess!(linkData); -// case 'onLinkError': -// final Map data = -// call.arguments.cast(); -//TODO use stream handler instead -// final OnLinkErrorException e = OnLinkErrorException._( -// data['code'], data['message'], data['details']); -// return _onLinkError!(e); -// } -// } } - -//TODO use exception in PI. Remove this. -// /// This object is returned by the handler when an error occurs. -// class OnLinkErrorException extends PlatformException { -// OnLinkErrorException._(String code, String? message, dynamic details) -// : super(code: code, message: message, details: details); -// } From 118c7695b4dd4c9131068e2af2c7ef3326ccf4e0 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:13:44 +0000 Subject: [PATCH 012/125] chore: remove unused stream handler --- .../GetLinkStreamHandler.java | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java deleted file mode 100644 index 9bce7a995af4..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/GetLinkStreamHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.flutter.plugins.firebasedynamiclinks; - -import android.content.Intent; -import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.EventChannel.StreamHandler; -import java.util.Map; - -public class GetLinkStreamHandler implements StreamHandler { - private EventChannel.EventSink events; - private final FirebaseDynamicLinks dynamicLinks; - - public GetLinkStreamHandler(FirebaseDynamicLinks dynamicLinks) { - this.dynamicLinks = dynamicLinks; - } - - public void sinkEvent(Intent intent) { - dynamicLinks - .getDynamicLink(intent) - .addOnSuccessListener( - pendingDynamicLinkData -> { - Map dynamicLink = - Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - events.success(dynamicLink); - }) - .addOnFailureListener( - exception -> - events.error( - Constants.DEFAULT_ERROR_CODE, - exception.getMessage(), - Utils.getExceptionDetails(exception))); - } - - @Override - public void onListen(Object arguments, EventChannel.EventSink events) { - this.events = events; - } - - @Override - public void onCancel(Object arguments) { - // do nothing - } -} From 3b639aca799d81548570a881b46fc03eef92e42c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:14:38 +0000 Subject: [PATCH 013/125] chore(dynamic_links): miscellaneous xCode changes --- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 21 ------------------- .../contents.xcworkspacedata | 2 +- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist index 6c2de8086bcd..3a9c234f96d4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Flutter/AppFrameworkInfo.plist @@ -25,6 +25,6 @@ arm64 MinimumOSVersion - 8.0 + 9.0 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj index 9a7df42960b3..1a3a41915cf3 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj @@ -154,7 +154,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -235,24 +234,6 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 852BEAA0EB8653502C27C0BD /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../Flutter/Flutter.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -322,7 +303,6 @@ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -376,7 +356,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..919434a6254f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> From 53179a389fd4cdd20b7deb49cda11a1ead6c57c6 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 12:34:45 +0000 Subject: [PATCH 014/125] chore(dynamic_links, ios): make header file public --- .../ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/firebase_dynamic_links/firebase_dynamic_links/{example/ios/.symlinks/plugins/firebase_dynamic_links => }/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h (100%) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/.symlinks/plugins/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h similarity index 100% rename from packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/.symlinks/plugins/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h rename to packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h From e15f56183917850ef98bc4505a18562aa00ce001 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 16:21:41 +0000 Subject: [PATCH 015/125] refactor(dynamic_links, ios): rework plugin --- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 376 ++++++++++++------ .../ios/Classes/FLTOnLinkStreamHandler.m | 29 +- .../Classes/Private/FLTOnLinkStreamHandler.h | 3 +- .../Public/FLTFirebaseDynamicLinksPlugin.h | 9 +- 4 files changed, 278 insertions(+), 139 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 0831fe6b0a23..6f995a8023b1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -1,15 +1,25 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import +#import +#import -#import "FLTFirebaseDynamicLinksPlugin.h" +#import "Public/FLTFirebaseDynamicLinksPlugin.h" +#import "Private/FLTOnLinkStreamHandler.h" -#import +NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; +NSString *const kAppName = @"appName"; +NSString *const kUrl = @"url"; +NSString *const kDynamicLinkParametersOptions = @"dynamicLinkParametersOptions"; +NSString *const kDefaultAppName = @"[DEFAULT]"; -static FlutterError *getFlutterError(NSError *error) { - return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)error.code] - message:error.domain - details:error.localizedDescription]; + +static FlutterError *convertFlutterError(NSError *error) { + return [FLTFirebasePlugin createFlutterErrorFromCode:[NSString stringWithFormat:@"%d",(int) error.code] + message:error.domain + optionalDetails:nil + andOptionalNSError:error]; } static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) { @@ -40,135 +50,207 @@ return dictionary; } -@interface FLTFirebaseDynamicLinksPlugin () -@property(nonatomic, retain) FlutterMethodChannel *channel; -@property(nonatomic, retain) FIRDynamicLink *initialLink; -@property(nonatomic, retain) FlutterError *flutterError; -@property(nonatomic) BOOL initiated; -@end +@implementation FLTFirebaseDynamicLinksPlugin{ + NSObject *_binaryMessenger; + NSMutableDictionary *_eventChannels; + NSMutableDictionary *_streamHandlers; +} + +#pragma mark - FlutterPlugin -@implementation FLTFirebaseDynamicLinksPlugin +- (instancetype)init:(NSObject *)messenger { + self = [super init]; + if (self) { + [[FLTFirebasePluginRegistry sharedInstance] registerFirebasePlugin:self]; + _binaryMessenger = messenger; + _eventChannels = [NSMutableDictionary dictionary]; + _streamHandlers = [NSMutableDictionary dictionary]; + } + return self; +} + (void)registerWithRegistrar:(NSObject *)registrar { FlutterMethodChannel *channel = - [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/firebase_dynamic_links" + [FlutterMethodChannel methodChannelWithName:kFLTFirebaseDynamicLinksChannelName binaryMessenger:[registrar messenger]]; - FLTFirebaseDynamicLinksPlugin *instance = - [[FLTFirebaseDynamicLinksPlugin alloc] initWithChannel:channel]; + FLTFirebaseDynamicLinksPlugin *instance = [[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger]; + [registrar addMethodCallDelegate:instance channel:channel]; + +#if TARGET_OS_OSX + // Publish does not exist on MacOS version of FlutterPluginRegistrar. + // FlutterPluginRegistrar. (https://github.com/flutter/flutter/issues/41471) +#else + [registrar publish:instance]; [registrar addApplicationDelegate:instance]; +#endif +} - SEL sel = NSSelectorFromString(@"registerLibrary:withVersion:"); - if ([FIRApp respondsToSelector:sel]) { - [FIRApp performSelector:sel withObject:LIBRARY_NAME withObject:LIBRARY_VERSION]; +- (void)cleanupWithCompletion:(void (^)(void))completion { + for (FlutterEventChannel *channel in self->_eventChannels.allValues) { + [channel setStreamHandler:nil]; } + [self->_eventChannels removeAllObjects]; + for (NSObject *handler in self->_streamHandlers.allValues) { + [handler onCancelWithArguments:nil]; + } + [self->_streamHandlers removeAllObjects]; + + if (completion != nil) completion(); } -- (instancetype)initWithChannel:(FlutterMethodChannel *)channel { - self = [super init]; - if (self) { - _initiated = NO; - _channel = channel; - if (![FIRApp appNamed:@"__FIRAPP_DEFAULT"]) { - NSLog(@"Configuring the default Firebase app..."); - [FIRApp configure]; - NSLog(@"Configured the default Firebase app %@.", [FIRApp defaultApp].name); - } - } - return self; +- (void)detachFromEngineForRegistrar:(NSObject *)registrar { + [self cleanupWithCompletion:nil]; } - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([@"DynamicLinkParameters#buildUrl" isEqualToString:call.method]) { - FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; - result([components.url absoluteString]); - } else if ([@"DynamicLinkParameters#buildShortLink" isEqualToString:call.method]) { - FIRDynamicLinkComponents *components = [self setupParameters:call.arguments]; - [components shortenWithCompletion:[self createShortLinkCompletion:result]]; - } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { - FIRDynamicLinkComponentsOptions *options = [self setupOptions:call.arguments]; - NSURL *url = [NSURL URLWithString:call.arguments[@"url"]]; - [FIRDynamicLinkComponents shortenURL:url - options:options - completion:[self createShortLinkCompletion:result]]; - } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { - _initiated = YES; - NSMutableDictionary *dict = [self getInitialLink]; - if (dict == nil && self.flutterError) { - result(self.flutterError); - } else { - result(dict); - } - } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { - NSURL *shortLink = [NSURL URLWithString:call.arguments[@"url"]]; - FIRDynamicLinkUniversalLinkHandler completion = - ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { - if (error) { - result(getFlutterError(error)); + FLTFirebaseMethodCallErrorBlock errorBlock = + ^(NSString *_Nullable code, NSString *_Nullable message, NSDictionary *_Nullable details, + NSError *_Nullable error) { + if (code == nil) { + NSString *code = @"unknown"; + NSString *message = @"An unknown error has occurred."; + details = @{ + @"code" : code, + @"message" : message, + }; } else { - result(getDictionaryFromDynamicLink(dynamicLink)); + details = @{ + @"code" : code, + @"message" : message, + }; + } + + if ([@"unknown" isEqualToString:code]) { + NSLog(@"FLTFirebaseDynamicLinks: An error occurred while calling method %@, errorOrNil => %@", + call.method, [error userInfo]); } + + result([FLTFirebasePlugin createFlutterErrorFromCode:code + message:message + optionalDetails:details + andOptionalNSError:error]); }; - [[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion]; + + + FLTFirebaseMethodCallResult *methodCallResult = + [FLTFirebaseMethodCallResult createWithSuccess:result andErrorBlock:errorBlock]; + + NSString * appName = call.arguments[kAppName]; + if(appName != nil && ![appName isEqualToString:kDefaultAppName]){ + // TODO - document iOS default app only + NSLog(@"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app"); + } + + if ([@"DynamicLinkBuilder#buildUrl" isEqualToString:call.method]) { + [self buildUrl:call.arguments withMethodCallResult:methodCallResult]; + } else if ([@"DynamicLinkBuilder#buildShortLink" isEqualToString:call.method]) { + [self buildShortLink:call.arguments withMethodCallResult:methodCallResult]; + } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { + [self shortenUrl:call.arguments withMethodCallResult:methodCallResult]; + } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { + [self getInitialLink: methodCallResult]; + } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { + [self getDynamicLink:call.arguments withMethodCallResult:methodCallResult]; + } else if ([@"FirebaseDynamicLinks#onLink" isEqualToString:call.method]){ + [self registerOnLinkListener:call.arguments withMethodCallResult:methodCallResult]; } else { result(FlutterMethodNotImplemented); } } -- (NSMutableDictionary *)getInitialLink { - return getDictionaryFromDynamicLink(_initialLink); +#pragma mark - Firebase Dynamic Links API + +- (void)buildUrl:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { + FIRDynamicLinkComponents *components = [self setupParameters:arguments]; + result.success([components.url absoluteString]); } -- (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { - if (_initiated) { - if (error) { - FlutterError *flutterError = getFlutterError(error); - [_channel invokeMethod:@"onLinkError" arguments:getDictionaryFromFlutterError(flutterError)]; +- (void) buildShortLink:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *) result { + FIRDynamicLinkComponents *components = [self setupParameters:arguments]; + + [components shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error){ + if(error != nil){ + result.error(nil, nil, nil, error); } else { - NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); - [_channel invokeMethod:@"onLinkSuccess" arguments:dictionary]; + if (warnings == nil) { + warnings = [NSMutableArray array]; + } + + result.success(@{ + kUrl: [shortURL absoluteString], + @"warnings": warnings, + }); } - } else { - if (error) { - _flutterError = getFlutterError(error); - } else if (dynamicLink.url != nil || _initialLink == nil) { - // We'd like to overwrite initial link only if it's - // the first time or if we overwrite it with url that is not nil - _initialLink = dynamicLink; + }]; +} + +- (void) shortenUrl:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *) result { + FIRDynamicLinkComponentsOptions *options = [self setupOptions:arguments]; + NSURL *url = [NSURL URLWithString:arguments[kUrl]]; + + [FIRDynamicLinkComponents shortenURL:url + options:options + completion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error){ + if(error != nil){ + result.error(nil, nil, nil, error); + } else { + if (warnings == nil) { + warnings = [NSMutableArray array]; + } + + result.success(@{ + kUrl: [shortURL absoluteString], + @"warnings": warnings, + }); } - } + }]; } -- (void)checkForDynamicLink:(NSURL *)url { - FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; - if (dynamicLink) { - [self onDeepLinkResult:dynamicLink error:nil]; - } +- (void)getInitialLink:(FLTFirebaseMethodCallResult *) result { + _initiated = YES; + NSMutableDictionary *dict = getDictionaryFromDynamicLink(_initialLink); + if (dict == nil && self.flutterError != nil) { + result.error(self.flutterError.code, self.flutterError.message, self.flutterError.details, nil); + } else { + result.success(dict); + } } -- (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - options:(NSDictionary *)options { - [self checkForDynamicLink:url]; - // Results of this are ORed and NO doesn't affect other delegate interceptors' result. - return NO; +- (void) getDynamicLink:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { + NSURL *shortLink = [NSURL URLWithString:arguments[kUrl]]; + FIRDynamicLinkUniversalLinkHandler completion = + ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { + if (error) { + result.error(nil, nil, nil, error); + } else { + result.success(getDictionaryFromDynamicLink(dynamicLink)); + } + }; + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion]; } + +#pragma mark - AppDelegate +// Handle links received through your app's custom URL scheme. Called when your +// app receives a link and your app is opened for the first time after installation. - (BOOL)application:(UIApplication *)application - openURL:(NSURL *)url - sourceApplication:(NSString *)sourceApplication - annotation:(id)annotation { + openURL:(NSURL *)url + options:(NSDictionary *)options { [self checkForDynamicLink:url]; // Results of this are ORed and NO doesn't affect other delegate interceptors' result. return NO; } +// Handle links received as Universal Links when the app is already installed (on iOS 9 and newer). - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray *_Nullable))restorationHandler { __block BOOL retried = NO; void (^completionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); + void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); + weakCompletionBlock = completionBlock = ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { if (!error && dynamicLink && dynamicLink.url) { @@ -184,15 +266,11 @@ - (BOOL)application:(UIApplication *)application [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL completion:weakCompletionBlock]; } - // We could send this to Dart and maybe have a onDynamicLinkError stream but there's also - // a good chance the `userActivity.webpageURL` might not be for a Firebase dynamic link, - // which needs consideration - so we'll log this for now, logging will get picked up by - // Crashlytics automatically if its integrated. - if (error) - NSLog( - @"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a universal " - @"link: %@", - error); + + if(error && retried) { + // Need to update any stream listener the universal link failed + [self onDeepLinkResult:nil error:error]; + } }; [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL @@ -202,23 +280,75 @@ - (BOOL)application:(UIApplication *)application return NO; } -- (FIRDynamicLinkShortenerCompletion)createShortLinkCompletion:(FlutterResult)result { - return ^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error) { - if (error) { - result(getFlutterError(error)); - } else { - if (warnings == nil) { - warnings = [NSMutableArray array]; - } - result(@{@"url" : [shortURL absoluteString], @"warnings" : warnings}); +#pragma mark - Utilities + +- (void)checkForDynamicLink:(NSURL *)url { + FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url]; + if (dynamicLink) { + [self onDeepLinkResult:dynamicLink error:nil]; + } +} + +- (void)registerOnLinkListener:(id)arguments + withMethodCallResult:(FLTFirebaseMethodCallResult *)result { + NSString *name = + [NSString stringWithFormat:@"%@/get-link/%@", kFLTFirebaseDynamicLinksChannelName, kDefaultAppName]; + + FlutterEventChannel *channel = [FlutterEventChannel eventChannelWithName:name + binaryMessenger:_binaryMessenger]; + + FLTOnLinkStreamHandler *handler = + [[FLTOnLinkStreamHandler alloc] init]; + [channel setStreamHandler:handler]; + + [_eventChannels setObject:channel forKey:name]; + [_streamHandlers setObject:handler forKey:name]; + + result.success(name); +} + +// Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners +- (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { + if (error) { + FlutterError * flutterError = convertFlutterError(error); + + if(_initialLink == nil) { + // store initial error to pass back to user if getInitialLink is called + _flutterError = flutterError; } - }; + + NSLog( + @"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic link: %@", + flutterError + ); + + for(id key in _streamHandlers) { + FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; + [eventHandler sinkEvent:flutterError]; + } + + } else { + NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); + + for(id key in _streamHandlers) { + FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; + [eventHandler sinkEvent:dictionary]; + } + } + + if (_initialLink == nil && dynamicLink.url != nil) { + _initialLink = dynamicLink; + } + + if (dynamicLink.url != nil) { + _latestLink = dynamicLink; + } } - (FIRDynamicLinkComponentsOptions *)setupOptions:(NSDictionary *)arguments { FIRDynamicLinkComponentsOptions *options; - if (![arguments[@"dynamicLinkParametersOptions"] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[@"dynamicLinkParametersOptions"]; + if (![arguments[kDynamicLinkParametersOptions] isEqual:[NSNull null]]) { + NSDictionary *params = arguments[kDynamicLinkParametersOptions]; options = [FIRDynamicLinkComponentsOptions options]; @@ -370,4 +500,26 @@ - (FIRDynamicLinkComponents *)setupParameters:(NSDictionary *)arguments { return components; } +#pragma mark - FLTFirebasePlugin + +- (void)didReinitializeFirebaseCore:(void (^)(void))completion { + [self cleanupWithCompletion:completion]; +} + +- (NSDictionary *_Nonnull)pluginConstantsForFIRApp:(FIRApp *)firebase_app { + return @{}; +} + +- (NSString *_Nonnull)firebaseLibraryName { + return LIBRARY_NAME; +} + +- (NSString *_Nonnull)firebaseLibraryVersion { + return LIBRARY_VERSION; +} + +- (NSString *_Nonnull)flutterChannelName { + return kFLTFirebaseDynamicLinksChannelName; +} + @end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m index 83d88351dcff..c962464edb2e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m @@ -5,6 +5,7 @@ #import "Private/FLTOnLinkStreamHandler.h" #import "Public/FLTFirebaseDynamicLinksPlugin.h" + @implementation FLTOnLinkStreamHandler { FlutterEventSink events; } @@ -15,39 +16,19 @@ - (instancetype)init { return self; } -- (void) sinkEvent { - +- (void) sinkEvent:(id)event { + // Can be data or error + events(event); } - (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventHandler { events = eventHandler; -// bool __block initialAuthState = YES; -// -// _listener = -// [_auth addAuthStateDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { -// if (initialAuthState) { -// initialAuthState = NO; -// return; -// } -// -// if (user) { -// events(@{@"user" : [FLTFirebaseAuthPlugin getNSDictionaryFromUser:user]}); -// } else { -// events(@{ -// @"user" : [NSNull null], -// }); -// } -// }]; return nil; } - (FlutterError *)onCancelWithArguments:(id)arguments { -// if (_listener) { -// [_auth removeAuthStateDidChangeListener:_listener]; -// } -// _listener = nil; -// + // Do nothing return nil; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h index cf7a9f630b3a..9bc9004e343a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h @@ -19,9 +19,8 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTOnLinkStreamHandler : NSObject - - (instancetype)init; - +- (void) sinkEvent:(id)dynamicLinkData; @end NS_ASSUME_NONNULL_END diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h index f905bbbd03e0..ca5496c9b2d8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h @@ -4,5 +4,12 @@ #import -@interface FLTFirebaseDynamicLinksPlugin : NSObject +@interface FLTFirebaseDynamicLinksPlugin : FLTFirebasePlugin + +@property(nonatomic, retain) FlutterError *flutterError; +@property(nonatomic, retain) NSObject *messenger; +@property(nonatomic, retain) FlutterMethodChannel *channel; +@property(nonatomic, retain) FIRDynamicLink *initialLink; +@property(nonatomic, retain) FIRDynamicLink *latestLink; +@property(nonatomic) BOOL initiated; @end From 2647009be4855187cef6b91d8679fa4cd00e87af Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 16:21:58 +0000 Subject: [PATCH 016/125] chore: update note --- .../plugins/firebasedynamiclinks/OnLinkStreamHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java index 5a856b0ba1f7..28be9425f352 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java @@ -38,6 +38,6 @@ public void onListen(Object arguments, EventChannel.EventSink events) { @Override public void onCancel(Object arguments) { - // do nothing + // Do nothing } } From e2b45ec2de3d355e6023e4ff05f17366aa4b1fdb Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 3 Nov 2021 16:23:14 +0000 Subject: [PATCH 017/125] format: run formatter --- .../plugins/firebasedynamiclinks/Utils.java | 6 +- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 251 +++++++++--------- .../ios/Classes/FLTOnLinkStreamHandler.m | 5 +- .../Classes/Private/FLTOnLinkStreamHandler.h | 2 +- ...method_channel_firebase_dynamic_links.dart | 16 +- 5 files changed, 140 insertions(+), 140 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java index 6efd8638533c..7527bd5e5d97 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java @@ -9,9 +9,9 @@ public class Utils { static Map getExceptionDetails(@Nullable Exception exception) { Map details = new HashMap<>(); - // There aren't any Dynamic Link Exceptions in the reference: - // https://firebase.google.com/docs/reference/android/com/google/firebase/dynamiclinks/package-summary - details.put("code", "unknown"); + // There aren't any Dynamic Link Exceptions in the reference: + // https://firebase.google.com/docs/reference/android/com/google/firebase/dynamiclinks/package-summary + details.put("code", "unknown"); if (exception != null) { details.put("message", exception.getMessage()); } else { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 6f995a8023b1..37d4e4a9aa29 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -5,8 +5,8 @@ #import #import -#import "Public/FLTFirebaseDynamicLinksPlugin.h" #import "Private/FLTOnLinkStreamHandler.h" +#import "Public/FLTFirebaseDynamicLinksPlugin.h" NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; NSString *const kAppName = @"appName"; @@ -14,12 +14,12 @@ NSString *const kDynamicLinkParametersOptions = @"dynamicLinkParametersOptions"; NSString *const kDefaultAppName = @"[DEFAULT]"; - static FlutterError *convertFlutterError(NSError *error) { - return [FLTFirebasePlugin createFlutterErrorFromCode:[NSString stringWithFormat:@"%d",(int) error.code] - message:error.domain - optionalDetails:nil - andOptionalNSError:error]; + return [FLTFirebasePlugin + createFlutterErrorFromCode:[NSString stringWithFormat:@"%d", (int)error.code] + message:error.domain + optionalDetails:nil + andOptionalNSError:error]; } static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) { @@ -50,7 +50,7 @@ return dictionary; } -@implementation FLTFirebaseDynamicLinksPlugin{ +@implementation FLTFirebaseDynamicLinksPlugin { NSObject *_binaryMessenger; NSMutableDictionary *_eventChannels; NSMutableDictionary *_streamHandlers; @@ -72,7 +72,8 @@ + (void)registerWithRegistrar:(NSObject *)registrar { FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:kFLTFirebaseDynamicLinksChannelName binaryMessenger:[registrar messenger]]; - FLTFirebaseDynamicLinksPlugin *instance = [[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger]; + FLTFirebaseDynamicLinksPlugin *instance = + [[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger]; [registrar addMethodCallDelegate:instance channel:channel]; @@ -103,40 +104,39 @@ - (void)detachFromEngineForRegistrar:(NSObject *)registr } - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - FLTFirebaseMethodCallErrorBlock errorBlock = - ^(NSString *_Nullable code, NSString *_Nullable message, NSDictionary *_Nullable details, - NSError *_Nullable error) { - if (code == nil) { - NSString *code = @"unknown"; - NSString *message = @"An unknown error has occurred."; - details = @{ - @"code" : code, - @"message" : message, - }; - } else { - details = @{ - @"code" : code, - @"message" : message, - }; - } - - if ([@"unknown" isEqualToString:code]) { - NSLog(@"FLTFirebaseDynamicLinks: An error occurred while calling method %@, errorOrNil => %@", - call.method, [error userInfo]); - } + FLTFirebaseMethodCallErrorBlock errorBlock = ^( + NSString *_Nullable code, NSString *_Nullable message, NSDictionary *_Nullable details, + NSError *_Nullable error) { + if (code == nil) { + NSString *code = @"unknown"; + NSString *message = @"An unknown error has occurred."; + details = @{ + @"code" : code, + @"message" : message, + }; + } else { + details = @{ + @"code" : code, + @"message" : message, + }; + } - result([FLTFirebasePlugin createFlutterErrorFromCode:code - message:message - optionalDetails:details - andOptionalNSError:error]); - }; + if ([@"unknown" isEqualToString:code]) { + NSLog(@"FLTFirebaseDynamicLinks: An error occurred while calling method %@, errorOrNil => %@", + call.method, [error userInfo]); + } + result([FLTFirebasePlugin createFlutterErrorFromCode:code + message:message + optionalDetails:details + andOptionalNSError:error]); + }; - FLTFirebaseMethodCallResult *methodCallResult = - [FLTFirebaseMethodCallResult createWithSuccess:result andErrorBlock:errorBlock]; + FLTFirebaseMethodCallResult *methodCallResult = + [FLTFirebaseMethodCallResult createWithSuccess:result andErrorBlock:errorBlock]; - NSString * appName = call.arguments[kAppName]; - if(appName != nil && ![appName isEqualToString:kDefaultAppName]){ + NSString *appName = call.arguments[kAppName]; + if (appName != nil && ![appName isEqualToString:kDefaultAppName]) { // TODO - document iOS default app only NSLog(@"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app"); } @@ -148,10 +148,10 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { [self shortenUrl:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { - [self getInitialLink: methodCallResult]; + [self getInitialLink:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { [self getDynamicLink:call.arguments withMethodCallResult:methodCallResult]; - } else if ([@"FirebaseDynamicLinks#onLink" isEqualToString:call.method]){ + } else if ([@"FirebaseDynamicLinks#onLink" isEqualToString:call.method]) { [self registerOnLinkListener:call.arguments withMethodCallResult:methodCallResult]; } else { result(FlutterMethodNotImplemented); @@ -160,63 +160,67 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result #pragma mark - Firebase Dynamic Links API -- (void)buildUrl:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { +- (void)buildUrl:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { FIRDynamicLinkComponents *components = [self setupParameters:arguments]; result.success([components.url absoluteString]); } -- (void) buildShortLink:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *) result { +- (void)buildShortLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { FIRDynamicLinkComponents *components = [self setupParameters:arguments]; - [components shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error){ - if(error != nil){ - result.error(nil, nil, nil, error); - } else { - if (warnings == nil) { - warnings = [NSMutableArray array]; - } + [components + shortenWithCompletion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, + NSError *_Nullable error) { + if (error != nil) { + result.error(nil, nil, nil, error); + } else { + if (warnings == nil) { + warnings = [NSMutableArray array]; + } - result.success(@{ - kUrl: [shortURL absoluteString], - @"warnings": warnings, - }); - } - }]; + result.success(@{ + kUrl : [shortURL absoluteString], + @"warnings" : warnings, + }); + } + }]; } -- (void) shortenUrl:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *) result { +- (void)shortenUrl:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { FIRDynamicLinkComponentsOptions *options = [self setupOptions:arguments]; NSURL *url = [NSURL URLWithString:arguments[kUrl]]; - [FIRDynamicLinkComponents shortenURL:url - options:options - completion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, NSError *_Nullable error){ - if(error != nil){ - result.error(nil, nil, nil, error); - } else { - if (warnings == nil) { - warnings = [NSMutableArray array]; - } + [FIRDynamicLinkComponents + shortenURL:url + options:options + completion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, + NSError *_Nullable error) { + if (error != nil) { + result.error(nil, nil, nil, error); + } else { + if (warnings == nil) { + warnings = [NSMutableArray array]; + } - result.success(@{ - kUrl: [shortURL absoluteString], - @"warnings": warnings, - }); - } - }]; + result.success(@{ + kUrl : [shortURL absoluteString], + @"warnings" : warnings, + }); + } + }]; } -- (void)getInitialLink:(FLTFirebaseMethodCallResult *) result { +- (void)getInitialLink:(FLTFirebaseMethodCallResult *)result { _initiated = YES; NSMutableDictionary *dict = getDictionaryFromDynamicLink(_initialLink); - if (dict == nil && self.flutterError != nil) { - result.error(self.flutterError.code, self.flutterError.message, self.flutterError.details, nil); - } else { - result.success(dict); - } + if (dict == nil && self.flutterError != nil) { + result.error(self.flutterError.code, self.flutterError.message, self.flutterError.details, nil); + } else { + result.success(dict); + } } -- (void) getDynamicLink:(id) arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { +- (void)getDynamicLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { NSURL *shortLink = [NSURL URLWithString:arguments[kUrl]]; FIRDynamicLinkUniversalLinkHandler completion = ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { @@ -229,7 +233,6 @@ - (void) getDynamicLink:(id) arguments withMethodCallResult:(FLTFirebaseMethodCa [[FIRDynamicLinks dynamicLinks] handleUniversalLink:shortLink completion:completion]; } - #pragma mark - AppDelegate // Handle links received through your app's custom URL scheme. Called when your // app receives a link and your app is opened for the first time after installation. @@ -247,31 +250,31 @@ - (BOOL)application:(UIApplication *)application restorationHandler:(nonnull void (^)(NSArray *_Nullable))restorationHandler { __block BOOL retried = NO; void (^completionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); - + void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); - - weakCompletionBlock = completionBlock = ^(FIRDynamicLink *_Nullable dynamicLink, - NSError *_Nullable error) { - if (!error && dynamicLink && dynamicLink.url) { - [self onDeepLinkResult:dynamicLink error:nil]; - } - // Per Apple Tech Support, a network failure could occur when returning from background on - // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 So - // we'll retry the request once - if (error && !retried && [NSPOSIXErrorDomain isEqualToString:error.domain] && - error.code == 53) { - retried = YES; - [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL - completion:weakCompletionBlock]; - } - - if(error && retried) { - // Need to update any stream listener the universal link failed - [self onDeepLinkResult:nil error:error]; - } - }; + weakCompletionBlock = completionBlock = + ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { + if (!error && dynamicLink && dynamicLink.url) { + [self onDeepLinkResult:dynamicLink error:nil]; + } + + // Per Apple Tech Support, a network failure could occur when returning from background on + // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 + // So we'll retry the request once + if (error && !retried && [NSPOSIXErrorDomain isEqualToString:error.domain] && + error.code == 53) { + retried = YES; + [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL + completion:weakCompletionBlock]; + } + + if (error && retried) { + // Need to update any stream listener the universal link failed + [self onDeepLinkResult:nil error:error]; + } + }; [[FIRDynamicLinks dynamicLinks] handleUniversalLink:userActivity.webpageURL completion:completionBlock]; @@ -290,15 +293,14 @@ - (void)checkForDynamicLink:(NSURL *)url { } - (void)registerOnLinkListener:(id)arguments - withMethodCallResult:(FLTFirebaseMethodCallResult *)result { - NSString *name = - [NSString stringWithFormat:@"%@/get-link/%@", kFLTFirebaseDynamicLinksChannelName, kDefaultAppName]; + withMethodCallResult:(FLTFirebaseMethodCallResult *)result { + NSString *name = [NSString + stringWithFormat:@"%@/get-link/%@", kFLTFirebaseDynamicLinksChannelName, kDefaultAppName]; FlutterEventChannel *channel = [FlutterEventChannel eventChannelWithName:name binaryMessenger:_binaryMessenger]; - FLTOnLinkStreamHandler *handler = - [[FLTOnLinkStreamHandler alloc] init]; + FLTOnLinkStreamHandler *handler = [[FLTOnLinkStreamHandler alloc] init]; [channel setStreamHandler:handler]; [_eventChannels setObject:channel forKey:name]; @@ -310,36 +312,35 @@ - (void)registerOnLinkListener:(id)arguments // Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { if (error) { - FlutterError * flutterError = convertFlutterError(error); - - if(_initialLink == nil) { + FlutterError *flutterError = convertFlutterError(error); + + if (_initialLink == nil) { // store initial error to pass back to user if getInitialLink is called _flutterError = flutterError; } - - NSLog( - @"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic link: %@", - flutterError - ); - - for(id key in _streamHandlers) { - FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; - [eventHandler sinkEvent:flutterError]; + + NSLog(@"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic " + @"link: %@", + flutterError); + + for (id key in _streamHandlers) { + FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; + [eventHandler sinkEvent:flutterError]; } - + } else { NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); - - for(id key in _streamHandlers) { - FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; - [eventHandler sinkEvent:dictionary]; + + for (id key in _streamHandlers) { + FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; + [eventHandler sinkEvent:dictionary]; } } - + if (_initialLink == nil && dynamicLink.url != nil) { _initialLink = dynamicLink; } - + if (dynamicLink.url != nil) { _latestLink = dynamicLink; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m index c962464edb2e..eca0bfa90f1c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m @@ -5,18 +5,17 @@ #import "Private/FLTOnLinkStreamHandler.h" #import "Public/FLTFirebaseDynamicLinksPlugin.h" - @implementation FLTOnLinkStreamHandler { FlutterEventSink events; } - (instancetype)init { self = [super init]; - + return self; } -- (void) sinkEvent:(id)event { +- (void)sinkEvent:(id)event { // Can be data or error events(event); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h index 9bc9004e343a..815a297f969a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN @interface FLTOnLinkStreamHandler : NSObject - (instancetype)init; -- (void) sinkEvent:(id)dynamicLinkData; +- (void)sinkEvent:(id)dynamicLinkData; @end NS_ASSUME_NONNULL_END diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 9f3cf2d3a201..900a27fdfbd6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -76,8 +76,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future getInitialLink() async { final Map? linkData = - await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink'); + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getInitialLink'); return getPendingDynamicLinkDataFromMap(linkData); } @@ -86,7 +86,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Future getDynamicLink(Uri url) async { final Map? linkData = await channel .invokeMapMethod('FirebaseDynamicLinks#getDynamicLink', - {'url': url.toString()}); + {'url': url.toString()}); return getPendingDynamicLinkDataFromMap(linkData); } @@ -94,7 +94,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Stream onLink() { StreamSubscription? snapshotStream; late StreamController - controller; // ignore: close_sinks + controller; // ignore: close_sinks controller = StreamController.broadcast( onListen: () async { @@ -106,10 +106,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { snapshotStream = onLinkChannel(name).receiveBroadcastStream().listen((event) { - controller.add(getPendingDynamicLinkDataFromMap(event)); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + controller.add(getPendingDynamicLinkDataFromMap(event)); + }, onError: (error, stack) { + controller.addError(convertPlatformException(error), stack); + }); }, onCancel: () { snapshotStream?.cancel(); From c2e1b56620686dd626e0fe3cf6da0418eacb5791 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 4 Nov 2021 11:59:25 +0000 Subject: [PATCH 018/125] refactor(dynamic_links): update error handling --- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 2 - .../Classes/FLTFirebaseDynamicLinksPlugin.m | 66 +++++++++++-------- .../Public/FLTFirebaseDynamicLinksPlugin.h | 3 +- .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../contents.xcworkspacedata | 2 +- 6 files changed, 45 insertions(+), 32 deletions(-) diff --git a/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist b/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist index 9367d483e44e..8d4492f977ad 100644 --- a/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 9.0 diff --git a/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj b/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj index a950ad498dce..b1d34c4d8a2c 100644 --- a/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj @@ -315,7 +315,6 @@ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -369,7 +368,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 37d4e4a9aa29..4c50fa21bfac 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -11,17 +11,11 @@ NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; NSString *const kAppName = @"appName"; NSString *const kUrl = @"url"; +NSString *const kCode = @"code"; +NSString *const kMessage = @"message"; NSString *const kDynamicLinkParametersOptions = @"dynamicLinkParametersOptions"; NSString *const kDefaultAppName = @"[DEFAULT]"; -static FlutterError *convertFlutterError(NSError *error) { - return [FLTFirebasePlugin - createFlutterErrorFromCode:[NSString stringWithFormat:@"%d", (int)error.code] - message:error.domain - optionalDetails:nil - andOptionalNSError:error]; -} - static NSMutableDictionary *getDictionaryFromDynamicLink(FIRDynamicLink *dynamicLink) { if (dynamicLink != nil) { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; @@ -38,16 +32,31 @@ } } -static NSMutableDictionary *getDictionaryFromFlutterError(FlutterError *error) { +static NSDictionary *getDictionaryFromNSError(NSError *error) { + NSString *code = @"unknown"; + NSString *message = @"An unknown error has occurred."; if (error == nil) { - return nil; + return @{ + kCode : code, + kMessage : message, + @"additionalData" : @{}, + }; } NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - dictionary[@"code"] = error.code; - dictionary[@"message"] = error.message; - dictionary[@"details"] = error.details; - return dictionary; + dictionary[kCode] = [NSString stringWithFormat:@"%d", (int)error.code]; + dictionary[kMessage] = [error localizedDescription]; + id additionalData = [NSMutableDictionary dictionary]; + + if([error userInfo] != nil){ + additionalData = [error userInfo]; + } + + return @{ + kCode : code, + kMessage : message, + @"additionalData" : additionalData, + }; } @implementation FLTFirebaseDynamicLinksPlugin { @@ -108,16 +117,15 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSString *_Nullable code, NSString *_Nullable message, NSDictionary *_Nullable details, NSError *_Nullable error) { if (code == nil) { - NSString *code = @"unknown"; - NSString *message = @"An unknown error has occurred."; - details = @{ - @"code" : code, - @"message" : message, - }; + NSDictionary *errorDetails = getDictionaryFromNSError(error); + code = errorDetails[kCode]; + message = errorDetails[kMessage]; + details = errorDetails; } else { details = @{ - @"code" : code, - @"message" : message, + kCode : code, + kMessage : message, + @"additionalData" : @{}, }; } @@ -213,8 +221,8 @@ - (void)shortenUrl:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResu - (void)getInitialLink:(FLTFirebaseMethodCallResult *)result { _initiated = YES; NSMutableDictionary *dict = getDictionaryFromDynamicLink(_initialLink); - if (dict == nil && self.flutterError != nil) { - result.error(self.flutterError.code, self.flutterError.message, self.flutterError.details, nil); + if (dict == nil && self.initialError != nil) { + result.error(nil, nil, nil, self.initialError); } else { result.success(dict); } @@ -312,13 +320,19 @@ - (void)registerOnLinkListener:(id)arguments // Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { if (error) { - FlutterError *flutterError = convertFlutterError(error); if (_initialLink == nil) { // store initial error to pass back to user if getInitialLink is called - _flutterError = flutterError; + _initialError = error; } + NSDictionary * errorDetails = getDictionaryFromNSError(error); + + FlutterError * flutterError = [FLTFirebasePlugin createFlutterErrorFromCode:errorDetails[kCode] + message:errorDetails[kMessage] + optionalDetails:errorDetails + andOptionalNSError:error]; + NSLog(@"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic " @"link: %@", flutterError); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h index ca5496c9b2d8..f804938594f6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h @@ -3,10 +3,11 @@ // found in the LICENSE file. #import +#import @interface FLTFirebaseDynamicLinksPlugin : FLTFirebasePlugin -@property(nonatomic, retain) FlutterError *flutterError; +@property(nonatomic, retain) NSError *initialError; @property(nonatomic, retain) NSObject *messenger; @property(nonatomic, retain) FlutterMethodChannel *channel; @property(nonatomic, retain) FIRDynamicLink *initialLink; diff --git a/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist index 6c2de8086bcd..3a9c234f96d4 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist @@ -25,6 +25,6 @@ arm64 MinimumOSVersion - 8.0 + 9.0 diff --git a/packages/firebase_remote_config/firebase_remote_config/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/firebase_remote_config/firebase_remote_config/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16ed0f..919434a6254f 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/packages/firebase_remote_config/firebase_remote_config/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> From ed2b44b65444501a01dddf0dc9fa641b54b66156 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 4 Nov 2021 11:59:54 +0000 Subject: [PATCH 019/125] chore(dynamic_links): update paths post directory restructuring --- packages/firebase_auth/firebase_auth/example/pubspec.yaml | 4 ++-- .../firebase_dynamic_links/example/analysis_options.yaml | 4 ++-- .../firebase_dynamic_links/example/pubspec.yaml | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/firebase_auth/firebase_auth/example/pubspec.yaml b/packages/firebase_auth/firebase_auth/example/pubspec.yaml index a213dcb2e56c..53abfba41c33 100644 --- a/packages/firebase_auth/firebase_auth/example/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/example/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: firebase_core: path: ../../../firebase_core/firebase_core firebase_dynamic_links: - path: ../../../firebase_dynamic_links + path: ../../../firebase_dynamic_links/firebase_dynamic_links flutter: sdk: flutter flutter_signin_button: ^2.0.0 @@ -31,7 +31,7 @@ dependency_overrides: firebase_core_web: path: ../../../firebase_core/firebase_core_web firebase_dynamic_links: - path: ../../../firebase_dynamic_links + path: ../../../firebase_dynamic_links/firebase_dynamic_links dev_dependencies: drive: 1.0.0-1.0.nullsafety.1 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml index 98eee62ba0f0..9a1bfe522b63 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/analysis_options.yaml @@ -1,8 +1,8 @@ # Copyright 2021 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # in the LICENSE file. -include: ../../../analysis_options.yaml +include: ../../../../analysis_options.yaml linter: rules: public_member_api_docs: false - avoid_print: false \ No newline at end of file + avoid_print: false diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml index d5bbc2a7f8d4..2d4785237a27 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -15,6 +15,8 @@ dependencies: url_launcher: ^6.0.2 dependency_overrides: + firebase_dynamic_links: + path: ../ firebase_core: path: ../../../firebase_core/firebase_core firebase_core_platform_interface: From 5e436c3a2713fa3e0d774512b71e10093dffce1d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 4 Nov 2021 14:33:20 +0000 Subject: [PATCH 020/125] chore(dynamic_links): update pubspec.yaml --- .../firebase_dynamic_links/example/pubspec.yaml | 2 ++ .../firebase_dynamic_links/pubspec.yaml | 5 +---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml index 2d4785237a27..f0f432fa33bd 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -17,6 +17,8 @@ dependencies: dependency_overrides: firebase_dynamic_links: path: ../ + firebase_dynamic_links_platform_interface: + path: ../../firebase_dynamic_links_platform_interface firebase_core: path: ../../../firebase_core/firebase_core firebase_core_platform_interface: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml index 88f258774eee..cc436a9070c2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml @@ -9,10 +9,10 @@ repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages environment: sdk: '>=2.12.0 <3.0.0' flutter: ">=1.12.13+hotfix.5" - dependencies: firebase_core: ^1.8.0 firebase_core_platform_interface: ^4.0.1 + firebase_dynamic_links_platform_interface: ^0.0.1 flutter: sdk: flutter meta: ^1.3.0 @@ -23,9 +23,6 @@ dev_dependencies: mockito: ^5.0.0 url_launcher: ^6.0.2 -dependency_overrides: - firebase_dynamic_links_platform_interface: - path: ../firebase_dynamic_links_platform_interface flutter: plugin: From 9ecbb628c5a4044109c6afb8a9e467afe5410cdd Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 4 Nov 2021 16:40:53 +0000 Subject: [PATCH 021/125] chore(dynamic_links): started update of example app --- .../firebase_dynamic_links/example/lib/main.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index c665f9d1ed47..a7ef4756b326 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -41,17 +42,14 @@ class _MainScreenState extends State<_MainScreen> { } Future initDynamicLinks() async { - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData? dynamicLink) async { - final Uri? deepLink = dynamicLink?.link; + FirebaseDynamicLinks.instance.onLink().listen((dynamicLinkData) { - if (deepLink != null) { - // ignore: unawaited_futures - Navigator.pushNamed(context, deepLink.path); + if(dynamicLinkData != null){ + Navigator.pushNamed(context, dynamicLinkData.link.path); } - }, onError: (OnLinkErrorException e) async { - print('onLinkError'); - print(e.message); + }).onError((error) { + print('onLink error'); + print(error.message); }); final PendingDynamicLinkData? data = From e884dffbff31e5df9181be693375c8692772a1cd Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 9 Nov 2021 11:37:07 +0000 Subject: [PATCH 022/125] refactor(dynamic_links): removed dynamic_link_builder.dart --- .../example/lib/main.dart | 23 +++---- .../lib/firebase_dynamic_links.dart | 3 - .../lib/src/dynamic_link_builder.dart | 32 ---------- .../lib/src/firebase_dynamic_links.dart | 14 ++++- .../firebase_dynamic_links/test/mock.dart | 46 ++++++++++++++ ...base_dynamic_links_platform_interface.dart | 2 +- ...ters.dart => dynamic_link_parameters.dart} | 6 +- .../method_channel_dynamic_link_builder.dart | 62 ------------------- ...method_channel_firebase_dynamic_links.dart | 45 +++++++++++++- ...atform_interface_dynamic_link_builder.dart | 50 --------------- ...form_interface_firebase_dynamic_links.dart | 20 +++++- 11 files changed, 135 insertions(+), 168 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart rename packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/{build_dynamic_link_parameters.dart => dynamic_link_parameters.dart} (96%) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index a7ef4756b326..23122b3684ed 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -29,6 +29,8 @@ class _MainScreen extends StatefulWidget { class _MainScreenState extends State<_MainScreen> { String? _linkMessage; bool _isCreatingLink = false; + + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; String _testString = 'To test: long press link and then copy and click from a non-browser ' "app. Make sure this isn't being tested on iOS simulator and iOS xcode " @@ -42,9 +44,8 @@ class _MainScreenState extends State<_MainScreen> { } Future initDynamicLinks() async { - FirebaseDynamicLinks.instance.onLink().listen((dynamicLinkData) { - - if(dynamicLinkData != null){ + dynamicLinks.onLink().listen((dynamicLinkData) { + if (dynamicLinkData != null) { Navigator.pushNamed(context, dynamicLinkData.link.path); } }).onError((error) { @@ -52,8 +53,7 @@ class _MainScreenState extends State<_MainScreen> { print(error.message); }); - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); + final PendingDynamicLinkData? data = await dynamicLinks.getInitialLink(); final Uri? deepLink = data?.link; if (deepLink != null) { @@ -67,17 +67,17 @@ class _MainScreenState extends State<_MainScreen> { _isCreatingLink = true; }); - final DynamicLinkBuilder parameters = DynamicLinkBuilder( + final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://cx4k7.app.goo.gl', link: Uri.parse('https://dynamic.link.example/helloworld'), - androidParameters: AndroidParameters( + androidParameters: const AndroidParameters( packageName: 'io.flutter.plugins.firebasedynamiclinksexample', minimumVersion: 0, ), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: IosParameters( + iosParameters: const IosParameters( bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev', minimumVersion: '0', ), @@ -85,10 +85,11 @@ class _MainScreenState extends State<_MainScreen> { Uri url; if (short) { - final ShortDynamicLink shortLink = await parameters.buildShortLink(); + final ShortDynamicLink shortLink = + await dynamicLinks.buildShortLink(parameters); url = shortLink.shortUrl; } else { - url = await parameters.buildUrl(); + url = await dynamicLinks.buildUrl(parameters); } setState(() { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index a7b7b5413ef9..a6be06e80495 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -8,11 +8,8 @@ library firebase_dynamic_links; import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart' show FirebasePluginPlatform; -part 'src/dynamic_link_builder.dart'; part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart deleted file mode 100644 index ec0f21f39e85..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/dynamic_link_builder.dart +++ /dev/null @@ -1,32 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -part of firebase_dynamic_links; - -/// The class used for Dynamic Link URL generation. -/// -/// Supports creation of short and long Dynamic Link URLs. -class DynamicLinkBuilder { - DynamicLinkBuilder._(this.dynamicLink, this._delegate) { - DynamicLinkBuilderPlatform.verifyExtends(_delegate); - } - - DynamicLinkBuilderPlatform _delegate; - FirebaseDynamicLinks dynamicLink; - - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { - return _delegate.shortenUrl(url, options); - } - - Future buildUrl(BuildDynamicLinkParameters parameters) async { - return _delegate.buildUrl(parameters); - } - - Future buildShortLink( - BuildDynamicLinkParameters parameters) async { - return _delegate.buildShortLink(parameters); - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 0dd72d68531d..2120249f3c4a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -70,7 +70,17 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { return _delegate.onLink(); } - DynamicLinkBuilder createLink() { - return DynamicLinkBuilder._(this, _delegate.createLink()); + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + return _delegate.shortenUrl(url, options); + } + + Future buildUrl(DynamicLinkParameters parameters) async { + return _delegate.buildUrl(parameters); + } + + Future buildShortLink( + DynamicLinkParameters parameters) async { + return _delegate.buildShortLink(parameters); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart new file mode 100644 index 000000000000..1ccbc38513eb --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart @@ -0,0 +1,46 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +typedef Callback = void Function(MethodCall call); + +void setupFirebaseDynamicLinksMocks([Callback? customHandlers]) { + TestWidgetsFlutterBinding.ensureInitialized(); + + MethodChannelFirebase.channel.setMockMethodCallHandler((call) async { + if (call.method == 'Firebase#initializeCore') { + return [ + { + 'name': defaultFirebaseAppName, + 'options': { + 'apiKey': '123', + 'appId': '123', + 'messagingSenderId': '123', + 'projectId': '123', + }, + 'pluginConstants': {}, + } + ]; + } + + if (call.method == 'Firebase#initializeApp') { + return { + 'name': call.arguments['appName'], + 'options': call.arguments['options'], + 'pluginConstants': {}, + }; + } + + if (customHandlers != null) { + customHandlers(call); + } + + return null; + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart index 1bd734a4f798..11aa65403dc4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -19,4 +19,4 @@ export 'src/itunes_connect_analytics_parameters.dart'; export 'src/navigation_info_parameters.dart'; export 'src/social_meta_tag_parameters.dart'; export 'src/android_parameters.dart'; -export 'src/build_dynamic_link_parameters.dart'; +export 'src/dynamic_link_parameters.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart similarity index 96% rename from packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart rename to packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index bebd9a35f397..db33114f006e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/build_dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -8,10 +8,10 @@ import 'package:flutter/foundation.dart'; import '../firebase_dynamic_links_platform_interface.dart'; /// Interface that defines the all the parameters required to build a dynamic link -class BuildDynamicLinkParameters { +class DynamicLinkParameters { // ignore: public_member_api_docs @protected - BuildDynamicLinkParameters({ + DynamicLinkParameters({ this.androidParameters, required this.uriPrefix, this.dynamicLinkParametersOptions, @@ -76,6 +76,6 @@ class BuildDynamicLinkParameters { @override String toString() { - return '$BuildDynamicLinkParameters($asMap)'; + return '$DynamicLinkParameters($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart deleted file mode 100644 index 7d3f0f973c1c..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_dynamic_link_builder.dart +++ /dev/null @@ -1,62 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2021, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; - -import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_dynamic_links_platform_interface/src/platform_interface/platform_interface_dynamic_link_builder.dart'; -import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; - -class MethodChannelDynamicLinkBuilder extends DynamicLinkBuilderPlatform { - MethodChannelDynamicLinkBuilder(FirebaseDynamicLinksPlatform dynamicLinks) - : super(dynamicLinks); - - /// Attaches generic default values to method channel arguments. - Map _withChannelDefaults(Map other) { - return { - 'appName': dynamicLinks.app.name, - }..addAll(other); - } - - @override - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { - final Map? reply = await MethodChannelFirebaseDynamicLinks - .channel - .invokeMapMethod( - 'DynamicLinkParameters#shortenUrl', - _withChannelDefaults({ - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.data, - })); - return _parseShortLink(reply!); - } - - @override - Future buildUrl(BuildDynamicLinkParameters parameters) async { - final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('DynamicLinkParameters#buildUrl', - _withChannelDefaults(parameters.asMap())); - return Uri.parse(url!); - } - - @override - Future buildShortLink( - BuildDynamicLinkParameters parameters) async { - final Map? response = - await MethodChannelFirebaseDynamicLinks.channel - .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', - _withChannelDefaults(parameters.asMap())); - return _parseShortLink(response!); - } - - ShortDynamicLink _parseShortLink(Map response) { - final List? warnings = response['warnings']; - return ShortDynamicLink( - Uri.parse(response['url']), warnings?.cast(), response['previewLink']); - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 900a27fdfbd6..d67f98cb9653 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -44,6 +44,13 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return MethodChannelFirebaseDynamicLinks(app: app); } + /// Attaches generic default values to method channel arguments. + Map _withChannelDefaults(Map other) { + return { + 'appName': appInstance?.name ?? defaultFirebaseAppName, + }..addAll(other); + } + PendingDynamicLinkData? getPendingDynamicLinkDataFromMap( Map? linkData) { if (linkData == null) return null; @@ -120,7 +127,41 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - MethodChannelDynamicLinkBuilder createLink() { - return MethodChannelDynamicLinkBuilder(this); + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + final Map? reply = await MethodChannelFirebaseDynamicLinks + .channel + .invokeMapMethod( + 'DynamicLinkParameters#shortenUrl', + _withChannelDefaults({ + 'url': url.toString(), + 'dynamicLinkParametersOptions': options?.data, + })); + return _parseShortLink(reply!); + } + + @override + Future buildUrl(BuildDynamicLinkParameters parameters) async { + final String? url = await MethodChannelFirebaseDynamicLinks.channel + .invokeMethod('DynamicLinkParameters#buildUrl', + _withChannelDefaults(parameters.asMap())); + return Uri.parse(url!); + } + + @override + Future buildShortLink( + BuildDynamicLinkParameters parameters) async { + final Map? response = + await MethodChannelFirebaseDynamicLinks.channel + .invokeMapMethod( + 'DynamicLinkParameters#buildShortLink', + _withChannelDefaults(parameters.asMap())); + return _parseShortLink(response!); + } + + ShortDynamicLink _parseShortLink(Map response) { + final List? warnings = response['warnings']; + return ShortDynamicLink( + Uri.parse(response['url']), warnings?.cast(), response['previewLink']); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart deleted file mode 100644 index 509a61f87e4d..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_dynamic_link_builder.dart +++ /dev/null @@ -1,50 +0,0 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2021, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; - -import 'package:plugin_platform_interface/plugin_platform_interface.dart'; - -import '../../firebase_dynamic_links_platform_interface.dart'; - -abstract class DynamicLinkBuilderPlatform extends PlatformInterface { - /// Constructor. - DynamicLinkBuilderPlatform(this.dynamicLinks) : super(token: _token); - - /// The [FirebaseAuthPlatform] instance. - final FirebaseDynamicLinksPlatform dynamicLinks; - - static final Object _token = Object(); - - /// Throws an [AssertionError] if [instance] does not extend - /// [DynamicLinkBuilderPlatform]. - /// - /// This is used by the app-facing [DynamicLinkBuilder] to ensure that - /// the object in which it's going to delegate calls has been - /// constructed properly. - static void verifyExtends(DynamicLinkBuilderPlatform instance) { - PlatformInterface.verifyToken(instance, _token); - } - - /// Shortens a Dynamic Link URL. - /// - /// This method may be used for shortening a custom URL that was not generated - /// using [DynamicLinkBuilder]. - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { - throw UnimplementedError('shortenUrl() is not implemented'); - } - - /// Generate a long Dynamic Link URL. - Future buildUrl(BuildDynamicLinkParameters parameters) async { - throw UnimplementedError('buildUrl() is not implemented'); - } - - /// Generate a short Dynamic Link URL. - Future buildShortLink( - BuildDynamicLinkParameters parameters) async { - throw UnimplementedError('buildShortLink() is not implemented'); - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 8bda1ab1206e..18dea13ce4ce 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -73,8 +73,24 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('onLink() is not implemented'); } - DynamicLinkBuilderPlatform createLink() { - throw UnimplementedError('createLink() is not implemented'); + /// Shortens a Dynamic Link URL. + /// + /// This method may be used for shortening a custom URL that was not generated + /// using [DynamicLinkBuilder]. + Future shortenUrl(Uri url, + [DynamicLinkParametersOptions? options]) async { + throw UnimplementedError('shortenUrl() is not implemented'); + } + + /// Generate a long Dynamic Link URL. + Future buildUrl(BuildDynamicLinkParameters parameters) async { + throw UnimplementedError('buildUrl() is not implemented'); + } + + /// Generate a short Dynamic Link URL. + Future buildShortLink( + BuildDynamicLinkParameters parameters) async { + throw UnimplementedError('buildShortLink() is not implemented'); } @override From c4a2e20e0630092a86b986d831c258b459036314 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 9 Nov 2021 17:14:11 +0000 Subject: [PATCH 023/125] test(dynamic_links): update tests --- .../test/firebase_dynamic_links_test.dart | 1352 +++++++++-------- .../firebase_dynamic_links/test/mock.dart | 7 + ...base_dynamic_links_platform_interface.dart | 1 - ...method_channel_firebase_dynamic_links.dart | 5 +- ...form_interface_firebase_dynamic_links.dart | 5 +- 5 files changed, 723 insertions(+), 647 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 9879812c5856..e8b0c1671fad 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -5,671 +5,743 @@ import 'dart:async'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import './mock.dart'; + + +MockFirebaseDynamicLinks mockDynamicLinksPlatform = MockFirebaseDynamicLinks(); + +int kMockClickTimestamp = 1234567; +int kMockMinimumVersionAndroid = 12; +String kMockMinimumVersionIOS = 'ios minimum version'; +Uri kMockUri = Uri(scheme: 'mock-scheme'); void main() { - TestWidgetsFlutterBinding.ensureInitialized(); + setupFirebaseDynamicLinksMocks(); - group('$FirebaseDynamicLinks', () { - final List log = []; + late FirebaseDynamicLinks dynamicLinks; + late FirebaseApp appInstance; - setUp(() { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - final Map returnUrl = { - 'url': 'google.com', - 'warnings': ['This is only a test link'], - }; - switch (methodCall.method) { - case 'DynamicLinkParameters#buildUrl': - return 'google.com'; - case 'DynamicLinkParameters#buildShortLink': - return returnUrl; - case 'DynamicLinkParameters#shortenUrl': - return returnUrl; - case 'FirebaseDynamicLinks#getInitialLink': - return { - 'link': 'https://google.com', - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }; - case 'FirebaseDynamicLinks#getDynamicLink': - return { - 'link': 'https://google.com', - }; - default: - return null; - } - }); - log.clear(); + group('$FirebaseDynamicLinks', () { + var testCount = 0; + + setUp(() async { + FirebaseDynamicLinksPlatform.instance = mockDynamicLinksPlatform = MockFirebaseDynamicLinks(); + + // Each test uses a unique FirebaseApp instance to avoid sharing state + appInstance = await Firebase.initializeApp( + name: '$testCount', + options: const FirebaseOptions( + apiKey: '', + appId: '', + messagingSenderId: '', + projectId: '', + ), + ); + + dynamicLinks = FirebaseDynamicLinks.instanceFor(app: appInstance); }); + // incremented after tests completed, in case a test may want to use this + // value for an assertion (toString) + tearDown(() => testCount++); + group('getInitialLink', () { test('link can be parsed', () async { final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); + await dynamicLinks.getInitialLink(); - expect(data!.link, Uri.parse('https://google.com')); + expect(data!.link.scheme, kMockUri.scheme); - expect(data.android!.clickTimestamp, 1234567); - expect(data.android!.minimumVersion, 12); + expect(data.android!.clickTimestamp, kMockClickTimestamp); + expect(data.android!.minimumVersion, kMockMinimumVersionAndroid); - expect(data.ios!.minimumVersion, 'Version 12'); + expect(data.ios!.minimumVersion, kMockMinimumVersionIOS); - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); + verify(mockDynamicLinksPlatform.getInitialLink()); }); // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() // might return null link. In such a case we want to ignore the deep-link. - test('for null link, returns null', () async { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - switch (methodCall.method) { - case 'FirebaseDynamicLinks#getInitialLink': - return { - 'link': null, - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }; - default: - return null; - } - }); - - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - expect(data, isNull); - - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); - }); - - test('for null result, returns null', () async { - FirebaseDynamicLinks.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - log.add(methodCall); - switch (methodCall.method) { - case 'FirebaseDynamicLinks#getInitialLink': - return null; - default: - return null; - } - }); - - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - expect(data, isNull); - - expect(log, [ - isMethodCall( - 'FirebaseDynamicLinks#getInitialLink', - arguments: null, - ) - ]); - }); + // test('for null link, returns null', () async { + // FirebaseDynamicLinks.channel + // .setMockMethodCallHandler((MethodCall methodCall) async { + // log.add(methodCall); + // switch (methodCall.method) { + // case 'FirebaseDynamicLinks#getInitialLink': + // return { + // 'link': null, + // 'android': { + // 'clickTimestamp': 1234567, + // 'minimumVersion': 12, + // }, + // 'ios': { + // 'minimumVersion': 'Version 12', + // }, + // }; + // default: + // return null; + // } + // }); + // + // final PendingDynamicLinkData? data = + // await FirebaseDynamicLinks.instance.getInitialLink(); + // + // expect(data, isNull); + // + // expect(log, [ + // isMethodCall( + // 'FirebaseDynamicLinks#getInitialLink', + // arguments: null, + // ) + // ]); + // }); + // + // test('for null result, returns null', () async { + // FirebaseDynamicLinks.channel + // .setMockMethodCallHandler((MethodCall methodCall) async { + // log.add(methodCall); + // switch (methodCall.method) { + // case 'FirebaseDynamicLinks#getInitialLink': + // return null; + // default: + // return null; + // } + // }); + // + // final PendingDynamicLinkData? data = + // await FirebaseDynamicLinks.instance.getInitialLink(); + // + // expect(data, isNull); + // + // expect(log, [ + // isMethodCall( + // 'FirebaseDynamicLinks#getInitialLink', + // arguments: null, + // ) + // ]); + // }); + // }); + // + // test('getDynamicLink', () async { + // final Uri argument = Uri.parse('short-link'); + // final PendingDynamicLinkData? data = + // await FirebaseDynamicLinks.instance.getDynamicLink(argument); + // + // expect(data!.link.host, 'google.com'); + // + // expect(log, [ + // isMethodCall('FirebaseDynamicLinks#getDynamicLink', + // arguments: { + // 'url': argument.toString(), + // }) + // ]); + // }); + // + // group('$DynamicLinkBuilder', () { + // test('shortenUrl', () async { + // final Uri url = Uri.parse('google.com'); + // final DynamicLinkParametersOptions options = + // DynamicLinkParametersOptions( + // shortDynamicLinkPathLength: + // ShortDynamicLinkPathLength.unguessable); + // + // await DynamicLinkBuilder.shortenUrl(url, options); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#shortenUrl', + // arguments: { + // 'url': url.toString(), + // 'dynamicLinkParametersOptions': { + // 'shortDynamicLinkPathLength': + // ShortDynamicLinkPathLength.unguessable.index, + // }, + // }, + // ), + // ]); + // }); + // + // test('$AndroidParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // androidParameters: AndroidParameters( + // fallbackUrl: Uri.parse('test-url'), + // minimumVersion: 1, + // packageName: 'test-package', + // ), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': { + // 'fallbackUrl': 'test-url', + // 'minimumVersion': 1, + // 'packageName': 'test-package', + // }, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': { + // 'fallbackUrl': 'test-url', + // 'minimumVersion': 1, + // 'packageName': 'test-package', + // }, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$DynamicLinkParametersOptions', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // dynamicLinkParametersOptions: DynamicLinkParametersOptions( + // shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': { + // 'shortDynamicLinkPathLength': + // ShortDynamicLinkPathLength.short.index, + // }, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': { + // 'shortDynamicLinkPathLength': + // ShortDynamicLinkPathLength.short.index, + // }, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$ShortDynamicLinkPathLength', () { + // expect(ShortDynamicLinkPathLength.unguessable.index, 0); + // expect(ShortDynamicLinkPathLength.short.index, 1); + // }); + // + // test('$GoogleAnalyticsParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // googleAnalyticsParameters: GoogleAnalyticsParameters( + // campaign: 'where', + // content: 'is', + // medium: 'my', + // source: 'cat', + // term: 'friend', + // ), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': { + // 'campaign': 'where', + // 'content': 'is', + // 'medium': 'my', + // 'source': 'cat', + // 'term': 'friend', + // }, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': { + // 'campaign': 'where', + // 'content': 'is', + // 'medium': 'my', + // 'source': 'cat', + // 'term': 'friend', + // }, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$IosParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // iosParameters: IosParameters( + // appStoreId: 'is', + // bundleId: 'this', + // customScheme: 'the', + // fallbackUrl: Uri.parse('place'), + // ipadBundleId: 'to', + // ipadFallbackUrl: Uri.parse('find'), + // minimumVersion: 'potatoes', + // ), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': { + // 'appStoreId': 'is', + // 'bundleId': 'this', + // 'customScheme': 'the', + // 'fallbackUrl': 'place', + // 'ipadBundleId': 'to', + // 'ipadFallbackUrl': 'find', + // 'minimumVersion': 'potatoes', + // }, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': { + // 'appStoreId': 'is', + // 'bundleId': 'this', + // 'customScheme': 'the', + // 'fallbackUrl': 'place', + // 'ipadBundleId': 'to', + // 'ipadFallbackUrl': 'find', + // 'minimumVersion': 'potatoes', + // }, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$ItunesConnectAnalyticsParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( + // affiliateToken: 'hello', + // campaignToken: 'mister', + // providerToken: 'rose', + // ), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': { + // 'affiliateToken': 'hello', + // 'campaignToken': 'mister', + // 'providerToken': 'rose', + // }, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': { + // 'affiliateToken': 'hello', + // 'campaignToken': 'mister', + // 'providerToken': 'rose', + // }, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$NavigationInfoParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // navigationInfoParameters: + // NavigationInfoParameters(forcedRedirectEnabled: true), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': { + // 'forcedRedirectEnabled': true, + // }, + // 'socialMetaTagParameters': null, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': { + // 'forcedRedirectEnabled': true, + // }, + // 'socialMetaTagParameters': null, + // }, + // ), + // ]); + // }); + // + // test('$SocialMetaTagParameters', () async { + // final DynamicLinkBuilder components = DynamicLinkBuilder( + // uriPrefix: 'https://test-domain/', + // link: Uri.parse('test-link.com'), + // socialMetaTagParameters: SocialMetaTagParameters( + // description: 'describe', + // imageUrl: Uri.parse('thisimage'), + // title: 'bro', + // ), + // ); + // + // await components.buildUrl(); + // await components.buildShortLink(); + // + // expect(log, [ + // isMethodCall( + // 'DynamicLinkParameters#buildUrl', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': { + // 'description': 'describe', + // 'imageUrl': 'thisimage', + // 'title': 'bro', + // }, + // }, + // ), + // isMethodCall( + // 'DynamicLinkParameters#buildShortLink', + // arguments: { + // 'androidParameters': null, + // 'uriPrefix': 'https://test-domain/', + // 'dynamicLinkParametersOptions': null, + // 'googleAnalyticsParameters': null, + // 'iosParameters': null, + // 'itunesConnectAnalyticsParameters': null, + // 'link': 'test-link.com', + // 'navigationInfoParameters': null, + // 'socialMetaTagParameters': { + // 'description': 'describe', + // 'imageUrl': 'thisimage', + // 'title': 'bro', + // }, + // }, + // ), + // ]); + // }); + // }); + // + // group('onLink', () { + // OnLinkSuccessCallback? onSuccess; + // OnLinkErrorCallback? onError; + // final List successLog = + // []; + // final List errorLog = []; + // setUp(() { + // onSuccess = (linkData) async { + // successLog.add(linkData); + // }; + // onError = (error) async { + // errorLog.add(error); + // }; + // successLog.clear(); + // errorLog.clear(); + // }); + // + // Future callMethodHandler(String method, dynamic arguments) { + // const channel = FirebaseDynamicLinks.channel; + // final methodCall = MethodCall(method, arguments); + // final data = channel.codec.encodeMethodCall(methodCall); + // final Completer completer = Completer(); + // channel.binaryMessenger.handlePlatformMessage( + // channel.name, + // data, + // (data) { + // completer.complete(null); + // }, + // ); + // return completer.future; + // } + // + // test('onSuccess', () async { + // FirebaseDynamicLinks.instance + // .onLink(onSuccess: onSuccess, onError: onError); + // await callMethodHandler('onLinkSuccess', { + // 'link': 'https://google.com', + // 'android': { + // 'clickTimestamp': 1234567, + // 'minimumVersion': 12, + // }, + // 'ios': { + // 'minimumVersion': 'Version 12', + // }, + // }); + // + // expect(successLog, hasLength(1)); + // expect(errorLog, hasLength(0)); + // final success = successLog[0]!; + // + // expect(success.link, Uri.parse('https://google.com')); + // + // expect(success.android!.clickTimestamp, 1234567); + // expect(success.android!.minimumVersion, 12); + // + // expect(success.ios!.minimumVersion, 'Version 12'); + // }); + // + // test('onSuccess with null link', () async { + // FirebaseDynamicLinks.instance + // .onLink(onSuccess: onSuccess, onError: onError); + // await callMethodHandler('onLinkSuccess', { + // 'link': null, + // 'android': { + // 'clickTimestamp': 1234567, + // 'minimumVersion': 12, + // }, + // 'ios': { + // 'minimumVersion': 'Version 12', + // }, + // }); + // + // expect(successLog, hasLength(1)); + // expect(errorLog, hasLength(0)); + // final success = successLog[0]; + // + // expect(success, isNull); + // }); + // + // test('onSuccess with null', () async { + // FirebaseDynamicLinks.instance + // .onLink(onSuccess: onSuccess, onError: onError); + // await callMethodHandler('onLinkSuccess', null); + // + // expect(successLog, hasLength(1)); + // expect(errorLog, hasLength(0)); + // final success = successLog[0]; + // + // expect(success, isNull); + // }); + // + // test('onError', () async { + // FirebaseDynamicLinks.instance + // .onLink(onSuccess: onSuccess, onError: onError); + // await callMethodHandler('onLinkError', { + // 'code': 'code', + // 'message': 'message', + // 'details': 'details', + // }); + // + // expect(successLog, hasLength(0)); + // expect(errorLog, hasLength(1)); + // final failure = errorLog[0]; + // expect(failure.code, 'code'); + // expect(failure.message, 'message'); + // expect(failure.details, 'details'); + // }); }); + }); +} - test('getDynamicLink', () async { - final Uri argument = Uri.parse('short-link'); - final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getDynamicLink(argument); - - expect(data!.link.host, 'google.com'); - - expect(log, [ - isMethodCall('FirebaseDynamicLinks#getDynamicLink', - arguments: { - 'url': argument.toString(), - }) - ]); - }); - - group('$DynamicLinkBuilder', () { - test('shortenUrl', () async { - final Uri url = Uri.parse('google.com'); - final DynamicLinkParametersOptions options = - DynamicLinkParametersOptions( - shortDynamicLinkPathLength: - ShortDynamicLinkPathLength.unguessable); - - await DynamicLinkBuilder.shortenUrl(url, options); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#shortenUrl', - arguments: { - 'url': url.toString(), - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, - }, - ), - ]); - }); - - test('$AndroidParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - androidParameters: AndroidParameters( - fallbackUrl: Uri.parse('test-url'), - minimumVersion: 1, - packageName: 'test-package', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': { - 'fallbackUrl': 'test-url', - 'minimumVersion': 1, - 'packageName': 'test-package', - }, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': { - 'fallbackUrl': 'test-url', - 'minimumVersion': 1, - 'packageName': 'test-package', - }, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$DynamicLinkParametersOptions', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.short.index, - }, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.short.index, - }, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$ShortDynamicLinkPathLength', () { - expect(ShortDynamicLinkPathLength.unguessable.index, 0); - expect(ShortDynamicLinkPathLength.short.index, 1); - }); - - test('$GoogleAnalyticsParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'where', - content: 'is', - medium: 'my', - source: 'cat', - term: 'friend', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': { - 'campaign': 'where', - 'content': 'is', - 'medium': 'my', - 'source': 'cat', - 'term': 'friend', - }, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': { - 'campaign': 'where', - 'content': 'is', - 'medium': 'my', - 'source': 'cat', - 'term': 'friend', - }, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$IosParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - iosParameters: IosParameters( - appStoreId: 'is', - bundleId: 'this', - customScheme: 'the', - fallbackUrl: Uri.parse('place'), - ipadBundleId: 'to', - ipadFallbackUrl: Uri.parse('find'), - minimumVersion: 'potatoes', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': { - 'appStoreId': 'is', - 'bundleId': 'this', - 'customScheme': 'the', - 'fallbackUrl': 'place', - 'ipadBundleId': 'to', - 'ipadFallbackUrl': 'find', - 'minimumVersion': 'potatoes', - }, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': { - 'appStoreId': 'is', - 'bundleId': 'this', - 'customScheme': 'the', - 'fallbackUrl': 'place', - 'ipadBundleId': 'to', - 'ipadFallbackUrl': 'find', - 'minimumVersion': 'potatoes', - }, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$ItunesConnectAnalyticsParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - affiliateToken: 'hello', - campaignToken: 'mister', - providerToken: 'rose', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'hello', - 'campaignToken': 'mister', - 'providerToken': 'rose', - }, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'hello', - 'campaignToken': 'mister', - 'providerToken': 'rose', - }, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$NavigationInfoParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - navigationInfoParameters: - NavigationInfoParameters(forcedRedirectEnabled: true), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': null, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': null, - }, - ), - ]); - }); - - test('$SocialMetaTagParameters', () async { - final DynamicLinkBuilder components = DynamicLinkBuilder( - uriPrefix: 'https://test-domain/', - link: Uri.parse('test-link.com'), - socialMetaTagParameters: SocialMetaTagParameters( - description: 'describe', - imageUrl: Uri.parse('thisimage'), - title: 'bro', - ), - ); - - await components.buildUrl(); - await components.buildShortLink(); - - expect(log, [ - isMethodCall( - 'DynamicLinkParameters#buildUrl', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': { - 'description': 'describe', - 'imageUrl': 'thisimage', - 'title': 'bro', - }, - }, - ), - isMethodCall( - 'DynamicLinkParameters#buildShortLink', - arguments: { - 'androidParameters': null, - 'uriPrefix': 'https://test-domain/', - 'dynamicLinkParametersOptions': null, - 'googleAnalyticsParameters': null, - 'iosParameters': null, - 'itunesConnectAnalyticsParameters': null, - 'link': 'test-link.com', - 'navigationInfoParameters': null, - 'socialMetaTagParameters': { - 'description': 'describe', - 'imageUrl': 'thisimage', - 'title': 'bro', - }, - }, - ), - ]); - }); - }); - - group('onLink', () { - OnLinkSuccessCallback? onSuccess; - OnLinkErrorCallback? onError; - final List successLog = - []; - final List errorLog = []; - setUp(() { - onSuccess = (linkData) async { - successLog.add(linkData); - }; - onError = (error) async { - errorLog.add(error); - }; - successLog.clear(); - errorLog.clear(); - }); - - Future callMethodHandler(String method, dynamic arguments) { - const channel = FirebaseDynamicLinks.channel; - final methodCall = MethodCall(method, arguments); - final data = channel.codec.encodeMethodCall(methodCall); - final Completer completer = Completer(); - channel.binaryMessenger.handlePlatformMessage( - channel.name, - data, - (data) { - completer.complete(null); - }, - ); - return completer.future; - } - - test('onSuccess', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', { - 'link': 'https://google.com', - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }); - - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]!; - - expect(success.link, Uri.parse('https://google.com')); - - expect(success.android!.clickTimestamp, 1234567); - expect(success.android!.minimumVersion, 12); - - expect(success.ios!.minimumVersion, 'Version 12'); - }); - - test('onSuccess with null link', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', { - 'link': null, - 'android': { - 'clickTimestamp': 1234567, - 'minimumVersion': 12, - }, - 'ios': { - 'minimumVersion': 'Version 12', - }, - }); - - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]; - - expect(success, isNull); - }); +// FirebaseDynamicLinks.channel +// .setMockMethodCallHandler((MethodCall methodCall) async { +// log.add(methodCall); +// final Map returnUrl = { +// 'url': 'google.com', +// 'warnings': ['This is only a test link'], +// }; +// switch (methodCall.method) { +// case 'DynamicLinkParameters#buildUrl': +// return 'google.com'; +// case 'DynamicLinkParameters#buildShortLink': +// return returnUrl; +// case 'DynamicLinkParameters#shortenUrl': +// return returnUrl; +// case 'FirebaseDynamicLinks#getInitialLink': +// return { +// 'link': 'https://google.com', +// 'android': { +// 'clickTimestamp': 1234567, +// 'minimumVersion': 12, +// }, +// 'ios': { +// 'minimumVersion': 'Version 12', +// }, +// }; +// case 'FirebaseDynamicLinks#getDynamicLink': +// return { +// 'link': 'https://google.com', +// }; +// default: +// return null; +// } +// }); + +class TestPendingDynamicLinkData extends PendingDynamicLinkData { + TestPendingDynamicLinkData() : super(kMockUri,PendingDynamicLinkDataAndroid(kMockClickTimestamp, kMockMinimumVersionAndroid), PendingDynamicLinkDataIOS(kMockMinimumVersionIOS)); +} - test('onSuccess with null', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkSuccess', null); +class MockFirebaseDynamicLinks extends Mock + with MockPlatformInterfaceMixin + implements TestFirebaseDynamicLinksPlatform { + + @override + Future getInitialLink() { + return super.noSuchMethod( + Invocation.method(#getInitialLink, []), + returnValue: Future.value(TestPendingDynamicLinkData()), + returnValueForMissingStub: Future.value(TestPendingDynamicLinkData()), + ); + } + + @override + FirebaseDynamicLinksPlatform delegateFor({required FirebaseApp app}) { + return super.noSuchMethod( + Invocation.method(#delegateFor, [], {#app: app}), + returnValue: MockFirebaseDynamicLinks(appInstance), + returnValueForMissingStub: MockFirebaseDynamicLinks(), + ); + } - expect(successLog, hasLength(1)); - expect(errorLog, hasLength(0)); - final success = successLog[0]; +} - expect(success, isNull); - }); +class TestFirebaseDynamicLinksPlatform extends FirebaseDynamicLinksPlatform { + TestFirebaseDynamicLinksPlatform() : super(); - test('onError', () async { - FirebaseDynamicLinks.instance - .onLink(onSuccess: onSuccess, onError: onError); - await callMethodHandler('onLinkError', { - 'code': 'code', - 'message': 'message', - 'details': 'details', - }); + void instanceFor({ + FirebaseApp? app, + }) {} - expect(successLog, hasLength(0)); - expect(errorLog, hasLength(1)); - final failure = errorLog[0]; - expect(failure.code, 'code'); - expect(failure.message, 'message'); - expect(failure.details, 'details'); - }); - }); - }); + @override + FirebaseDynamicLinksPlatform delegateFor({required FirebaseApp app}) { + return this; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart index 1ccbc38513eb..31e65af535df 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart @@ -44,3 +44,10 @@ void setupFirebaseDynamicLinksMocks([Callback? customHandlers]) { return null; }); } + +Future neverEndingFuture() async { + // ignore: literal_only_boolean_expressions + while (true) { + await Future.delayed(const Duration(minutes: 5)); + } +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart index 11aa65403dc4..bf79c7f7dd40 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -6,7 +6,6 @@ library firebase_dynamic_links_platform_interface; export 'src/platform_interface/platform_interface_firebase_dynamic_links.dart'; -export 'src/platform_interface/platform_interface_dynamic_link_builder.dart'; export 'src/pending_dynamic_link_data.dart'; export 'src/pending_dynamic_link_data_android.dart'; export 'src/pending_dynamic_link_data_ios.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index d67f98cb9653..0a4727b8012f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_dynamic_link_builder.dart'; import 'package:flutter/services.dart'; import 'utils/exception.dart'; @@ -141,7 +140,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - Future buildUrl(BuildDynamicLinkParameters parameters) async { + Future buildUrl(DynamicLinkParameters parameters) async { final String? url = await MethodChannelFirebaseDynamicLinks.channel .invokeMethod('DynamicLinkParameters#buildUrl', _withChannelDefaults(parameters.asMap())); @@ -150,7 +149,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future buildShortLink( - BuildDynamicLinkParameters parameters) async { + DynamicLinkParameters parameters) async { final Map? response = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 18dea13ce4ce..2d9f6ea13288 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_dynamic_links_platform_interface/src/platform_interface/platform_interface_dynamic_link_builder.dart'; import 'package:meta/meta.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; @@ -83,13 +82,13 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { } /// Generate a long Dynamic Link URL. - Future buildUrl(BuildDynamicLinkParameters parameters) async { + Future buildUrl(DynamicLinkParameters parameters) async { throw UnimplementedError('buildUrl() is not implemented'); } /// Generate a short Dynamic Link URL. Future buildShortLink( - BuildDynamicLinkParameters parameters) async { + DynamicLinkParameters parameters) async { throw UnimplementedError('buildShortLink() is not implemented'); } From 9521ac108c311197e6640360395c689eb6a6adb7 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 10 Nov 2021 13:48:46 +0000 Subject: [PATCH 024/125] tests(dynamic_links): update universal tests --- .../test/firebase_dynamic_links_test.dart | 958 ++++++------------ 1 file changed, 296 insertions(+), 662 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index e8b0c1671fad..4aa32bd3b157 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -9,36 +9,79 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import './mock.dart'; - MockFirebaseDynamicLinks mockDynamicLinksPlatform = MockFirebaseDynamicLinks(); -int kMockClickTimestamp = 1234567; -int kMockMinimumVersionAndroid = 12; -String kMockMinimumVersionIOS = 'ios minimum version'; -Uri kMockUri = Uri(scheme: 'mock-scheme'); +DynamicLinkParameters buildDynamicLinkParameters() { + AndroidParameters android = AndroidParameters( + fallbackUrl: Uri.parse('test-url'), + minimumVersion: 1, + packageName: 'test-package', + ); + + GoogleAnalyticsParameters google = const GoogleAnalyticsParameters( + campaign: 'campaign', + medium: 'medium', + source: 'source', + term: 'term', + content: 'content'); + + IosParameters ios = IosParameters( + appStoreId: 'appStoreId', + bundleId: 'bundleId', + customScheme: 'customScheme', + fallbackUrl: Uri.parse('fallbackUrl'), + ipadBundleId: 'ipadBundleId', + ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), + minimumVersion: 'minimumVersion'); + + ItunesConnectAnalyticsParameters itunes = + const ItunesConnectAnalyticsParameters( + affiliateToken: 'affiliateToken', + campaignToken: 'campaignToken', + providerToken: 'providerToken', + ); + + DynamicLinkParametersOptions parametersOptions = + const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); + + Uri link = Uri.parse('link'); + NavigationInfoParameters navigation = + const NavigationInfoParameters(forcedRedirectEnabled: true); + SocialMetaTagParameters social = SocialMetaTagParameters( + description: 'description', + imageUrl: Uri.parse('imageUrl'), + title: 'title'); + + String uriPrefix = 'https://'; + + return DynamicLinkParameters( + uriPrefix: uriPrefix, + link: link, + androidParameters: android, + dynamicLinkParametersOptions: parametersOptions, + googleAnalyticsParameters: google, + iosParameters: ios, + itunesConnectAnalyticsParameters: itunes, + navigationInfoParameters: navigation, + socialMetaTagParameters: social); +} void main() { setupFirebaseDynamicLinksMocks(); late FirebaseDynamicLinks dynamicLinks; - late FirebaseApp appInstance; group('$FirebaseDynamicLinks', () { - var testCount = 0; - setUp(() async { - FirebaseDynamicLinksPlatform.instance = mockDynamicLinksPlatform = MockFirebaseDynamicLinks(); + FirebaseDynamicLinksPlatform.instance = mockDynamicLinksPlatform; - // Each test uses a unique FirebaseApp instance to avoid sharing state - appInstance = await Firebase.initializeApp( - name: '$testCount', + await Firebase.initializeApp( options: const FirebaseOptions( apiKey: '', appId: '', @@ -47,690 +90,281 @@ void main() { ), ); - dynamicLinks = FirebaseDynamicLinks.instanceFor(app: appInstance); + dynamicLinks = FirebaseDynamicLinks.instance; }); - // incremented after tests completed, in case a test may want to use this - // value for an assertion (toString) - tearDown(() => testCount++); - group('getInitialLink', () { test('link can be parsed', () async { + const mockClickTimestamp = 1234567; + const mockMinimumVersionAndroid = 12; + const mockMinimumVersionIOS = 'ios minimum version'; + Uri mockUri = Uri.parse('mock-scheme'); + + when(dynamicLinks.getInitialLink()).thenAnswer((_) async => + TestPendingDynamicLinkData(mockUri, mockClickTimestamp, + mockMinimumVersionAndroid, mockMinimumVersionIOS)); + + final PendingDynamicLinkData? data = + await dynamicLinks.getInitialLink(); + + expect(data!.link.scheme, mockUri.scheme); + + expect(data.android!.clickTimestamp, mockClickTimestamp); + expect(data.android!.minimumVersion, mockMinimumVersionAndroid); + + expect(data.ios!.minimumVersion, mockMinimumVersionIOS); + + verify(dynamicLinks.getInitialLink()); + }); + + test('for null result, returns null', () async { + when(dynamicLinks.getInitialLink()).thenAnswer((_) async => null); + final PendingDynamicLinkData? data = await dynamicLinks.getInitialLink(); - expect(data!.link.scheme, kMockUri.scheme); + expect(data, isNull); + + verify(dynamicLinks.getInitialLink()); + }); + }); + + group('getDynamicLink', () { + test('getDynamicLink', () async { + final Uri mockUri = Uri.parse('short-link'); + const mockClickTimestamp = 38947390875; + const mockMinimumVersionAndroid = 21; + const mockMinimumVersionIOS = 'min version'; + + when(dynamicLinks.getDynamicLink(mockUri)).thenAnswer((_) async => + TestPendingDynamicLinkData(mockUri, mockClickTimestamp, + mockMinimumVersionAndroid, mockMinimumVersionIOS)); + + final PendingDynamicLinkData? data = + await dynamicLinks.getDynamicLink(mockUri); + + expect(data!.link.scheme, mockUri.scheme); + + expect(data.android!.clickTimestamp, mockClickTimestamp); + expect(data.android!.minimumVersion, mockMinimumVersionAndroid); + + expect(data.ios!.minimumVersion, mockMinimumVersionIOS); + + verify(dynamicLinks.getDynamicLink(mockUri)); + }); + }); + + group('onLink', () { + test('onLink', () async { + final Uri mockUri = Uri.parse('on-link'); + const mockClickTimestamp = 239058435; + const mockMinimumVersionAndroid = 33; + const mockMinimumVersionIOS = 'on-link version'; + when(dynamicLinks.onLink()).thenAnswer((_) => Stream.value( + TestPendingDynamicLinkData(mockUri, mockClickTimestamp, + mockMinimumVersionAndroid, mockMinimumVersionIOS))); + + final PendingDynamicLinkData? data = await dynamicLinks.onLink().first; + expect(data!.link.scheme, mockUri.scheme); + + expect(data.android!.clickTimestamp, mockClickTimestamp); + expect(data.android!.minimumVersion, mockMinimumVersionAndroid); + + expect(data.ios!.minimumVersion, mockMinimumVersionIOS); + + verify(dynamicLinks.onLink()); + }); + }); + + group('shortenUrl', () { + test('shortenUrl', () async { + final Uri mockUri = Uri.parse('shortenUrl'); + final Uri previewLink = Uri.parse('previewLink'); + List warnings = ['warning']; + const DynamicLinkParametersOptions options = + DynamicLinkParametersOptions( + shortDynamicLinkPathLength: + ShortDynamicLinkPathLength.unguessable); + + when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer( + (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + + final shortDynamicLink = + await dynamicLinks.shortenUrl(mockUri, options); + + expect(shortDynamicLink.previewLink, previewLink); + expect(shortDynamicLink.warnings, warnings); + expect(shortDynamicLink.shortUrl, mockUri); + + verify(dynamicLinks.shortenUrl(mockUri, options)); + }); + }); + + group('buildUrl', () { + test('buildUrl', () async { + final Uri mockUri = Uri.parse('buildUrl'); + DynamicLinkParameters params = + DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); + + when(dynamicLinks.buildUrl(params)).thenAnswer((_) async => mockUri); - expect(data.android!.clickTimestamp, kMockClickTimestamp); - expect(data.android!.minimumVersion, kMockMinimumVersionAndroid); + final shortDynamicLink = await dynamicLinks.buildUrl(params); - expect(data.ios!.minimumVersion, kMockMinimumVersionIOS); + expect(shortDynamicLink, mockUri); + expect(shortDynamicLink.scheme, mockUri.scheme); + expect(shortDynamicLink.path, mockUri.path); - verify(mockDynamicLinksPlatform.getInitialLink()); + verify(dynamicLinks.buildUrl(params)); }); - // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() - // might return null link. In such a case we want to ignore the deep-link. - // test('for null link, returns null', () async { - // FirebaseDynamicLinks.channel - // .setMockMethodCallHandler((MethodCall methodCall) async { - // log.add(methodCall); - // switch (methodCall.method) { - // case 'FirebaseDynamicLinks#getInitialLink': - // return { - // 'link': null, - // 'android': { - // 'clickTimestamp': 1234567, - // 'minimumVersion': 12, - // }, - // 'ios': { - // 'minimumVersion': 'Version 12', - // }, - // }; - // default: - // return null; - // } - // }); - // - // final PendingDynamicLinkData? data = - // await FirebaseDynamicLinks.instance.getInitialLink(); - // - // expect(data, isNull); - // - // expect(log, [ - // isMethodCall( - // 'FirebaseDynamicLinks#getInitialLink', - // arguments: null, - // ) - // ]); - // }); - // - // test('for null result, returns null', () async { - // FirebaseDynamicLinks.channel - // .setMockMethodCallHandler((MethodCall methodCall) async { - // log.add(methodCall); - // switch (methodCall.method) { - // case 'FirebaseDynamicLinks#getInitialLink': - // return null; - // default: - // return null; - // } - // }); - // - // final PendingDynamicLinkData? data = - // await FirebaseDynamicLinks.instance.getInitialLink(); - // - // expect(data, isNull); - // - // expect(log, [ - // isMethodCall( - // 'FirebaseDynamicLinks#getInitialLink', - // arguments: null, - // ) - // ]); - // }); - // }); - // - // test('getDynamicLink', () async { - // final Uri argument = Uri.parse('short-link'); - // final PendingDynamicLinkData? data = - // await FirebaseDynamicLinks.instance.getDynamicLink(argument); - // - // expect(data!.link.host, 'google.com'); - // - // expect(log, [ - // isMethodCall('FirebaseDynamicLinks#getDynamicLink', - // arguments: { - // 'url': argument.toString(), - // }) - // ]); - // }); - // - // group('$DynamicLinkBuilder', () { - // test('shortenUrl', () async { - // final Uri url = Uri.parse('google.com'); - // final DynamicLinkParametersOptions options = - // DynamicLinkParametersOptions( - // shortDynamicLinkPathLength: - // ShortDynamicLinkPathLength.unguessable); - // - // await DynamicLinkBuilder.shortenUrl(url, options); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#shortenUrl', - // arguments: { - // 'url': url.toString(), - // 'dynamicLinkParametersOptions': { - // 'shortDynamicLinkPathLength': - // ShortDynamicLinkPathLength.unguessable.index, - // }, - // }, - // ), - // ]); - // }); - // - // test('$AndroidParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // androidParameters: AndroidParameters( - // fallbackUrl: Uri.parse('test-url'), - // minimumVersion: 1, - // packageName: 'test-package', - // ), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': { - // 'fallbackUrl': 'test-url', - // 'minimumVersion': 1, - // 'packageName': 'test-package', - // }, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': { - // 'fallbackUrl': 'test-url', - // 'minimumVersion': 1, - // 'packageName': 'test-package', - // }, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$DynamicLinkParametersOptions', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // dynamicLinkParametersOptions: DynamicLinkParametersOptions( - // shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': { - // 'shortDynamicLinkPathLength': - // ShortDynamicLinkPathLength.short.index, - // }, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': { - // 'shortDynamicLinkPathLength': - // ShortDynamicLinkPathLength.short.index, - // }, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$ShortDynamicLinkPathLength', () { - // expect(ShortDynamicLinkPathLength.unguessable.index, 0); - // expect(ShortDynamicLinkPathLength.short.index, 1); - // }); - // - // test('$GoogleAnalyticsParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // googleAnalyticsParameters: GoogleAnalyticsParameters( - // campaign: 'where', - // content: 'is', - // medium: 'my', - // source: 'cat', - // term: 'friend', - // ), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': { - // 'campaign': 'where', - // 'content': 'is', - // 'medium': 'my', - // 'source': 'cat', - // 'term': 'friend', - // }, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': { - // 'campaign': 'where', - // 'content': 'is', - // 'medium': 'my', - // 'source': 'cat', - // 'term': 'friend', - // }, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$IosParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // iosParameters: IosParameters( - // appStoreId: 'is', - // bundleId: 'this', - // customScheme: 'the', - // fallbackUrl: Uri.parse('place'), - // ipadBundleId: 'to', - // ipadFallbackUrl: Uri.parse('find'), - // minimumVersion: 'potatoes', - // ), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': { - // 'appStoreId': 'is', - // 'bundleId': 'this', - // 'customScheme': 'the', - // 'fallbackUrl': 'place', - // 'ipadBundleId': 'to', - // 'ipadFallbackUrl': 'find', - // 'minimumVersion': 'potatoes', - // }, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': { - // 'appStoreId': 'is', - // 'bundleId': 'this', - // 'customScheme': 'the', - // 'fallbackUrl': 'place', - // 'ipadBundleId': 'to', - // 'ipadFallbackUrl': 'find', - // 'minimumVersion': 'potatoes', - // }, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$ItunesConnectAnalyticsParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - // affiliateToken: 'hello', - // campaignToken: 'mister', - // providerToken: 'rose', - // ), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': { - // 'affiliateToken': 'hello', - // 'campaignToken': 'mister', - // 'providerToken': 'rose', - // }, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': { - // 'affiliateToken': 'hello', - // 'campaignToken': 'mister', - // 'providerToken': 'rose', - // }, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$NavigationInfoParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // navigationInfoParameters: - // NavigationInfoParameters(forcedRedirectEnabled: true), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': { - // 'forcedRedirectEnabled': true, - // }, - // 'socialMetaTagParameters': null, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': { - // 'forcedRedirectEnabled': true, - // }, - // 'socialMetaTagParameters': null, - // }, - // ), - // ]); - // }); - // - // test('$SocialMetaTagParameters', () async { - // final DynamicLinkBuilder components = DynamicLinkBuilder( - // uriPrefix: 'https://test-domain/', - // link: Uri.parse('test-link.com'), - // socialMetaTagParameters: SocialMetaTagParameters( - // description: 'describe', - // imageUrl: Uri.parse('thisimage'), - // title: 'bro', - // ), - // ); - // - // await components.buildUrl(); - // await components.buildShortLink(); - // - // expect(log, [ - // isMethodCall( - // 'DynamicLinkParameters#buildUrl', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': { - // 'description': 'describe', - // 'imageUrl': 'thisimage', - // 'title': 'bro', - // }, - // }, - // ), - // isMethodCall( - // 'DynamicLinkParameters#buildShortLink', - // arguments: { - // 'androidParameters': null, - // 'uriPrefix': 'https://test-domain/', - // 'dynamicLinkParametersOptions': null, - // 'googleAnalyticsParameters': null, - // 'iosParameters': null, - // 'itunesConnectAnalyticsParameters': null, - // 'link': 'test-link.com', - // 'navigationInfoParameters': null, - // 'socialMetaTagParameters': { - // 'description': 'describe', - // 'imageUrl': 'thisimage', - // 'title': 'bro', - // }, - // }, - // ), - // ]); - // }); - // }); - // - // group('onLink', () { - // OnLinkSuccessCallback? onSuccess; - // OnLinkErrorCallback? onError; - // final List successLog = - // []; - // final List errorLog = []; - // setUp(() { - // onSuccess = (linkData) async { - // successLog.add(linkData); - // }; - // onError = (error) async { - // errorLog.add(error); - // }; - // successLog.clear(); - // errorLog.clear(); - // }); - // - // Future callMethodHandler(String method, dynamic arguments) { - // const channel = FirebaseDynamicLinks.channel; - // final methodCall = MethodCall(method, arguments); - // final data = channel.codec.encodeMethodCall(methodCall); - // final Completer completer = Completer(); - // channel.binaryMessenger.handlePlatformMessage( - // channel.name, - // data, - // (data) { - // completer.complete(null); - // }, - // ); - // return completer.future; - // } - // - // test('onSuccess', () async { - // FirebaseDynamicLinks.instance - // .onLink(onSuccess: onSuccess, onError: onError); - // await callMethodHandler('onLinkSuccess', { - // 'link': 'https://google.com', - // 'android': { - // 'clickTimestamp': 1234567, - // 'minimumVersion': 12, - // }, - // 'ios': { - // 'minimumVersion': 'Version 12', - // }, - // }); - // - // expect(successLog, hasLength(1)); - // expect(errorLog, hasLength(0)); - // final success = successLog[0]!; - // - // expect(success.link, Uri.parse('https://google.com')); - // - // expect(success.android!.clickTimestamp, 1234567); - // expect(success.android!.minimumVersion, 12); - // - // expect(success.ios!.minimumVersion, 'Version 12'); - // }); - // - // test('onSuccess with null link', () async { - // FirebaseDynamicLinks.instance - // .onLink(onSuccess: onSuccess, onError: onError); - // await callMethodHandler('onLinkSuccess', { - // 'link': null, - // 'android': { - // 'clickTimestamp': 1234567, - // 'minimumVersion': 12, - // }, - // 'ios': { - // 'minimumVersion': 'Version 12', - // }, - // }); - // - // expect(successLog, hasLength(1)); - // expect(errorLog, hasLength(0)); - // final success = successLog[0]; - // - // expect(success, isNull); - // }); - // - // test('onSuccess with null', () async { - // FirebaseDynamicLinks.instance - // .onLink(onSuccess: onSuccess, onError: onError); - // await callMethodHandler('onLinkSuccess', null); - // - // expect(successLog, hasLength(1)); - // expect(errorLog, hasLength(0)); - // final success = successLog[0]; - // - // expect(success, isNull); - // }); - // - // test('onError', () async { - // FirebaseDynamicLinks.instance - // .onLink(onSuccess: onSuccess, onError: onError); - // await callMethodHandler('onLinkError', { - // 'code': 'code', - // 'message': 'message', - // 'details': 'details', - // }); - // - // expect(successLog, hasLength(0)); - // expect(errorLog, hasLength(1)); - // final failure = errorLog[0]; - // expect(failure.code, 'code'); - // expect(failure.message, 'message'); - // expect(failure.details, 'details'); - // }); + test("buildUrl with full 'DynamicLinkParameters' options", () async { + final Uri mockUri = Uri.parse('buildUrl'); + DynamicLinkParameters params = buildDynamicLinkParameters(); + + when(dynamicLinks.buildUrl(params)).thenAnswer((_) async => mockUri); + + final shortDynamicLink = await dynamicLinks.buildUrl(params); + + expect(shortDynamicLink, mockUri); + expect(shortDynamicLink.scheme, mockUri.scheme); + expect(shortDynamicLink.path, mockUri.path); + + verify(dynamicLinks.buildUrl(params)); + }); + }); + + group('buildShortLink', () { + test('buildShortLink', () async { + final Uri mockUri = Uri.parse('buildShortLink'); + final Uri previewLink = Uri.parse('previewLink'); + List warnings = ['warning']; + DynamicLinkParameters params = + DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); + final shortLink = ShortDynamicLink(mockUri, warnings, previewLink); + + when(dynamicLinks.buildShortLink(params)).thenAnswer( + (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + + final shortDynamicLink = await dynamicLinks.buildShortLink(params); + + expect(shortDynamicLink.warnings, shortLink.warnings); + expect(shortDynamicLink.shortUrl, shortLink.shortUrl); + expect(shortDynamicLink.previewLink, shortLink.previewLink); + + verify(dynamicLinks.buildShortLink(params)); + }); + + test("buildShortLink with full 'DynamicLinkParameters' options", + () async { + final Uri mockUri = Uri.parse('buildShortLink'); + final Uri previewLink = Uri.parse('previewLink'); + List warnings = ['warning']; + DynamicLinkParameters params = buildDynamicLinkParameters(); + final shortLink = ShortDynamicLink(mockUri, warnings, previewLink); + + when(dynamicLinks.buildShortLink(params)).thenAnswer( + (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + + final shortDynamicLink = await dynamicLinks.buildShortLink(params); + + expect(shortDynamicLink.warnings, shortLink.warnings); + expect(shortDynamicLink.shortUrl, shortLink.shortUrl); + expect(shortDynamicLink.previewLink, shortLink.previewLink); + + verify(dynamicLinks.buildShortLink(params)); + }); }); }); } -// FirebaseDynamicLinks.channel -// .setMockMethodCallHandler((MethodCall methodCall) async { -// log.add(methodCall); -// final Map returnUrl = { -// 'url': 'google.com', -// 'warnings': ['This is only a test link'], -// }; -// switch (methodCall.method) { -// case 'DynamicLinkParameters#buildUrl': -// return 'google.com'; -// case 'DynamicLinkParameters#buildShortLink': -// return returnUrl; -// case 'DynamicLinkParameters#shortenUrl': -// return returnUrl; -// case 'FirebaseDynamicLinks#getInitialLink': -// return { -// 'link': 'https://google.com', -// 'android': { -// 'clickTimestamp': 1234567, -// 'minimumVersion': 12, -// }, -// 'ios': { -// 'minimumVersion': 'Version 12', -// }, -// }; -// case 'FirebaseDynamicLinks#getDynamicLink': -// return { -// 'link': 'https://google.com', -// }; -// default: -// return null; -// } -// }); - class TestPendingDynamicLinkData extends PendingDynamicLinkData { - TestPendingDynamicLinkData() : super(kMockUri,PendingDynamicLinkDataAndroid(kMockClickTimestamp, kMockMinimumVersionAndroid), PendingDynamicLinkDataIOS(kMockMinimumVersionIOS)); + TestPendingDynamicLinkData(mockUri, mockClickTimestamp, + mockMinimumVersionAndroid, mockMinimumVersionIOS) + : super( + mockUri, + PendingDynamicLinkDataAndroid( + mockClickTimestamp, mockMinimumVersionAndroid), + PendingDynamicLinkDataIOS(mockMinimumVersionIOS)); +} + +final testData = TestPendingDynamicLinkData(Uri.parse('uri'), null, null, null); + +Future testFutureData() { + return Future.value(testData); } +Uri uri = Uri.parse('mock'); + class MockFirebaseDynamicLinks extends Mock with MockPlatformInterfaceMixin implements TestFirebaseDynamicLinksPlatform { - @override Future getInitialLink() { return super.noSuchMethod( Invocation.method(#getInitialLink, []), - returnValue: Future.value(TestPendingDynamicLinkData()), - returnValueForMissingStub: Future.value(TestPendingDynamicLinkData()), + returnValue: testFutureData(), + returnValueForMissingStub: testFutureData(), + ); + } + + @override + Future getDynamicLink(Uri uri) { + return super.noSuchMethod( + Invocation.method(#getDynamicLink, [], {#uri: uri}), + returnValue: testFutureData(), + returnValueForMissingStub: testFutureData(), + ); + } + + @override + Future buildUrl(DynamicLinkParameters parameters) { + return super.noSuchMethod( + Invocation.method(#getDynamicLink, [parameters]), + returnValue: Future.value(Uri.parse('buildUrl')), + returnValueForMissingStub: Future.value(Uri.parse('buildUrl')), ); } @override FirebaseDynamicLinksPlatform delegateFor({required FirebaseApp app}) { return super.noSuchMethod( - Invocation.method(#delegateFor, [], {#app: app}), - returnValue: MockFirebaseDynamicLinks(appInstance), + Invocation.method(#delegateFor, [], {#app: app}), + returnValue: MockFirebaseDynamicLinks(), returnValueForMissingStub: MockFirebaseDynamicLinks(), ); } + @override + Future shortenUrl(Uri uri, + [DynamicLinkParametersOptions? options]) { + return super.noSuchMethod( + Invocation.method(#shortenUrl, [uri, options]), + returnValue: Future.value( + ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + returnValueForMissingStub: Future.value( + ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + ); + } + + @override + Future buildShortLink(DynamicLinkParameters parameters) { + return super.noSuchMethod( + Invocation.method(#buildShortLink, [parameters]), + returnValue: Future.value( + ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + returnValueForMissingStub: Future.value( + ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + ); + } + + @override + Stream onLink() { + return super.noSuchMethod( + Invocation.method(#onLink, []), + returnValue: Stream.value(testData), + returnValueForMissingStub: Stream.value(testData), + ); + } } class TestFirebaseDynamicLinksPlatform extends FirebaseDynamicLinksPlatform { From 8829264effa2a1f67752026e76802468042f0c0a Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 10 Nov 2021 13:49:08 +0000 Subject: [PATCH 025/125] format: run formatter --- ...method_channel_firebase_dynamic_links.dart | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 0a4727b8012f..d8a8f6a599ca 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -131,11 +131,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { final Map? reply = await MethodChannelFirebaseDynamicLinks .channel .invokeMapMethod( - 'DynamicLinkParameters#shortenUrl', - _withChannelDefaults({ - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.data, - })); + 'DynamicLinkParameters#shortenUrl', + _withChannelDefaults({ + 'url': url.toString(), + 'dynamicLinkParametersOptions': options?.data, + })); return _parseShortLink(reply!); } @@ -143,7 +143,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Future buildUrl(DynamicLinkParameters parameters) async { final String? url = await MethodChannelFirebaseDynamicLinks.channel .invokeMethod('DynamicLinkParameters#buildUrl', - _withChannelDefaults(parameters.asMap())); + _withChannelDefaults(parameters.asMap())); return Uri.parse(url!); } @@ -151,10 +151,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Future buildShortLink( DynamicLinkParameters parameters) async { final Map? response = - await MethodChannelFirebaseDynamicLinks.channel - .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', - _withChannelDefaults(parameters.asMap())); + await MethodChannelFirebaseDynamicLinks.channel + .invokeMapMethod( + 'DynamicLinkParameters#buildShortLink', + _withChannelDefaults(parameters.asMap())); return _parseShortLink(response!); } From bf133f5874e4f42a36f29acce68f68bd7f5d674a Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 10 Nov 2021 16:09:47 +0000 Subject: [PATCH 026/125] test(dynamic_links): refactor tests for universal & PI --- .../test/firebase_dynamic_links_test.dart | 63 +++++--- .../lib/src/android_parameters.dart | 7 +- .../lib/src/dynamic_link.dart | 11 +- .../src/dynamic_link_parameter_options.dart | 7 +- .../lib/src/dynamic_link_parameters.dart | 14 +- .../lib/src/google_analytics_parameters.dart | 14 +- .../lib/src/ios_parameters.dart | 7 +- .../itunes_connect_analytics_parameters.dart | 7 +- ...method_channel_firebase_dynamic_links.dart | 19 ++- .../lib/src/navigation_info_parameters.dart | 7 +- .../lib/src/pending_dynamic_link_data.dart | 14 +- .../pending_dynamic_link_data_android.dart | 15 +- .../src/pending_dynamic_link_data_ios.dart | 12 +- .../lib/src/short_dynamic_link.dart | 15 +- .../lib/src/social_meta_tag_parameters.dart | 9 +- .../test/android_parameters_test.dart | 46 ++++++ .../dynamic_link_parameter_options_test.dart | 40 +++++ .../test/dynamic_link_parameters_test.dart | 152 ++++++++++++++++++ .../test/dynamic_link_test.dart | 35 ++++ .../test/ios_parameters_test.dart | 64 ++++++++ ...nes_connect_analytics_parameters_test.dart | 47 ++++++ .../test/navigation_info_parameters_test.dart | 38 +++++ .../test/pending_dynamic_link_data_test.dart | 56 +++++++ .../test/short_dynamic_link_test.dart | 43 +++++ .../test/social_meta_tag_parameters_test.dart | 46 ++++++ 25 files changed, 731 insertions(+), 57 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 4aa32bd3b157..8dcf7ce9dc36 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -1,5 +1,5 @@ // ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -186,8 +186,11 @@ void main() { shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); - when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer( - (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer((_) async => + ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink)); final shortDynamicLink = await dynamicLinks.shortenUrl(mockUri, options); @@ -240,10 +243,14 @@ void main() { List warnings = ['warning']; DynamicLinkParameters params = DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); - final shortLink = ShortDynamicLink(mockUri, warnings, previewLink); + final shortLink = ShortDynamicLink( + shortUrl: mockUri, warnings: warnings, previewLink: previewLink); - when(dynamicLinks.buildShortLink(params)).thenAnswer( - (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + when(dynamicLinks.buildShortLink(params)).thenAnswer((_) async => + ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink)); final shortDynamicLink = await dynamicLinks.buildShortLink(params); @@ -260,10 +267,14 @@ void main() { final Uri previewLink = Uri.parse('previewLink'); List warnings = ['warning']; DynamicLinkParameters params = buildDynamicLinkParameters(); - final shortLink = ShortDynamicLink(mockUri, warnings, previewLink); + final shortLink = ShortDynamicLink( + shortUrl: mockUri, warnings: warnings, previewLink: previewLink); - when(dynamicLinks.buildShortLink(params)).thenAnswer( - (_) async => ShortDynamicLink(mockUri, warnings, previewLink)); + when(dynamicLinks.buildShortLink(params)).thenAnswer((_) async => + ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink)); final shortDynamicLink = await dynamicLinks.buildShortLink(params); @@ -281,10 +292,12 @@ class TestPendingDynamicLinkData extends PendingDynamicLinkData { TestPendingDynamicLinkData(mockUri, mockClickTimestamp, mockMinimumVersionAndroid, mockMinimumVersionIOS) : super( - mockUri, - PendingDynamicLinkDataAndroid( - mockClickTimestamp, mockMinimumVersionAndroid), - PendingDynamicLinkDataIOS(mockMinimumVersionIOS)); + link: mockUri, + android: PendingDynamicLinkDataAndroid( + clickTimestamp: mockClickTimestamp, + minimumVersion: mockMinimumVersionAndroid), + ios: PendingDynamicLinkDataIOS( + minimumVersion: mockMinimumVersionIOS)); } final testData = TestPendingDynamicLinkData(Uri.parse('uri'), null, null, null); @@ -339,10 +352,14 @@ class MockFirebaseDynamicLinks extends Mock [DynamicLinkParametersOptions? options]) { return super.noSuchMethod( Invocation.method(#shortenUrl, [uri, options]), - returnValue: Future.value( - ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), - returnValueForMissingStub: Future.value( - ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + returnValue: Future.value(ShortDynamicLink( + shortUrl: uri, + warnings: ['warning'], + previewLink: Uri.parse('preview'))), + returnValueForMissingStub: Future.value(ShortDynamicLink( + shortUrl: uri, + warnings: ['warning'], + previewLink: Uri.parse('preview'))), ); } @@ -350,10 +367,14 @@ class MockFirebaseDynamicLinks extends Mock Future buildShortLink(DynamicLinkParameters parameters) { return super.noSuchMethod( Invocation.method(#buildShortLink, [parameters]), - returnValue: Future.value( - ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), - returnValueForMissingStub: Future.value( - ShortDynamicLink(uri, ['warning'], Uri.parse('preview'))), + returnValue: Future.value(ShortDynamicLink( + shortUrl: uri, + warnings: ['warning'], + previewLink: Uri.parse('preview'))), + returnValueForMissingStub: Future.value(ShortDynamicLink( + shortUrl: uri, + warnings: ['warning'], + previewLink: Uri.parse('preview'))), ); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart index e7f3b8d3b708..43818f0154f1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -19,9 +19,14 @@ class AndroidParameters { /// The Android app’s package name. final String packageName; - Map get data => { + Map asMap() => { 'fallbackUrl': fallbackUrl?.toString(), 'minimumVersion': minimumVersion, 'packageName': packageName, }; + + @override + String toString() { + return '$AndroidParameters($asMap())'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart index c73cd3e2f63f..f98eb1479d40 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart @@ -1,7 +1,16 @@ /// Response from creating a dynamic link with [DynamicLinkBuilder]. class DynamicLink { - const DynamicLink(this.url); + const DynamicLink({required this.url}); /// url value. final Uri url; + + Map asMap() => { + 'url': url.toString(), + }; + + @override + String toString() { + return '$DynamicLink($asMap())'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart index 591b787ccc0e..f3daa2d380e8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart @@ -7,7 +7,12 @@ class DynamicLinkParametersOptions { /// Specifies the length of the path component of a short Dynamic Link. final ShortDynamicLinkPathLength? shortDynamicLinkPathLength; - Map get data => { + Map asMap() => { 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, }; + + @override + String toString() { + return '$DynamicLinkParametersOptions($asMap())'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index db33114f006e..943bc765984e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -62,16 +62,16 @@ class DynamicLinkParameters { /// Returns the current instance as a [Map]. Map asMap() => { - 'androidParameters': androidParameters?.data, + 'androidParameters': androidParameters?.asMap(), 'uriPrefix': uriPrefix, - 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.data, - 'googleAnalyticsParameters': googleAnalyticsParameters?.data, - 'iosParameters': iosParameters?.data, + 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.asMap(), + 'googleAnalyticsParameters': googleAnalyticsParameters?.asMap(), + 'iosParameters': iosParameters?.asMap(), 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?.data, + itunesConnectAnalyticsParameters?.asMap(), 'link': link.toString(), - 'navigationInfoParameters': navigationInfoParameters?.data, - 'socialMetaTagParameters': socialMetaTagParameters?.data, + 'navigationInfoParameters': navigationInfoParameters?.asMap(), + 'socialMetaTagParameters': socialMetaTagParameters?.asMap(), }; @override diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart index 999e94e24a8b..e2b6927f0c3e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart @@ -8,13 +8,6 @@ class GoogleAnalyticsParameters { this.term, }); - GoogleAnalyticsParameters.empty() - : campaign = null, - content = null, - medium = null, - source = null, - term = null; - /// The utm_campaign analytics parameter. final String? campaign; @@ -30,11 +23,16 @@ class GoogleAnalyticsParameters { /// The utm_term analytics parameter. final String? term; - Map get data => { + Map asMap() => { 'campaign': campaign, 'content': content, 'medium': medium, 'source': source, 'term': term, }; + + @override + String toString() { + return '$GoogleAnalyticsParameters($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart index 0b8bc0594e91..0a54273797a5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart @@ -46,7 +46,7 @@ class IosParameters { /// declares higher [minimumVersion] than currently installed. final String? minimumVersion; - Map get data => { + Map asMap() => { 'appStoreId': appStoreId, 'bundleId': bundleId, 'customScheme': customScheme, @@ -55,4 +55,9 @@ class IosParameters { 'ipadFallbackUrl': ipadFallbackUrl?.toString(), 'minimumVersion': minimumVersion, }; + + @override + String toString() { + return '$IosParameters($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart index dbad99ab879d..fa656de9587c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -12,9 +12,14 @@ class ItunesConnectAnalyticsParameters { /// The iTunes Connect provider token. final String? providerToken; - Map get data => { + Map asMap() => { 'affiliateToken': affiliateToken, 'campaignToken': campaignToken, 'providerToken': providerToken, }; + + @override + String toString() { + return '$ItunesConnectAnalyticsParameters($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index d8a8f6a599ca..90f64f5a85c4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -61,21 +61,22 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { if (linkData['android'] != null) { final Map data = linkData['android']; androidData = PendingDynamicLinkDataAndroid( - data['clickTimestamp'], - data['minimumVersion'], + clickTimestamp: data['clickTimestamp'], + minimumVersion: data['minimumVersion'], ); } PendingDynamicLinkDataIOS? iosData; if (linkData['ios'] != null) { final Map data = linkData['ios']; - iosData = PendingDynamicLinkDataIOS(data['minimumVersion']); + iosData = + PendingDynamicLinkDataIOS(minimumVersion: data['minimumVersion']); } return PendingDynamicLinkData( - Uri.parse(link), - androidData, - iosData, + link: Uri.parse(link), + android: androidData, + ios: iosData, ); } @@ -134,7 +135,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'DynamicLinkParameters#shortenUrl', _withChannelDefaults({ 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.data, + 'dynamicLinkParametersOptions': options?.asMap(), })); return _parseShortLink(reply!); } @@ -161,6 +162,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ShortDynamicLink _parseShortLink(Map response) { final List? warnings = response['warnings']; return ShortDynamicLink( - Uri.parse(response['url']), warnings?.cast(), response['previewLink']); + shortUrl: Uri.parse(response['url']), + warnings: warnings?.cast(), + previewLink: response['previewLink']); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart index 0a3595d35d94..db98a91943e5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart @@ -13,7 +13,12 @@ class NavigationInfoParameters { /// click. final bool? forcedRedirectEnabled; - Map get data => { + Map asMap() => { 'forcedRedirectEnabled': forcedRedirectEnabled, }; + + @override + String toString() { + return '$NavigationInfoParameters($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart index 57b0437ab3ea..e294db053cb8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -3,7 +3,7 @@ import 'pending_dynamic_link_data_ios.dart'; /// Provides data from received dynamic link. class PendingDynamicLinkData { - const PendingDynamicLinkData(this.link, this.android, this.ios); + const PendingDynamicLinkData({required this.link, this.android, this.ios}); /// Provides Android specific data from received dynamic link. /// @@ -19,4 +19,16 @@ class PendingDynamicLinkData { /// Deep link parameter of the dynamic link. final Uri link; + + /// Returns the current instance as a [Map]. + Map asMap() => { + 'ios': ios?.asMap(), + 'android': android?.asMap(), + 'link': link.toString(), + }; + + @override + String toString() { + return '$PendingDynamicLinkData($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart index 02fffd48a32a..272f9f70b7e4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart @@ -1,9 +1,9 @@ /// Provides android specific data from received dynamic link. class PendingDynamicLinkDataAndroid { - const PendingDynamicLinkDataAndroid( + const PendingDynamicLinkDataAndroid({ this.clickTimestamp, this.minimumVersion, - ); + }); /// The time the user clicked on the dynamic link. /// @@ -18,4 +18,15 @@ class PendingDynamicLinkDataAndroid { /// If the installed app is an older version, the user is taken to the Play /// Store to upgrade the app. final int? minimumVersion; + + /// Returns the current instance as a [Map]. + Map asMap() => { + 'clickTimestamp': clickTimestamp, + 'minimumVersion': minimumVersion, + }; + + @override + String toString() { + return '$PendingDynamicLinkDataAndroid($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart index cbe4c4fe3c43..30789ed6dff7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -1,10 +1,20 @@ /// Provides iOS specific data from received dynamic link. class PendingDynamicLinkDataIOS { - const PendingDynamicLinkDataIOS(this.minimumVersion); + const PendingDynamicLinkDataIOS({this.minimumVersion}); /// The minimum version of your app that can open the link. /// /// It is app developer's responsibility to open AppStore when received link /// declares higher [minimumVersion] than currently installed. final String? minimumVersion; + + /// Returns the current instance as a [Map]. + Map asMap() => { + 'minimumVersion': minimumVersion, + }; + + @override + String toString() { + return '$PendingDynamicLinkDataIOS($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index b8c9c02dd010..9881d19c4db0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -1,6 +1,7 @@ /// Response from creating a short dynamic link with [DynamicLinkBuilder]. class ShortDynamicLink { - const ShortDynamicLink(this.shortUrl, this.warnings, this.previewLink); + const ShortDynamicLink( + {required this.shortUrl, this.warnings, this.previewLink}); /// Short url value. final Uri shortUrl; @@ -10,4 +11,16 @@ class ShortDynamicLink { /// Information about potential warnings on link creation. final List? warnings; + + /// Returns the current instance as a [Map]. + Map asMap() => { + 'shortUrl': shortUrl.toString(), + 'previewLink': previewLink.toString(), + 'warnings': warnings, + }; + + @override + String toString() { + return '$ShortDynamicLink($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart index 209bd7749a97..87c581522ac1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart @@ -1,6 +1,6 @@ /// The Dynamic Link Social Meta Tag parameters. class SocialMetaTagParameters { - SocialMetaTagParameters({this.description, this.imageUrl, this.title}); + const SocialMetaTagParameters({this.description, this.imageUrl, this.title}); /// The description to use when the Dynamic Link is shared in a social post. final String? description; @@ -11,9 +11,14 @@ class SocialMetaTagParameters { /// The title to use when the Dynamic Link is shared in a social post. final String? title; - Map get data => { + Map asMap() => { 'description': description, 'imageUrl': imageUrl?.toString(), 'title': title, }; + + @override + String toString() { + return '$SocialMetaTagParameters($asMap)'; + } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart new file mode 100644 index 000000000000..60a183717a70 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart @@ -0,0 +1,46 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Uri fallbackUrl = Uri.parse('fallbackUrl'); + const String packageName = 'packageName'; + const int minimumVersion = 21; + + group('$AndroidParameters', () { + AndroidParameters androidParams = AndroidParameters( + fallbackUrl: fallbackUrl, + minimumVersion: 1, + packageName: 'test-package', + ); + group('Constructor', () { + test('returns an instance of [AndroidParameters]', () { + expect(androidParams, isA()); + expect(androidParams.fallbackUrl, fallbackUrl); + expect(androidParams.minimumVersion, minimumVersion); + expect(androidParams.packageName, packageName); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = androidParams.asMap(); + + expect(result, isA>()); + + expect(result['fallbackUrl'], fallbackUrl); + expect(result['minimumVersion'], minimumVersion); + expect(result['packageName'], packageName); + }); + }); + + test('toString', () { + expect(androidParams.toString(), + equals('$AndroidParameters(${androidParams.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart new file mode 100644 index 000000000000..2590c1b01fb7 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart @@ -0,0 +1,40 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('$DynamicLinkParametersOptions', () { + DynamicLinkParametersOptions dynamicLinkOptions = + const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ); + group('Constructor', () { + test('returns an instance of [DynamicLinkParametersOptions]', () { + expect(dynamicLinkOptions, isA()); + expect(dynamicLinkOptions.shortDynamicLinkPathLength, + ShortDynamicLinkPathLength.short); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = dynamicLinkOptions.asMap(); + + expect(result, isA>()); + expect(result['shortDynamicLinkPathLength'], + ShortDynamicLinkPathLength.short); + }); + }); + + test('toString', () { + expect( + dynamicLinkOptions.toString(), + equals( + '$DynamicLinkParametersOptions(${dynamicLinkOptions.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart new file mode 100644 index 000000000000..5362cf2fd7a5 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -0,0 +1,152 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + AndroidParameters androidParams = AndroidParameters( + fallbackUrl: Uri.parse('test-url'), + minimumVersion: 1, + packageName: 'test-package', + ); + + GoogleAnalyticsParameters googleParams = const GoogleAnalyticsParameters( + campaign: 'campaign', + medium: 'medium', + source: 'source', + term: 'term', + content: 'content'); + + IosParameters iosParams = IosParameters( + appStoreId: 'appStoreId', + bundleId: 'bundleId', + customScheme: 'customScheme', + fallbackUrl: Uri.parse('fallbackUrl'), + ipadBundleId: 'ipadBundleId', + ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), + minimumVersion: 'minimumVersion'); + + ItunesConnectAnalyticsParameters itunesParams = + const ItunesConnectAnalyticsParameters( + affiliateToken: 'affiliateToken', + campaignToken: 'campaignToken', + providerToken: 'providerToken', + ); + + DynamicLinkParametersOptions parametersOptions = + const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); + + Uri link = Uri.parse('link'); + NavigationInfoParameters navigation = + const NavigationInfoParameters(forcedRedirectEnabled: true); + SocialMetaTagParameters social = SocialMetaTagParameters( + description: 'description', + imageUrl: Uri.parse('imageUrl'), + title: 'title'); + + String uriPrefix = 'https://'; + + group('$DynamicLinkParameters', () { + DynamicLinkParameters dynamicLinkParams = DynamicLinkParameters( + uriPrefix: uriPrefix, + link: link, + androidParameters: androidParams, + dynamicLinkParametersOptions: parametersOptions, + googleAnalyticsParameters: googleParams, + iosParameters: iosParams, + itunesConnectAnalyticsParameters: itunesParams, + navigationInfoParameters: navigation, + socialMetaTagParameters: social, + ); + group('Constructor', () { + test('returns an instance of [DynamicLinkParameters]', () { + expect(dynamicLinkParams, isA()); + expect(dynamicLinkParams.androidParameters, androidParams); + expect(dynamicLinkParams.uriPrefix, uriPrefix); + expect(dynamicLinkParams.link, link); + expect(dynamicLinkParams.googleAnalyticsParameters, googleParams); + expect(dynamicLinkParams.iosParameters, iosParams); + expect( + dynamicLinkParams.itunesConnectAnalyticsParameters, itunesParams); + expect(dynamicLinkParams.navigationInfoParameters, navigation); + expect(dynamicLinkParams.socialMetaTagParameters, social); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = dynamicLinkParams.asMap(); + + expect(result, isA>()); + expect(result['androidParameters']['fallbackUrl'], + dynamicLinkParams.androidParameters?.fallbackUrl.toString()); + expect(result['androidParameters']['minimumVersion'], + dynamicLinkParams.androidParameters?.minimumVersion); + expect(result['androidParameters']['packageName'], + dynamicLinkParams.androidParameters?.packageName); + expect(result['uriPrefix'], dynamicLinkParams.uriPrefix); + expect( + result['dynamicLinkParametersOptions'] + ['shortDynamicLinkPathLength'], + dynamicLinkParams + .dynamicLinkParametersOptions?.shortDynamicLinkPathLength); + expect(result['googleAnalyticsParameters']['campaign'], + dynamicLinkParams.googleAnalyticsParameters?.campaign); + expect(result['googleAnalyticsParameters']['content'], + dynamicLinkParams.googleAnalyticsParameters?.content); + expect(result['googleAnalyticsParameters']['medium'], + dynamicLinkParams.googleAnalyticsParameters?.medium); + expect(result['googleAnalyticsParameters']['source'], + dynamicLinkParams.googleAnalyticsParameters?.source); + expect(result['googleAnalyticsParameters']['term'], + dynamicLinkParams.googleAnalyticsParameters?.term); + expect(result['iosParameters']['appStoreId'], + dynamicLinkParams.iosParameters?.appStoreId); + expect(result['iosParameters']['bundleId'], + dynamicLinkParams.iosParameters?.bundleId); + expect(result['iosParameters']['customScheme'], + dynamicLinkParams.iosParameters?.customScheme); + expect(result['iosParameters']['fallbackUrl'], + dynamicLinkParams.iosParameters?.fallbackUrl.toString()); + expect(result['iosParameters']['ipadBundleId'], + dynamicLinkParams.iosParameters?.ipadBundleId); + expect(result['iosParameters']['ipadFallbackUrl'], + dynamicLinkParams.iosParameters?.ipadFallbackUrl.toString()); + expect(result['iosParameters']['minimumVersion'], + dynamicLinkParams.iosParameters?.minimumVersion); + expect( + result['itunesConnectAnalyticsParameters']['affiliateToken'], + dynamicLinkParams + .itunesConnectAnalyticsParameters?.affiliateToken); + expect( + result['itunesConnectAnalyticsParameters']['providerToken'], + dynamicLinkParams + .itunesConnectAnalyticsParameters?.providerToken); + expect( + result['itunesConnectAnalyticsParameters']['campaignToken'], + dynamicLinkParams + .itunesConnectAnalyticsParameters?.campaignToken); + expect(result['link'], dynamicLinkParams.link.toString()); + expect( + result['navigationInfoParameters']['forcedRedirectEnabled'], + dynamicLinkParams + .navigationInfoParameters?.forcedRedirectEnabled); + expect(result['socialMetaTagParameters']['description'], + dynamicLinkParams.socialMetaTagParameters?.description); + expect(result['socialMetaTagParameters']['imageUrl'], + dynamicLinkParams.socialMetaTagParameters?.imageUrl.toString()); + expect(result['socialMetaTagParameters']['title'], + dynamicLinkParams.socialMetaTagParameters?.title); + }); + }); + + test('toString', () { + expect(dynamicLinkParams.toString(), + equals('$DynamicLinkParameters(${dynamicLinkParams.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart new file mode 100644 index 000000000000..e0e8b3a82ca6 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart @@ -0,0 +1,35 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/src/dynamic_link.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Uri link = Uri.parse('dynamicLink'); + + group('$DynamicLink', () { + DynamicLink dynamicLink = DynamicLink(url: link); + group('Constructor', () { + test('returns an instance of [DynamicLink]', () { + expect(dynamicLink, isA()); + expect(dynamicLink.url, link); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = dynamicLink.asMap(); + + expect(result, isA>()); + expect(result['url'], link.toString()); + }); + }); + + test('toString', () { + expect(dynamicLink.toString(), + equals('$DynamicLink(${dynamicLink.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart new file mode 100644 index 000000000000..ae46656b0a22 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart @@ -0,0 +1,64 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + String appStoreId = 'appStoreId'; + String bundleId = 'bundleId'; + String customScheme = 'customScheme'; + String ipadBundleId = 'ipadBundleId'; + String minimumVersion = 'minimumVersion'; + Uri fallbackUrl = Uri.parse('fallbackUrl'); + Uri ipadFallbackUrl = Uri.parse('ipadFallbackUrl'); + + group('$IosParameters', () { + IosParameters iosParams = IosParameters( + appStoreId: appStoreId, + bundleId: bundleId, + customScheme: customScheme, + fallbackUrl: fallbackUrl, + ipadBundleId: ipadBundleId, + ipadFallbackUrl: ipadFallbackUrl, + minimumVersion: minimumVersion, + ); + + group('Constructor', () { + test('returns an instance of [IosParameters]', () { + expect(iosParams, isA()); + expect(iosParams.appStoreId, appStoreId); + expect(iosParams.bundleId, bundleId); + expect(iosParams.bundleId, bundleId); + expect(iosParams.customScheme, customScheme); + expect(iosParams.fallbackUrl, fallbackUrl); + expect(iosParams.ipadBundleId, ipadBundleId); + expect(iosParams.ipadFallbackUrl, ipadFallbackUrl); + expect(iosParams.minimumVersion, minimumVersion); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = iosParams.asMap(); + + expect(result, isA>()); + expect(result['appStoreId'], iosParams.appStoreId); + expect(result['bundleId'], iosParams.bundleId); + expect(result['customScheme'], iosParams.customScheme); + expect(result['fallbackUrl'], iosParams.fallbackUrl.toString()); + expect( + result['ipadFallbackUrl'], iosParams.ipadFallbackUrl.toString()); + expect(result['ipadBundleId'], iosParams.ipadBundleId); + expect(result['minimumVersion'], iosParams.minimumVersion); + }); + }); + + test('toString', () { + expect(iosParams.toString(), + equals('$DynamicLinkParameters(${iosParams.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart new file mode 100644 index 000000000000..ae82ea2c8637 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart @@ -0,0 +1,47 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + String affiliateToken = 'affiliateToken'; + String campaignToken = 'campaignToken'; + String providerToken = 'providerToken'; + + group('$ItunesConnectAnalyticsParameters', () { + ItunesConnectAnalyticsParameters itunesParams = + ItunesConnectAnalyticsParameters( + affiliateToken: affiliateToken, + campaignToken: campaignToken, + providerToken: providerToken, + ); + + group('Constructor', () { + test('returns an instance of [ItunesConnectAnalyticsParameters]', () { + expect(itunesParams, isA()); + expect(itunesParams.affiliateToken, affiliateToken); + expect(itunesParams.campaignToken, campaignToken); + expect(itunesParams.providerToken, providerToken); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = itunesParams.asMap(); + + expect(result, isA>()); + expect(result['affiliateToken'], itunesParams.affiliateToken); + expect(result['campaignToken'], itunesParams.campaignToken); + expect(result['providerToken'], itunesParams.providerToken); + }); + }); + + test('toString', () { + expect(itunesParams.toString(), + equals('$ItunesConnectAnalyticsParameters(${itunesParams.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart new file mode 100644 index 000000000000..0a0a030501da --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart @@ -0,0 +1,38 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + bool forcedRedirectEnabled = true; + + group('$NavigationInfoParameters', () { + NavigationInfoParameters navParams = + NavigationInfoParameters(forcedRedirectEnabled: forcedRedirectEnabled); + + group('Constructor', () { + test('returns an instance of [NavigationInfoParameters]', () { + expect(navParams, isA()); + expect(navParams.forcedRedirectEnabled, forcedRedirectEnabled); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = navParams.asMap(); + + expect(result, isA>()); + expect( + result['forcedRedirectEnabled'], navParams.forcedRedirectEnabled); + }); + }); + + test('toString', () { + expect(navParams.toString(), + equals('$NavigationInfoParameters(${navParams.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart new file mode 100644 index 000000000000..c0a1911e9ab1 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart @@ -0,0 +1,56 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Uri link = Uri.parse('pending-link'); + int minimumVersion = 12; + String minimumVersionIos = 'minimum version'; + int clickTimestamp = 12345345; + PendingDynamicLinkDataAndroid androidData = PendingDynamicLinkDataAndroid( + minimumVersion: minimumVersion, clickTimestamp: clickTimestamp); + PendingDynamicLinkDataIOS iosData = + PendingDynamicLinkDataIOS(minimumVersion: minimumVersionIos); + + group('$PendingDynamicLinkData', () { + PendingDynamicLinkData pendingDynamicLinkData = + PendingDynamicLinkData(link: link, android: androidData, ios: iosData); + + group('Constructor', () { + test('returns an instance of [PendingDynamicLinkData]', () { + expect(pendingDynamicLinkData, isA()); + expect(pendingDynamicLinkData.link, link); + expect(pendingDynamicLinkData.android?.clickTimestamp, + androidData.clickTimestamp); + expect(pendingDynamicLinkData.android?.minimumVersion, + androidData.minimumVersion); + expect( + pendingDynamicLinkData.ios?.minimumVersion, iosData.minimumVersion); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = pendingDynamicLinkData.asMap(); + + expect(result, isA>()); + expect(result['android']['clickTimestamp'], + pendingDynamicLinkData.android?.clickTimestamp); + expect(result['android']['minimumVersion'], + pendingDynamicLinkData.android?.minimumVersion); + expect(result['ios']['minimumVersion'], + pendingDynamicLinkData.ios?.minimumVersion); + expect(result['link'], pendingDynamicLinkData.link.toString()); + }); + }); + + test('toString', () { + expect(pendingDynamicLinkData.toString(), + equals('$PendingDynamicLinkData(${pendingDynamicLinkData.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart new file mode 100644 index 000000000000..caabee58aa62 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart @@ -0,0 +1,43 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + Uri link = Uri.parse('short-link'); + Uri previewLink = Uri.parse('preview-link'); + List warnings = ['warning']; + + group('$ShortDynamicLink', () { + ShortDynamicLink shortLink = ShortDynamicLink( + shortUrl: link, previewLink: previewLink, warnings: warnings); + + group('Constructor', () { + test('returns an instance of [ShortDynamicLink]', () { + expect(shortLink, isA()); + expect(shortLink.shortUrl, link); + expect(shortLink.previewLink, previewLink); + expect(shortLink.warnings, warnings); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = shortLink.asMap(); + + expect(result, isA>()); + expect(result['shortUrl'], shortLink.shortUrl.toString()); + expect(result['previewLink'], shortLink.previewLink.toString()); + expect(result['warnings'], shortLink.warnings); + }); + }); + + test('toString', () { + expect(shortLink.toString(), + equals('$ShortDynamicLink(${shortLink.asMap})')); + }); + }); + }); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart new file mode 100644 index 000000000000..ece2ec3b9907 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart @@ -0,0 +1,46 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + String description = 'description'; + String title = 'title'; + Uri imageUrl = Uri.parse('imageUrl'); + + group('$SocialMetaTagParameters', () { + SocialMetaTagParameters socialMetaTagParameters = SocialMetaTagParameters( + description: description, title: title, imageUrl: imageUrl); + + group('Constructor', () { + test('returns an instance of [SocialMetaTagParameters]', () { + expect(socialMetaTagParameters, isA()); + expect(socialMetaTagParameters.description, description); + expect(socialMetaTagParameters.title, title); + expect(socialMetaTagParameters.imageUrl, imageUrl); + }); + + group('asMap', () { + test('returns the current instance as a [Map]', () { + final result = socialMetaTagParameters.asMap(); + + expect(result, isA>()); + expect(result['description'], socialMetaTagParameters.description); + expect(result['title'], socialMetaTagParameters.title); + expect( + result['imageUrl'], socialMetaTagParameters.imageUrl.toString()); + }); + }); + + test('toString', () { + expect( + socialMetaTagParameters.toString(), + equals( + '$SocialMetaTagParameters(${socialMetaTagParameters.asMap})')); + }); + }); + }); +} From c62e6a1f37fe9440951ef59476365f0f08a2c89f Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 10 Nov 2021 17:45:52 +0000 Subject: [PATCH 027/125] test(dynamic_links): more reworking of tests & PI classes --- .../lib/src/android_parameters.dart | 2 +- .../lib/src/dynamic_link.dart | 2 +- .../src/dynamic_link_parameter_options.dart | 2 +- ...form_interface_firebase_dynamic_links.dart | 2 +- .../test/android_parameters_test.dart | 6 +- .../dynamic_link_parameter_options_test.dart | 2 +- .../test/dynamic_link_parameters_test.dart | 4 +- .../test/ios_parameters_test.dart | 4 +- ...d_channel_firebase_dynamic_links_test.dart | 174 ++++++++++++++++++ .../test/mock.dart | 71 +++++++ ...interface_firebase_dynamic_links_test.dart | 118 ++++++++++++ 11 files changed, 375 insertions(+), 12 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart index 43818f0154f1..e7ec24423425 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -27,6 +27,6 @@ class AndroidParameters { @override String toString() { - return '$AndroidParameters($asMap())'; + return '$AndroidParameters($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart index f98eb1479d40..c47944683ae0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart @@ -11,6 +11,6 @@ class DynamicLink { @override String toString() { - return '$DynamicLink($asMap())'; + return '$DynamicLink($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart index f3daa2d380e8..1bfaf4f5bdc8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart @@ -13,6 +13,6 @@ class DynamicLinkParametersOptions { @override String toString() { - return '$DynamicLinkParametersOptions($asMap())'; + return '$DynamicLinkParametersOptions($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 2d9f6ea13288..35e90a603805 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -67,7 +67,7 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('getDynamicLink() is not implemented'); } - /// Configures onLink listeners: it has two methods for success and failure. + /// Creates a stream for listening whenever a dynamic link becomes available Stream onLink() { throw UnimplementedError('onLink() is not implemented'); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart index 60a183717a70..be10ba8f72da 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart @@ -14,8 +14,8 @@ void main() { group('$AndroidParameters', () { AndroidParameters androidParams = AndroidParameters( fallbackUrl: fallbackUrl, - minimumVersion: 1, - packageName: 'test-package', + minimumVersion: minimumVersion, + packageName: packageName, ); group('Constructor', () { test('returns an instance of [AndroidParameters]', () { @@ -31,7 +31,7 @@ void main() { expect(result, isA>()); - expect(result['fallbackUrl'], fallbackUrl); + expect(result['fallbackUrl'], fallbackUrl.toString()); expect(result['minimumVersion'], minimumVersion); expect(result['packageName'], packageName); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart index 2590c1b01fb7..04d21d2df994 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart @@ -25,7 +25,7 @@ void main() { expect(result, isA>()); expect(result['shortDynamicLinkPathLength'], - ShortDynamicLinkPathLength.short); + ShortDynamicLinkPathLength.short.index); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index 5362cf2fd7a5..f68e62c3f5f7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -91,8 +91,8 @@ void main() { expect( result['dynamicLinkParametersOptions'] ['shortDynamicLinkPathLength'], - dynamicLinkParams - .dynamicLinkParametersOptions?.shortDynamicLinkPathLength); + dynamicLinkParams.dynamicLinkParametersOptions + ?.shortDynamicLinkPathLength?.index); expect(result['googleAnalyticsParameters']['campaign'], dynamicLinkParams.googleAnalyticsParameters?.campaign); expect(result['googleAnalyticsParameters']['content'], diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart index ae46656b0a22..17c39b350c73 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart @@ -56,8 +56,8 @@ void main() { }); test('toString', () { - expect(iosParams.toString(), - equals('$DynamicLinkParameters(${iosParams.asMap})')); + expect( + iosParams.toString(), equals('$IosParameters(${iosParams.asMap})')); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart new file mode 100644 index 000000000000..3e16f2b3a200 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -0,0 +1,174 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../mock.dart'; + +void main() { + setupFirebaseDynamicLinksMocks(); + late TestMethodChannelFirebaseDynamicLinks? mockDynamicLinks; + late FirebaseDynamicLinksPlatform? dynamicLinks; + final List logger = []; + int getInitialLinkCall = 1; + + group('$MethodChannelFirebaseDynamicLinks', () { + setUpAll(() async { + FirebaseApp app = await Firebase.initializeApp(); + + handleMethodCall((call) async { + logger.add(call); + final Map returnUrl = { + 'url': 'google.com', + 'warnings': ['This is only a test link'], + }; + switch (call.method) { + case 'DynamicLinkParameters#buildUrl': + return 'google.com'; + case 'DynamicLinkParameters#buildShortLink': + return returnUrl; + case 'DynamicLinkParameters#shortenUrl': + return returnUrl; + case 'FirebaseDynamicLinks#getInitialLink': + if (getInitialLinkCall == 3) { + return null; + } + return { + 'link': getInitialLinkCall == 2 ? null : 'https://google.com', + 'android': { + 'clickTimestamp': 1234567, + 'minimumVersion': 12, + }, + 'ios': { + 'minimumVersion': 'Version 12', + }, + }; + case 'FirebaseDynamicLinks#getDynamicLink': + return { + 'link': 'https://google.com', + }; + default: + return null; + } + }); + + dynamicLinks = MethodChannelFirebaseDynamicLinks(app: app); + mockDynamicLinks = TestMethodChannelFirebaseDynamicLinks(app); + }); + + setUp(() async { + logger.clear(); + }); + + group('getInitialLink', () { + test('link can be parsed', () async { + final PendingDynamicLinkData? data = + await mockDynamicLinks!.getInitialLink(); + + expect(data!.link, Uri.parse('https://google.com')); + + expect(data.android!.clickTimestamp, 1234567); + expect(data.android!.minimumVersion, 12); + + expect(data.ios!.minimumVersion, 'Version 12'); + + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + + // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() + // might return null link. In such a case we want to ignore the deep-link. + test('for null link, returns null', () async { + getInitialLinkCall = 2; + final PendingDynamicLinkData? data = + await mockDynamicLinks!.getInitialLink(); + + expect(data, isNull); + + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + + test('for null result, returns null', () async { + getInitialLinkCall = 3; + + final PendingDynamicLinkData? data = + await mockDynamicLinks!.getInitialLink(); + + expect(data, isNull); + + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#getInitialLink', + arguments: null, + ) + ]); + }); + }); + + group('getDynamicLink()', () { + test('getDynamicLink', () async { + final Uri argument = Uri.parse('short-link'); + final PendingDynamicLinkData? data = + await dynamicLinks!.getDynamicLink(argument); + + expect(data!.link.host, 'google.com'); + + expect(logger, [ + isMethodCall('FirebaseDynamicLinks#getDynamicLink', + arguments: { + 'url': argument.toString(), + }) + ]); + }); + }); + group('shortenUrl()', () { + test('shortenUrl', () async { + final Uri url = Uri.parse('google.com'); + const DynamicLinkParametersOptions options = + DynamicLinkParametersOptions( + shortDynamicLinkPathLength: + ShortDynamicLinkPathLength.unguessable); + + await dynamicLinks!.shortenUrl(url, options); + + expect(logger, [ + isMethodCall( + 'DynamicLinkParameters#shortenUrl', + arguments: { + 'url': url.toString(), + 'appName': '[DEFAULT]', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, + }, + }, + ), + ]); + }); + + test('buildUrl()', () async { + // TODO upto here + }); + }); + }); +} + +class TestMethodChannelFirebaseDynamicLinks + extends MethodChannelFirebaseDynamicLinks { + TestMethodChannelFirebaseDynamicLinks(FirebaseApp app) : super(app: app); +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart new file mode 100644 index 000000000000..1715706bb9a0 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart @@ -0,0 +1,71 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:firebase_dynamic_links_platform_interface/src/method_channel/method_channel_firebase_dynamic_links.dart'; + +typedef MethodCallCallback = dynamic Function(MethodCall methodCall); +typedef Callback = void Function(MethodCall call); + +int mockHandleId = 0; +int get nextMockHandleId => mockHandleId++; + +void setupFirebaseDynamicLinksMocks([Callback? customHandlers]) { + TestWidgetsFlutterBinding.ensureInitialized(); + + MethodChannelFirebase.channel.setMockMethodCallHandler((call) async { + if (call.method == 'Firebase#initializeCore') { + return [ + { + 'name': defaultFirebaseAppName, + 'options': { + 'apiKey': '123', + 'appId': '123', + 'messagingSenderId': '123', + 'projectId': '123', + }, + 'pluginConstants': {}, + } + ]; + } + + if (call.method == 'Firebase#initializeApp') { + return { + 'name': call.arguments['appName'], + 'options': call.arguments['options'], + 'pluginConstants': {}, + }; + } + + if (customHandlers != null) { + customHandlers(call); + } + + return null; + }); +} + +void handleMethodCall(MethodCallCallback methodCallCallback) => + MethodChannelFirebaseDynamicLinks.channel + .setMockMethodCallHandler((call) async { + return await methodCallCallback(call); + }); + +// TODO update error handling and test +// Future testExceptionHandling( +// String type, +// void Function() testMethod, +// ) async { +// await expectLater( +// () async => testMethod(), +// anyOf([ +// completes, +// if (type == 'PLATFORM' || type == 'EXCEPTION') +// throwsA(isA()) +// ]), +// ); +// } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart new file mode 100644 index 000000000000..fa9508e855f2 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -0,0 +1,118 @@ +// ignore_for_file: require_trailing_commas +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; + +import '../mock.dart'; + +void main() { + setupFirebaseDynamicLinksMocks(); + + TestFirebaseDynamicLinksPlatform? firebaseDynamicLinksPlatformPlatform; + + FirebaseApp? app; + FirebaseApp? secondaryApp; + final link = Uri.parse('uri'); + final parameters = DynamicLinkParameters(uriPrefix: '', link: link); + + group('$FirebaseDynamicLinksPlatform()', () { + setUpAll(() async { + app = await Firebase.initializeApp(); + secondaryApp = await Firebase.initializeApp( + name: 'testApp2', + options: const FirebaseOptions( + appId: '1:1234567890:ios:42424242424242', + apiKey: '123', + projectId: '123', + messagingSenderId: '1234567890', + ), + ); + + firebaseDynamicLinksPlatformPlatform = TestFirebaseDynamicLinksPlatform( + app!, + ); + }); + + test('Constructor', () { + expect(firebaseDynamicLinksPlatformPlatform, + isA()); + expect(firebaseDynamicLinksPlatformPlatform, isA()); + }); + + test('get.instance', () { + expect(FirebaseDynamicLinksPlatform.instance, + isA()); + expect(FirebaseDynamicLinksPlatform.instance.app.name, + equals(defaultFirebaseAppName)); + }); + + group('set.instance', () { + test('sets the current instance', () { + FirebaseDynamicLinksPlatform.instance = + TestFirebaseDynamicLinksPlatform(secondaryApp!); + + expect(FirebaseDynamicLinksPlatform.instance, + isA()); + expect( + FirebaseDynamicLinksPlatform.instance.app.name, equals('testApp2')); + }); + }); + + test('throws if .getInitialLink', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.getInitialLink(), + throwsA(isA().having((e) => e.message, 'message', + 'getInitialLink() is not implemented')), + ); + }); + + test('throws if .getDynamicLink', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.getDynamicLink(link), + throwsA(isA().having((e) => e.message, 'message', + 'getDynamicLink() is not implemented')), + ); + }); + + test('throws if .onLink', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.onLink(), + throwsA(isA().having( + (e) => e.message, 'message', 'onLink() is not implemented')), + ); + }); + + test('throws if .shortenUrl', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.shortenUrl(link), + throwsA(isA().having( + (e) => e.message, 'message', 'shortenUrl() is not implemented')), + ); + }); + + test('throws if .buildUrl', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.buildUrl(parameters), + throwsA(isA().having( + (e) => e.message, 'message', 'buildUrl() is not implemented')), + ); + }); + + test('throws if .buildShortLink', () { + expect( + () => firebaseDynamicLinksPlatformPlatform!.buildShortLink(parameters), + throwsA(isA().having((e) => e.message, 'message', + 'buildShortLink() is not implemented')), + ); + }); + }); +} + +class TestFirebaseDynamicLinksPlatform extends FirebaseDynamicLinksPlatform { + TestFirebaseDynamicLinksPlatform(FirebaseApp app) : super(appInstance: app); +} From d3575c55bdf894b39bb1511fda40738e0fca30ee Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 09:22:00 +0000 Subject: [PATCH 028/125] chore(dynamic_links): rename method channel instance --- .../FirebaseDynamicLinksPlugin.java | 18 +++++++++--------- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 6 +++--- .../method_channel_firebase_dynamic_links.dart | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index cc2ff4b1b7b7..8eb79e018b9d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -46,7 +46,7 @@ public class FirebaseDynamicLinksPlugin private MethodChannel channel; @Nullable private BinaryMessenger messenger; - private final Map streamHandlers = new HashMap<>(); + private final Map streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -107,7 +107,7 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments @Override public boolean onNewIntent(Intent intent) { // Passes intent to every listener for different app instances the user may create - for (OnLinkStreamHandler instance : streamHandlers.values()) { + for (io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler instance : streamHandlers.values()) { instance.sinkEvent(intent); } return false; @@ -120,14 +120,14 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re FirebaseDynamicLinks dynamicLinks = getDynamicLinkInstance(call.arguments()); switch (call.method) { - case "DynamicLinkBuilder#buildUrl": + case "FirebaseDynamicLinks#buildUrl": String url = buildUrl(call.arguments()); result.success(url); return; - case "DynamicLinkBuilder#buildShortLink": + case "FirebaseDynamicLinks#buildShortLink": methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); break; - case "DynamicLinkBuilder#shortenUrl": + case "FirebaseDynamicLinks#shortenUrl": urlBuilder.setLongLink(Uri.parse(call.argument("url"))); methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); break; @@ -152,9 +152,9 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re } else { Exception exception = task.getException(); result.error( - Constants.DEFAULT_ERROR_CODE, + io.flutter.plugins.firebasedynamiclinks.Constants.DEFAULT_ERROR_CODE, exception != null ? exception.getMessage() : null, - Utils.getExceptionDetails(exception)); + io.flutter.plugins.firebasedynamiclinks.Utils.getExceptionDetails(exception)); } }); } @@ -228,7 +228,7 @@ private Task> getDynamicLink( Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } - return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + return io.flutter.plugins.firebasedynamiclinks.Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); }); } @@ -355,7 +355,7 @@ private Task registerOnLinkListener( return Tasks.call( cachedThreadPool, () -> { - final OnLinkStreamHandler handler = new OnLinkStreamHandler(dynamicLinks); + final io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler handler = new io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler(dynamicLinks); final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; final EventChannel channel = new EventChannel(messenger, name); channel.setStreamHandler(handler); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 4c50fa21bfac..99ef32ac1af1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -149,11 +149,11 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSLog(@"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app"); } - if ([@"DynamicLinkBuilder#buildUrl" isEqualToString:call.method]) { + if ([@"FirebaseDynamicLinks#buildUrl" isEqualToString:call.method]) { [self buildUrl:call.arguments withMethodCallResult:methodCallResult]; - } else if ([@"DynamicLinkBuilder#buildShortLink" isEqualToString:call.method]) { + } else if ([@"FirebaseDynamicLinks#buildShortLink" isEqualToString:call.method]) { [self buildShortLink:call.arguments withMethodCallResult:methodCallResult]; - } else if ([@"DynamicLinkParameters#shortenUrl" isEqualToString:call.method]) { + } else if ([@"FirebaseDynamicLinks#shortenUrl" isEqualToString:call.method]) { [self shortenUrl:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { [self getInitialLink:methodCallResult]; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 90f64f5a85c4..e29b50524f3f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -132,7 +132,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { final Map? reply = await MethodChannelFirebaseDynamicLinks .channel .invokeMapMethod( - 'DynamicLinkParameters#shortenUrl', + 'FirebaseDynamicLinks#shortenUrl', _withChannelDefaults({ 'url': url.toString(), 'dynamicLinkParametersOptions': options?.asMap(), @@ -143,7 +143,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future buildUrl(DynamicLinkParameters parameters) async { final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('DynamicLinkParameters#buildUrl', + .invokeMethod('FirebaseDynamicLinks#buildUrl', _withChannelDefaults(parameters.asMap())); return Uri.parse(url!); } @@ -154,7 +154,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { final Map? response = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( - 'DynamicLinkParameters#buildShortLink', + 'FirebaseDynamicLinks#buildShortLink', _withChannelDefaults(parameters.asMap())); return _parseShortLink(response!); } From e66739549b014043da46b9cbfb4e9844c9dab07b Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 11:56:59 +0000 Subject: [PATCH 029/125] chore(dynamic_links): conditional mapping for params --- .../lib/src/dynamic_link_parameters.dart | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index 943bc765984e..30c657c2c454 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -61,18 +61,26 @@ class DynamicLinkParameters { final SocialMetaTagParameters? socialMetaTagParameters; /// Returns the current instance as a [Map]. - Map asMap() => { + Map asMap(){ + return { + 'uriPrefix': uriPrefix, + 'link': link.toString(), + if (androidParameters != null) 'androidParameters': androidParameters?.asMap(), - 'uriPrefix': uriPrefix, + if (dynamicLinkParametersOptions != null) 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.asMap(), + if (googleAnalyticsParameters != null) 'googleAnalyticsParameters': googleAnalyticsParameters?.asMap(), - 'iosParameters': iosParameters?.asMap(), + if (iosParameters != null) 'iosParameters': iosParameters?.asMap(), + if (itunesConnectAnalyticsParameters != null) 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?.asMap(), - 'link': link.toString(), + itunesConnectAnalyticsParameters?.asMap(), + if (navigationInfoParameters != null) 'navigationInfoParameters': navigationInfoParameters?.asMap(), + if (socialMetaTagParameters != null) 'socialMetaTagParameters': socialMetaTagParameters?.asMap(), - }; + }; + } @override String toString() { From 343583c1dd0a0d9feff8eedf52b334f27eecdc20 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 11:57:30 +0000 Subject: [PATCH 030/125] chore(dynamic_links): todo note about multi app --- .../firebase_dynamic_links/lib/src/firebase_dynamic_links.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 2120249f3c4a..3f06ccbd599c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -26,6 +26,7 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { if (_cachedInstances.containsKey(app.name)) { return _cachedInstances[app.name]!; } + //TODO notify user or even throw error that default only for web and iOS?? FirebaseDynamicLinks newInstance = FirebaseDynamicLinks._(app: app); _cachedInstances[app.name] = newInstance; From 1d7c37ec9a5386cf5a62dff5df8af7a2440352a2 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 11:58:21 +0000 Subject: [PATCH 031/125] test(dynamic_links): update method channel tests --- ...d_channel_firebase_dynamic_links_test.dart | 233 ++++++++++++++++-- .../test/mock.dart | 27 ++ 2 files changed, 245 insertions(+), 15 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index 3e16f2b3a200..fe1a9dea7689 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -2,6 +2,8 @@ // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:async'; +import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; @@ -11,10 +13,68 @@ import 'package:flutter_test/flutter_test.dart'; import '../mock.dart'; +DynamicLinkParameters buildDynamicLinkParameters() { + AndroidParameters android = AndroidParameters( + fallbackUrl: Uri.parse('fallbackUrl'), + minimumVersion: 1, + packageName: 'test-package', + ); + + GoogleAnalyticsParameters google = const GoogleAnalyticsParameters( + campaign: 'campaign', + medium: 'medium', + source: 'source', + term: 'term', + content: 'content', + ); + + IosParameters ios = IosParameters( + appStoreId: 'appStoreId', + bundleId: 'bundleId', + customScheme: 'customScheme', + fallbackUrl: Uri.parse('fallbackUrl'), + ipadBundleId: 'ipadBundleId', + ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), + minimumVersion: 'minimumVersion'); + + ItunesConnectAnalyticsParameters itunes = + const ItunesConnectAnalyticsParameters( + affiliateToken: 'affiliateToken', + campaignToken: 'campaignToken', + providerToken: 'providerToken', + ); + + DynamicLinkParametersOptions parametersOptions = + const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); + + Uri link = Uri.parse('link'); + NavigationInfoParameters navigation = + const NavigationInfoParameters(forcedRedirectEnabled: true); + SocialMetaTagParameters social = SocialMetaTagParameters( + description: 'description', + imageUrl: Uri.parse('imageUrl'), + title: 'title'); + + String uriPrefix = 'https://'; + + return DynamicLinkParameters( + uriPrefix: uriPrefix, + link: link, + androidParameters: android, + dynamicLinkParametersOptions: parametersOptions, + googleAnalyticsParameters: google, + iosParameters: ios, + itunesConnectAnalyticsParameters: itunes, + navigationInfoParameters: navigation, + socialMetaTagParameters: social, + ); +} + void main() { setupFirebaseDynamicLinksMocks(); late TestMethodChannelFirebaseDynamicLinks? mockDynamicLinks; - late FirebaseDynamicLinksPlatform? dynamicLinks; + late FirebaseDynamicLinksPlatform dynamicLinks; final List logger = []; int getInitialLinkCall = 1; @@ -29,12 +89,17 @@ void main() { 'warnings': ['This is only a test link'], }; switch (call.method) { - case 'DynamicLinkParameters#buildUrl': + case 'FirebaseDynamicLinks#buildUrl': return 'google.com'; - case 'DynamicLinkParameters#buildShortLink': + case 'FirebaseDynamicLinks#buildShortLink': return returnUrl; - case 'DynamicLinkParameters#shortenUrl': + case 'FirebaseDynamicLinks#shortenUrl': return returnUrl; + case 'FirebaseDynamicLinks#onLink': + const String name = 'FirebaseDynamicLinks#onLink'; + print('RRRRRRR'); + handleEventChannel(name, logger); + return name; case 'FirebaseDynamicLinks#getInitialLink': if (getInitialLinkCall == 3) { return null; @@ -66,10 +131,10 @@ void main() { logger.clear(); }); - group('getInitialLink', () { + group('getInitialLink()', () { test('link can be parsed', () async { final PendingDynamicLinkData? data = - await mockDynamicLinks!.getInitialLink(); + await dynamicLinks.getInitialLink(); expect(data!.link, Uri.parse('https://google.com')); @@ -88,10 +153,10 @@ void main() { // Both iOS FIRDynamicLink.url and android PendingDynamicLinkData.getUrl() // might return null link. In such a case we want to ignore the deep-link. - test('for null link, returns null', () async { + test('for null link, return null', () async { getInitialLinkCall = 2; final PendingDynamicLinkData? data = - await mockDynamicLinks!.getInitialLink(); + await dynamicLinks.getInitialLink(); expect(data, isNull); @@ -107,7 +172,7 @@ void main() { getInitialLinkCall = 3; final PendingDynamicLinkData? data = - await mockDynamicLinks!.getInitialLink(); + await dynamicLinks.getInitialLink(); expect(data, isNull); @@ -124,7 +189,7 @@ void main() { test('getDynamicLink', () async { final Uri argument = Uri.parse('short-link'); final PendingDynamicLinkData? data = - await dynamicLinks!.getDynamicLink(argument); + await dynamicLinks.getDynamicLink(argument); expect(data!.link.host, 'google.com'); @@ -144,11 +209,11 @@ void main() { shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); - await dynamicLinks!.shortenUrl(url, options); + await dynamicLinks.shortenUrl(url, options); expect(logger, [ isMethodCall( - 'DynamicLinkParameters#shortenUrl', + 'FirebaseDynamicLinks#shortenUrl', arguments: { 'url': url.toString(), 'appName': '[DEFAULT]', @@ -160,12 +225,150 @@ void main() { ), ]); }); + group('buildUrl()', () { + test('buildUrl', () async { + DynamicLinkParameters options = buildDynamicLinkParameters(); + + await dynamicLinks.buildUrl(options); + + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#buildUrl', + arguments: { + 'appName': '[DEFAULT]', + 'uriPrefix': 'https://', + 'link': 'link', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, + }, + 'androidParameters': { + 'fallbackUrl': 'fallbackUrl', + 'minimumVersion': 1, + 'packageName': 'test-package' + }, + 'googleAnalyticsParameters': { + 'campaign': 'campaign', + 'content': 'content', + 'medium': 'medium', + 'source': 'source', + 'term': 'term' + }, + 'iosParameters': { + 'appStoreId': 'appStoreId', + 'bundleId': 'bundleId', + 'customScheme': 'customScheme', + 'fallbackUrl': 'fallbackUrl', + 'ipadBundleId': 'ipadBundleId', + 'ipadFallbackUrl': 'ipadFallbackUrl', + 'minimumVersion': 'minimumVersion', + }, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'affiliateToken', + 'campaignToken': 'campaignToken', + 'providerToken': 'providerToken', + }, + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': { + 'description': 'description', + 'imageUrl': 'imageUrl', + 'title': 'title', + }, + }, + ), + ]); + }); + }); + }); + + group('onLink()', () { + StreamSubscription? subscription; + + tearDown(() { + subscription?.cancel(); + }); + + test('returns [Stream]', () async { + // Checks that `onLink` does not throw UnimplementedError + expect(dynamicLinks.onLink(), isNotNull); + }); + + test('listens to incoming changes', () async { + Stream stream = + dynamicLinks.onLink().asBroadcastStream(); - test('buildUrl()', () async { - // TODO upto here + await injectEventChannelResponse('FirebaseDynamicLinks#onLink', { + 'link': 'link', + 'ios': {'minimumVersion': 'minimumVersion'} + }); + // TODO find out why event isn't emitted + // await expectLater( + // stream, + // emits(isA() + // .having((r) => r.link, 'link', 'link')), + // ); + + }); + }); + group('buildShortLink()', () { + test('buildShortLink', () async { + DynamicLinkParameters options = buildDynamicLinkParameters(); + + await dynamicLinks.buildShortLink(options); + + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#buildShortLink', + arguments: { + 'appName': '[DEFAULT]', + 'uriPrefix': 'https://', + 'link': 'link', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, + }, + 'androidParameters': { + 'fallbackUrl': 'fallbackUrl', + 'minimumVersion': 1, + 'packageName': 'test-package' + }, + 'googleAnalyticsParameters': { + 'campaign': 'campaign', + 'content': 'content', + 'medium': 'medium', + 'source': 'source', + 'term': 'term' + }, + 'iosParameters': { + 'appStoreId': 'appStoreId', + 'bundleId': 'bundleId', + 'customScheme': 'customScheme', + 'fallbackUrl': 'fallbackUrl', + 'ipadBundleId': 'ipadBundleId', + 'ipadFallbackUrl': 'ipadFallbackUrl', + 'minimumVersion': 'minimumVersion', + }, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'affiliateToken', + 'campaignToken': 'campaignToken', + 'providerToken': 'providerToken', + }, + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': { + 'description': 'description', + 'imageUrl': 'imageUrl', + 'title': 'title', + }, + }, + ), + ]); + }); }); }); - }); } class TestMethodChannelFirebaseDynamicLinks diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart index 1715706bb9a0..6c9acd61a648 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart @@ -55,6 +55,33 @@ void handleMethodCall(MethodCallCallback methodCallCallback) => return await methodCallCallback(call); }); + +void handleEventChannel( + final String name, [ + List? log, + ]) { + MethodChannel(name).setMockMethodCallHandler((MethodCall methodCall) async { + log?.add(methodCall); + switch (methodCall.method) { + case 'listen': + break; + case 'cancel': + default: + return null; + } + }); +} + + +Future injectEventChannelResponse( + String channelName, Map event) async { + await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage( + channelName, + MethodChannelFirebaseDynamicLinks.channel.codec.encodeSuccessEnvelope(event), + (_) {}, + ); +} + // TODO update error handling and test // Future testExceptionHandling( // String type, From 9761839bd5f7e768e8df71b32c84c9eec50745e2 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 11:58:50 +0000 Subject: [PATCH 032/125] chore(dynamic_links): tidy up method channel --- .../method_channel_firebase_dynamic_links.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index e29b50524f3f..3b7926beb4eb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -19,7 +19,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { MethodChannelFirebaseDynamicLinks({FirebaseApp? app}) : super(appInstance: app); - /// The [FirebaseApp] instance to which this [FirebaseDatabase] belongs. + /// The [FirebaseApp] instance to which this [FirebaseDynamicLinks] belongs. /// /// If null, the default [FirebaseApp] is used. @@ -43,7 +43,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return MethodChannelFirebaseDynamicLinks(app: app); } - /// Attaches generic default values to method channel arguments. + /// Attaches generic default values to method channel arguments to allow multi-app support for android. Map _withChannelDefaults(Map other) { return { 'appName': appInstance?.name ?? defaultFirebaseAppName, @@ -110,9 +110,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'FirebaseDynamicLinks#onLink', { 'appName': app.name, }) as String; - + final events = onLinkChannel(name); snapshotStream = - onLinkChannel(name).receiveBroadcastStream().listen((event) { + events.receiveBroadcastStream().listen((event) { controller.add(getPendingDynamicLinkDataFromMap(event)); }, onError: (error, stack) { controller.addError(convertPlatformException(error), stack); From 5598e2227017f511b878a0fb576889d17ed71281 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 14:03:51 +0000 Subject: [PATCH 033/125] chore(dynamic_links): update exports & example --- .../firebase_dynamic_links/example/lib/main.dart | 15 ++++++++++++++- .../firebase_dynamic_links/example/pubspec.yaml | 2 -- .../lib/firebase_dynamic_links.dart | 6 ++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 23122b3684ed..f8bd9ac28e0f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -5,13 +5,26 @@ import 'dart:async'; +import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; -void main() { +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: const FirebaseOptions( + apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0', + appId: '1:448618578101:ios:4cd06f56e36384acac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + ) + ); runApp(MaterialApp( title: 'Dynamic Links Example', routes: { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml index f0f432fa33bd..ee9165a7accb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -23,8 +23,6 @@ dependency_overrides: path: ../../../firebase_core/firebase_core firebase_core_platform_interface: path: ../../../firebase_core/firebase_core_platform_interface - firebase_core_web: - path: ../../../firebase_core/firebase_core_web dev_dependencies: drive: 0.1.0 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index a6be06e80495..416f46e0e947 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -9,7 +9,9 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; -import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart' - show FirebasePluginPlatform; +export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart' + show AndroidParameters, DynamicLink, DynamicLinkParameters, DynamicLinkParametersOptions, FirebaseDynamicLinksPlatform, FirebasePluginPlatform, GoogleAnalyticsParameters, IosParameters, ItunesConnectAnalyticsParameters, NavigationInfoParameters, PendingDynamicLinkData, PendingDynamicLinkDataAndroid, PendingDynamicLinkDataIOS, ShortDynamicLink, ShortDynamicLinkPathLength, SocialMetaTagParameters; +import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; + part 'src/firebase_dynamic_links.dart'; From fa9635b9211c4a102339bf570d11c24da2fe3abf Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 14:04:24 +0000 Subject: [PATCH 034/125] tests(dynamic_links): update e2e --- .../firebase_dynamic_links_e2e.dart | 19 ++++++++++++------- .../firebase_dynamic_links_e2e_test.dart | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart index d82ca21c2738..e82e943ec6f2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart @@ -1,16 +1,21 @@ // ignore_for_file: require_trailing_commas -// @dart = 2.9 -// Copyright 2020, the Chromium project authors. Please see the AUTHORS file +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'package:drive/drive.dart' as drive; +import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter_test/flutter_test.dart'; void testsMain() { + setUpAll(() async { + await Firebase.initializeApp(); + }); + group('DynamicLinks', () { test('buildUrl', () async { + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; const String androidPackageName = 'io.flutter.plugins.firebasedynamiclinksexample'; const String iosBundleId = @@ -18,23 +23,23 @@ void testsMain() { const String urlHost = 'cx4k7.app.goo.gl'; const String link = 'https://dynamic.link.example/helloworld'; - final DynamicLinkBuilder parameters = DynamicLinkBuilder( + final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://$urlHost', link: Uri.parse(link), - androidParameters: AndroidParameters( + androidParameters: const AndroidParameters( packageName: androidPackageName, minimumVersion: 1, ), - dynamicLinkParametersOptions: DynamicLinkParametersOptions( + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: IosParameters( + iosParameters: const IosParameters( bundleId: iosBundleId, minimumVersion: '2', ), ); - final Uri uri = await parameters.buildUrl(); + final Uri uri = await dynamicLinks.buildUrl(parameters); // androidParameters.minimumVersion expect( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart index 9ea0d073c35e..8e7e4602061a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart @@ -1,6 +1,6 @@ // ignore_for_file: require_trailing_commas // @dart = 2.9 -// Copyright 2020, the Chromium project authors. Please see the AUTHORS file +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. From 7e1c4762850db8b7e6e24949555ca7968006305b Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 15:28:02 +0000 Subject: [PATCH 035/125] chore(dynamic_links): update example pubspecs --- packages/firebase_auth/firebase_auth/example/pubspec.yaml | 2 ++ .../firebase_dynamic_links/example/lib/main.dart | 2 +- .../firebase_dynamic_links/example/pubspec.yaml | 2 +- .../example/test_driver/firebase_dynamic_links_e2e_test.dart | 2 -- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/firebase_auth/firebase_auth/example/pubspec.yaml b/packages/firebase_auth/firebase_auth/example/pubspec.yaml index 53abfba41c33..fab109cc269d 100644 --- a/packages/firebase_auth/firebase_auth/example/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/example/pubspec.yaml @@ -32,6 +32,8 @@ dependency_overrides: path: ../../../firebase_core/firebase_core_web firebase_dynamic_links: path: ../../../firebase_dynamic_links/firebase_dynamic_links + firebase_dynamic_links_platform_interface: + path: ../../../firebase_dynamic_links/firebase_dynamic_links_platform_interface dev_dependencies: drive: 1.0.0-1.0.nullsafety.1 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index f8bd9ac28e0f..48f39c8f8f5e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -1,5 +1,5 @@ // ignore_for_file: require_trailing_commas -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml index ee9165a7accb..7e798410968e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -25,7 +25,7 @@ dependency_overrides: path: ../../../firebase_core/firebase_core_platform_interface dev_dependencies: - drive: 0.1.0 + drive: 1.0.0-1.0.nullsafety.1 flutter_driver: sdk: flutter flutter_test: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart index 8e7e4602061a..bb4e596d9ec0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e_test.dart @@ -1,5 +1,3 @@ -// ignore_for_file: require_trailing_commas -// @dart = 2.9 // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. From 90652b48468aacca0aa84f0a41c51f4229cd1efb Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 11 Nov 2021 17:33:16 +0000 Subject: [PATCH 036/125] fix(dynamic_links, android): return Task --- .../firebasedynamiclinks/FirebaseDynamicLinksPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index 8eb79e018b9d..0285e556ab02 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -372,7 +372,7 @@ private static T valueFor(String key, Map map) { @Override public Task> getPluginConstantsForFirebaseApp(FirebaseApp firebaseApp) { - return null; + return Tasks.call(cachedThreadPool, () -> null); } @Override From 9270264d242cc9c27fa9295b6f1b083e9a7a4966 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 10:43:19 +0000 Subject: [PATCH 037/125] refactor(dynamic_links): remove google-services.json --- .../example/android/app/build.gradle | 1 - .../example/android/app/google-services.json | 113 ------------------ 2 files changed, 114 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle index 9ed11651323b..096a11864303 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle @@ -22,7 +22,6 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' -apply plugin: 'com.google.gms.google-services' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json deleted file mode 100644 index 7123ea9b2ebd..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/google-services.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "project_info": { - "project_number": "479882132969", - "firebase_url": "https://my-flutter-proj.firebaseio.com", - "project_id": "my-flutter-proj", - "storage_bucket": "my-flutter-proj.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:632cdf3fc0a17139", - "android_client_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebasedynamiclinksexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "cvbxvzv" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:479882132969:android:215a22700e1b466b", - "android_client_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample" - } - }, - "oauth_client": [ - { - "client_id": "479882132969-8h4kiv8m7ho4tvn6uuujsfcrf69unuf7.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "io.flutter.plugins.firebaseperformanceexample", - "certificate_hash": "e733b7a303250b63e06de6f7c9767c517d69cfa0" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyCrZz9T0Pg0rDnpxfNuPBrOxGhXskfebXs" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 2, - "other_platform_oauth_client": [ - { - "client_id": "479882132969-pkn7lcq09ln9vfk4k52r634vh805dk3g.apps.googleusercontent.com", - "client_type": 2, - "ios_info": { - "bundle_id": "cvbxvzv" - } - }, - { - "client_id": "479882132969-0d20fkjtr1p8evfomfkf3vmi50uajml2.apps.googleusercontent.com", - "client_type": 3 - } - ] - }, - "ads_service": { - "status": 2 - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file From fa4149a4e10d7ba69a4e498e06a047e88df32cad Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 10:46:05 +0000 Subject: [PATCH 038/125] fix(dynamic_links, android): nullable link --- .../FirebaseDynamicLinksPlugin.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index 0285e556ab02..d744b1a3e95a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -116,7 +116,6 @@ public boolean onNewIntent(Intent intent) { @Override public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result result) { Task methodCallTask; - DynamicLink.Builder urlBuilder = setupParameters(call.arguments()); FirebaseDynamicLinks dynamicLinks = getDynamicLinkInstance(call.arguments()); switch (call.method) { @@ -125,11 +124,13 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re result.success(url); return; case "FirebaseDynamicLinks#buildShortLink": + DynamicLink.Builder urlBuilder = setupParameters(call.arguments()); methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); break; case "FirebaseDynamicLinks#shortenUrl": - urlBuilder.setLongLink(Uri.parse(call.argument("url"))); - methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); + DynamicLink.Builder urlBuilderShorten = setupParameters(call.arguments()); + urlBuilderShorten.setLongLink(Uri.parse(call.argument("url"))); + methodCallTask = buildShortLink(urlBuilderShorten, call.argument("dynamicLinkParametersOptions")); break; case "FirebaseDynamicLinks#getDynamicLink": case "FirebaseDynamicLinks#getInitialLink": @@ -228,6 +229,10 @@ private Task> getDynamicLink( Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } + if(pendingDynamicLink == null){ + return null; + } + return io.flutter.plugins.firebasedynamiclinks.Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); }); } From 7f59009d7a81751e994dda667e698554a559247d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 10:47:33 +0000 Subject: [PATCH 039/125] fix(dynamic_links): always pass defaults --- .../method_channel_firebase_dynamic_links.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 3b7926beb4eb..172a871f0a56 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -84,16 +84,17 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { Future getInitialLink() async { final Map? linkData = await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink'); + 'FirebaseDynamicLinks#getInitialLink', _withChannelDefaults({})); return getPendingDynamicLinkDataFromMap(linkData); } @override Future getDynamicLink(Uri url) async { - final Map? linkData = await channel - .invokeMapMethod('FirebaseDynamicLinks#getDynamicLink', - {'url': url.toString()}); + final Map? linkData = + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getDynamicLink', + _withChannelDefaults({'url': url.toString()})); return getPendingDynamicLinkDataFromMap(linkData); } @@ -107,12 +108,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { onListen: () async { // ignore: cast_nullable_to_non_nullable String name = await channel.invokeMethod( - 'FirebaseDynamicLinks#onLink', { - 'appName': app.name, - }) as String; + 'FirebaseDynamicLinks#onLink', _withChannelDefaults({})) as String; final events = onLinkChannel(name); - snapshotStream = - events.receiveBroadcastStream().listen((event) { + snapshotStream = events.receiveBroadcastStream().listen((event) { controller.add(getPendingDynamicLinkDataFromMap(event)); }, onError: (error, stack) { controller.addError(convertPlatformException(error), stack); From 1135ed70e935e06c951a8c89708f83a890eb1f0a Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 10:48:06 +0000 Subject: [PATCH 040/125] chore(dynamic_links): update example init --- .../example/lib/main.dart | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 48f39c8f8f5e..eb4c742abfb4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -15,16 +15,15 @@ import 'package:url_launcher/url_launcher.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0', - appId: '1:448618578101:ios:4cd06f56e36384acac3efc', - messagingSenderId: '448618578101', - projectId: 'react-native-firebase-testing', - authDomain: 'react-native-firebase-testing.firebaseapp.com', - iosClientId: - '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', - ) - ); + options: const FirebaseOptions( + apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', + appId: '1:448618578101:ios:4cd06f56e36384acac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + )); runApp(MaterialApp( title: 'Dynamic Links Example', routes: { From 2f864fc6260134b81795fd2f4259bc671fc84425 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 10:48:21 +0000 Subject: [PATCH 041/125] format: run formatter --- .../FirebaseDynamicLinksPlugin.java | 17 ++- .../lib/firebase_dynamic_links.dart | 19 +++- .../lib/src/dynamic_link_parameters.dart | 4 +- ...d_channel_firebase_dynamic_links_test.dart | 105 +++++++++--------- .../test/mock.dart | 13 +-- 5 files changed, 88 insertions(+), 70 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index d744b1a3e95a..795be176f207 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -46,7 +46,8 @@ public class FirebaseDynamicLinksPlugin private MethodChannel channel; @Nullable private BinaryMessenger messenger; - private final Map streamHandlers = new HashMap<>(); + private final Map + streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -107,7 +108,8 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments @Override public boolean onNewIntent(Intent intent) { // Passes intent to every listener for different app instances the user may create - for (io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler instance : streamHandlers.values()) { + for (io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler instance : + streamHandlers.values()) { instance.sinkEvent(intent); } return false; @@ -130,7 +132,8 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re case "FirebaseDynamicLinks#shortenUrl": DynamicLink.Builder urlBuilderShorten = setupParameters(call.arguments()); urlBuilderShorten.setLongLink(Uri.parse(call.argument("url"))); - methodCallTask = buildShortLink(urlBuilderShorten, call.argument("dynamicLinkParametersOptions")); + methodCallTask = + buildShortLink(urlBuilderShorten, call.argument("dynamicLinkParametersOptions")); break; case "FirebaseDynamicLinks#getDynamicLink": case "FirebaseDynamicLinks#getInitialLink": @@ -229,11 +232,12 @@ private Task> getDynamicLink( Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } - if(pendingDynamicLink == null){ + if (pendingDynamicLink == null) { return null; } - return io.flutter.plugins.firebasedynamiclinks.Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + return io.flutter.plugins.firebasedynamiclinks.Utils.getMapFromPendingDynamicLinkData( + pendingDynamicLink); }); } @@ -360,7 +364,8 @@ private Task registerOnLinkListener( return Tasks.call( cachedThreadPool, () -> { - final io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler handler = new io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler(dynamicLinks); + final io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler handler = + new io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler(dynamicLinks); final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; final EventChannel channel = new EventChannel(messenger, name); channel.setStreamHandler(handler); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 416f46e0e947..c34ab5e9b3ee 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -10,8 +10,23 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart' - show AndroidParameters, DynamicLink, DynamicLinkParameters, DynamicLinkParametersOptions, FirebaseDynamicLinksPlatform, FirebasePluginPlatform, GoogleAnalyticsParameters, IosParameters, ItunesConnectAnalyticsParameters, NavigationInfoParameters, PendingDynamicLinkData, PendingDynamicLinkDataAndroid, PendingDynamicLinkDataIOS, ShortDynamicLink, ShortDynamicLinkPathLength, SocialMetaTagParameters; + show + AndroidParameters, + DynamicLink, + DynamicLinkParameters, + DynamicLinkParametersOptions, + FirebaseDynamicLinksPlatform, + FirebasePluginPlatform, + GoogleAnalyticsParameters, + IosParameters, + ItunesConnectAnalyticsParameters, + NavigationInfoParameters, + PendingDynamicLinkData, + PendingDynamicLinkDataAndroid, + PendingDynamicLinkDataIOS, + ShortDynamicLink, + ShortDynamicLinkPathLength, + SocialMetaTagParameters; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; - part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index 30c657c2c454..d4cad4f2b25e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -61,7 +61,7 @@ class DynamicLinkParameters { final SocialMetaTagParameters? socialMetaTagParameters; /// Returns the current instance as a [Map]. - Map asMap(){ + Map asMap() { return { 'uriPrefix': uriPrefix, 'link': link.toString(), @@ -74,7 +74,7 @@ class DynamicLinkParameters { if (iosParameters != null) 'iosParameters': iosParameters?.asMap(), if (itunesConnectAnalyticsParameters != null) 'itunesConnectAnalyticsParameters': - itunesConnectAnalyticsParameters?.asMap(), + itunesConnectAnalyticsParameters?.asMap(), if (navigationInfoParameters != null) 'navigationInfoParameters': navigationInfoParameters?.asMap(), if (socialMetaTagParameters != null) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index fe1a9dea7689..b53229446dcc 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -309,66 +309,65 @@ void main() { // emits(isA() // .having((r) => r.link, 'link', 'link')), // ); - }); }); - group('buildShortLink()', () { - test('buildShortLink', () async { - DynamicLinkParameters options = buildDynamicLinkParameters(); + group('buildShortLink()', () { + test('buildShortLink', () async { + DynamicLinkParameters options = buildDynamicLinkParameters(); - await dynamicLinks.buildShortLink(options); + await dynamicLinks.buildShortLink(options); - expect(logger, [ - isMethodCall( - 'FirebaseDynamicLinks#buildShortLink', - arguments: { - 'appName': '[DEFAULT]', - 'uriPrefix': 'https://', - 'link': 'link', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, - 'androidParameters': { - 'fallbackUrl': 'fallbackUrl', - 'minimumVersion': 1, - 'packageName': 'test-package' - }, - 'googleAnalyticsParameters': { - 'campaign': 'campaign', - 'content': 'content', - 'medium': 'medium', - 'source': 'source', - 'term': 'term' - }, - 'iosParameters': { - 'appStoreId': 'appStoreId', - 'bundleId': 'bundleId', - 'customScheme': 'customScheme', - 'fallbackUrl': 'fallbackUrl', - 'ipadBundleId': 'ipadBundleId', - 'ipadFallbackUrl': 'ipadFallbackUrl', - 'minimumVersion': 'minimumVersion', - }, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'affiliateToken', - 'campaignToken': 'campaignToken', - 'providerToken': 'providerToken', - }, - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': { - 'description': 'description', - 'imageUrl': 'imageUrl', - 'title': 'title', - }, + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#buildShortLink', + arguments: { + 'appName': '[DEFAULT]', + 'uriPrefix': 'https://', + 'link': 'link', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, }, - ), - ]); - }); + 'androidParameters': { + 'fallbackUrl': 'fallbackUrl', + 'minimumVersion': 1, + 'packageName': 'test-package' + }, + 'googleAnalyticsParameters': { + 'campaign': 'campaign', + 'content': 'content', + 'medium': 'medium', + 'source': 'source', + 'term': 'term' + }, + 'iosParameters': { + 'appStoreId': 'appStoreId', + 'bundleId': 'bundleId', + 'customScheme': 'customScheme', + 'fallbackUrl': 'fallbackUrl', + 'ipadBundleId': 'ipadBundleId', + 'ipadFallbackUrl': 'ipadFallbackUrl', + 'minimumVersion': 'minimumVersion', + }, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'affiliateToken', + 'campaignToken': 'campaignToken', + 'providerToken': 'providerToken', + }, + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': { + 'description': 'description', + 'imageUrl': 'imageUrl', + 'title': 'title', + }, + }, + ), + ]); }); }); + }); } class TestMethodChannelFirebaseDynamicLinks diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart index 6c9acd61a648..8ec82cac22e4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart @@ -55,11 +55,10 @@ void handleMethodCall(MethodCallCallback methodCallCallback) => return await methodCallCallback(call); }); - void handleEventChannel( - final String name, [ - List? log, - ]) { + final String name, [ + List? log, +]) { MethodChannel(name).setMockMethodCallHandler((MethodCall methodCall) async { log?.add(methodCall); switch (methodCall.method) { @@ -72,13 +71,13 @@ void handleEventChannel( }); } - Future injectEventChannelResponse( String channelName, Map event) async { await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage( channelName, - MethodChannelFirebaseDynamicLinks.channel.codec.encodeSuccessEnvelope(event), - (_) {}, + MethodChannelFirebaseDynamicLinks.channel.codec + .encodeSuccessEnvelope(event), + (_) {}, ); } From 704edd427daa29d86636cac61fc2eaae8a7d776d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 11:44:07 +0000 Subject: [PATCH 042/125] test(dynamic_links): update --- .../firebase_dynamic_links_e2e.dart | 76 +++-------------- .../example/test_driver/instance_e2e.dart | 81 +++++++++++++++++++ 2 files changed, 94 insertions(+), 63 deletions(-) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart index e82e943ec6f2..5df860b85c01 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart @@ -1,78 +1,28 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'package:drive/drive.dart' as drive; import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'instance_e2e.dart'; + void testsMain() { setUpAll(() async { - await Firebase.initializeApp(); + await Firebase.initializeApp( + options: const FirebaseOptions( + apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', + appId: '1:448618578101:ios:4cd06f56e36384acac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + )); }); - group('DynamicLinks', () { - test('buildUrl', () async { - FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; - const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; - const String iosBundleId = - 'com.google.FirebaseCppDynamicLinksTestApp.dev'; - const String urlHost = 'cx4k7.app.goo.gl'; - const String link = 'https://dynamic.link.example/helloworld'; - - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://$urlHost', - link: Uri.parse(link), - androidParameters: const AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), - iosParameters: const IosParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await dynamicLinks.buildUrl(parameters); - - // androidParameters.minimumVersion - expect( - uri.queryParameters['amv'], - '1', - ); - // iosParameters.minimumVersion - expect( - uri.queryParameters['imv'], - '2', - ); - // androidParameters.packageName - expect( - uri.queryParameters['apn'], - androidPackageName, - ); - // iosParameters.bundleId - expect( - uri.queryParameters['ibi'], - iosBundleId, - ); - // link - expect( - uri.queryParameters['link'], - Uri.encodeFull(link), - ); - // uriPrefix - expect( - uri.host, - urlHost, - ); - }); - }); + runInstanceTests(); } void main() => drive.main(testsMain); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart new file mode 100644 index 000000000000..da55a06b0f5a --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -0,0 +1,81 @@ +// Copyright 2021, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void runInstanceTests() { + group('$FirebaseDynamicLinks.instance', () { + late FirebaseDynamicLinks dynamicLinks; + + setUpAll(() async { + dynamicLinks = FirebaseDynamicLinks.instance; + }); + + test('instance', () { + expect(dynamicLinks, isA()); + expect(dynamicLinks.app, isA()); + }); + + test('buildUrl', () async { + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; + const String androidPackageName = + 'io.flutter.plugins.firebasedynamiclinksexample'; + const String iosBundleId = + 'com.google.FirebaseCppDynamicLinksTestApp.dev'; + const String urlHost = 'cx4k7.app.goo.gl'; + const String link = 'https://dynamic.link.example/helloworld'; + + final DynamicLinkParameters parameters = DynamicLinkParameters( + uriPrefix: 'https://$urlHost', + link: Uri.parse(link), + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: const IosParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await dynamicLinks.buildUrl(parameters); + + // androidParameters.minimumVersion + expect( + uri.queryParameters['amv'], + '1', + ); + // iosParameters.minimumVersion + expect( + uri.queryParameters['imv'], + '2', + ); + // androidParameters.packageName + expect( + uri.queryParameters['apn'], + androidPackageName, + ); + // iosParameters.bundleId + expect( + uri.queryParameters['ibi'], + iosBundleId, + ); + // link + expect( + uri.queryParameters['link'], + Uri.encodeFull(link), + ); + // uriPrefix + expect( + uri.host, + urlHost, + ); + }); + }); +} From bb33ff36dae950589e36dc7bd599969261e97925 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 12:21:33 +0000 Subject: [PATCH 043/125] chore: update ios for testing --- .../ios/Runner.xcodeproj/project.pbxproj | 5 +-- .../ios/Runner/GoogleService-Info.plist | 42 ------------------- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 4 +- 3 files changed, 3 insertions(+), 48 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj index 1a3a41915cf3..51f949c78cda 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */; }; 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; @@ -43,7 +42,6 @@ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 8FE60D1A20C0962300E3A541 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; 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 = ""; }; @@ -102,7 +100,6 @@ children = ( 8FE60D1A20C0962300E3A541 /* Runner.entitlements */, 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 8FE60D1820C0959F00E3A541 /* GoogleService-Info.plist */, 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, @@ -189,6 +186,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -208,7 +206,6 @@ buildActionMask = 2147483647; files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 8FE60D1920C0959F00E3A541 /* GoogleService-Info.plist in Resources */, 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index ac0d4c98b0d0..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,42 +0,0 @@ - - - - - AD_UNIT_ID_FOR_BANNER_TEST - ca-app-pub-3940256099942544/2934735716 - AD_UNIT_ID_FOR_INTERSTITIAL_TEST - ca-app-pub-3940256099942544/4411468910 - CLIENT_ID - 479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9.apps.googleusercontent.com - REVERSED_CLIENT_ID - com.googleusercontent.apps.479882132969-pn2ancg65o0e7r5ikte1qiciuvdghqf9 - ANDROID_CLIENT_ID - 479882132969-32qusitiag53931ck80h121ajhlc5a7e.apps.googleusercontent.com - API_KEY - AIzaSyBECOwLTAN6PU4Aet1b2QLGIb3kRK8Xjew - GCM_SENDER_ID - 479882132969 - PLIST_VERSION - 1 - BUNDLE_ID - com.google.FirebaseCppDynamicLinksTestApp.dev - PROJECT_ID - my-flutter-proj - STORAGE_BUCKET - my-flutter-proj.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:479882132969:ios:36e157824ba4dd3d - DATABASE_URL - https://my-flutter-proj.firebaseio.com - - \ No newline at end of file diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 99ef32ac1af1..0a8efefa42c3 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -9,7 +9,7 @@ #import "Public/FLTFirebaseDynamicLinksPlugin.h" NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; -NSString *const kAppName = @"appName"; +NSString *const kDLAppName = @"appName"; NSString *const kUrl = @"url"; NSString *const kCode = @"code"; NSString *const kMessage = @"message"; @@ -143,7 +143,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result FLTFirebaseMethodCallResult *methodCallResult = [FLTFirebaseMethodCallResult createWithSuccess:result andErrorBlock:errorBlock]; - NSString *appName = call.arguments[kAppName]; + NSString *appName = call.arguments[kDLAppName]; if (appName != nil && ![appName isEqualToString:kDefaultAppName]) { // TODO - document iOS default app only NSLog(@"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app"); From 85fa49f84d24fdec53f18b603d50d51cc08af363 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:32:20 +0000 Subject: [PATCH 044/125] refactor(dynamic_links): convert platform errors --- ...method_channel_firebase_dynamic_links.dart | 79 ++++++++++++------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 172a871f0a56..ae83ac6aaae8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -82,20 +82,28 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future getInitialLink() async { - final Map? linkData = - await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink', _withChannelDefaults({})); - - return getPendingDynamicLinkDataFromMap(linkData); + try { + final Map? linkData = + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getInitialLink', _withChannelDefaults({})); + + return getPendingDynamicLinkDataFromMap(linkData); + } on PlatformException catch (e, s) { + throw platformExceptionToFirebaseException(e, s); + } } @override Future getDynamicLink(Uri url) async { - final Map? linkData = - await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getDynamicLink', - _withChannelDefaults({'url': url.toString()})); - return getPendingDynamicLinkDataFromMap(linkData); + try { + final Map? linkData = + await channel.invokeMapMethod( + 'FirebaseDynamicLinks#getDynamicLink', + _withChannelDefaults({'url': url.toString()})); + return getPendingDynamicLinkDataFromMap(linkData); + } on PlatformException catch (e, s) { + throw platformExceptionToFirebaseException(e, s); + } } @override @@ -127,34 +135,47 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future shortenUrl(Uri url, [DynamicLinkParametersOptions? options]) async { - final Map? reply = await MethodChannelFirebaseDynamicLinks - .channel - .invokeMapMethod( - 'FirebaseDynamicLinks#shortenUrl', - _withChannelDefaults({ - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.asMap(), - })); - return _parseShortLink(reply!); + try { + final Map? reply = + await MethodChannelFirebaseDynamicLinks.channel + .invokeMapMethod( + 'FirebaseDynamicLinks#shortenUrl', + _withChannelDefaults({ + 'url': url.toString(), + 'dynamicLinkParametersOptions': options?.asMap(), + })); + return _parseShortLink(reply!); + } on PlatformException catch (e, s) { + throw platformExceptionToFirebaseException(e, s); + } } @override Future buildUrl(DynamicLinkParameters parameters) async { - final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('FirebaseDynamicLinks#buildUrl', - _withChannelDefaults(parameters.asMap())); - return Uri.parse(url!); + try { + final String? url = await MethodChannelFirebaseDynamicLinks.channel + .invokeMethod('FirebaseDynamicLinks#buildUrl', + _withChannelDefaults(parameters.asMap())); + return Uri.parse(url!); + } on PlatformException catch (e, s) { + throw platformExceptionToFirebaseException(e, s); + } } @override Future buildShortLink( DynamicLinkParameters parameters) async { - final Map? response = - await MethodChannelFirebaseDynamicLinks.channel - .invokeMapMethod( - 'FirebaseDynamicLinks#buildShortLink', - _withChannelDefaults(parameters.asMap())); - return _parseShortLink(response!); + try { + final Map? response = + await MethodChannelFirebaseDynamicLinks + .channel + .invokeMapMethod( + 'FirebaseDynamicLinks#buildShortLink', + _withChannelDefaults(parameters.asMap())); + return _parseShortLink(response!); + } on PlatformException catch (e, s) { + throw platformExceptionToFirebaseException(e, s); + } } ShortDynamicLink _parseShortLink(Map response) { From f638ae0e84fa9883f91dd195a38db7d7946c83f4 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:33:21 +0000 Subject: [PATCH 045/125] chore(dynamic_links): pass stack trace if available --- .../lib/src/method_channel/utils/exception.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart index 1099bc9283e5..c1b728230593 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -23,7 +23,8 @@ Exception convertPlatformException(Object exception) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException) { + PlatformException platformException, + [StackTrace? stackTrace]) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -37,5 +38,8 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_dynamic_links', code: code, message: message); + plugin: 'firebase_dynamic_links', + code: code, + message: message, + stackTrace: stackTrace); } From d888c884aacd7f7c32f9adcda16ec0ec72816a85 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:33:40 +0000 Subject: [PATCH 046/125] tests(dynamic_links): update e2e tests --- .../example/test_driver/instance_e2e.dart | 257 +++++++++++++----- 1 file changed, 196 insertions(+), 61 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index da55a06b0f5a..e9143f7935c2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -2,80 +2,215 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'dart:async'; + import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; import 'package:flutter_test/flutter_test.dart'; void runInstanceTests() { - group('$FirebaseDynamicLinks.instance', () { + group('$FirebaseDynamicLinks', () { late FirebaseDynamicLinks dynamicLinks; setUpAll(() async { dynamicLinks = FirebaseDynamicLinks.instance; }); - test('instance', () { - expect(dynamicLinks, isA()); - expect(dynamicLinks.app, isA()); + group('instance', () { + test('instance', () { + expect(dynamicLinks, isA()); + expect(dynamicLinks.app, isA()); + }); }); - test('buildUrl', () async { - FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; - const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; - const String iosBundleId = - 'com.google.FirebaseCppDynamicLinksTestApp.dev'; - const String urlHost = 'cx4k7.app.goo.gl'; - const String link = 'https://dynamic.link.example/helloworld'; - - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://$urlHost', - link: Uri.parse(link), - androidParameters: const AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), - iosParameters: const IosParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await dynamicLinks.buildUrl(parameters); - - // androidParameters.minimumVersion - expect( - uri.queryParameters['amv'], - '1', - ); - // iosParameters.minimumVersion - expect( - uri.queryParameters['imv'], - '2', - ); - // androidParameters.packageName - expect( - uri.queryParameters['apn'], - androidPackageName, - ); - // iosParameters.bundleId - expect( - uri.queryParameters['ibi'], - iosBundleId, - ); - // link - expect( - uri.queryParameters['link'], - Uri.encodeFull(link), - ); - // uriPrefix - expect( - uri.host, - urlHost, - ); + group('buildUrl', () { + test('build normal dynamic links', () async { + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; + const String androidPackageName = + 'io.flutter.plugins.firebasedynamiclinksexample'; + const String iosBundleId = + 'com.google.FirebaseCppDynamicLinksTestApp.dev'; + const String urlHost = 'reactnativefirebase.page.link'; + const String link = 'https://dynamic.link.example/helloworld'; + + final DynamicLinkParameters parameters = DynamicLinkParameters( + uriPrefix: 'https://$urlHost', + link: Uri.parse(link), + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: const IosParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await dynamicLinks.buildUrl(parameters); + + // androidParameters.minimumVersion + expect( + uri.queryParameters['amv'], + '1', + ); + // iosParameters.minimumVersion + expect( + uri.queryParameters['imv'], + '2', + ); + // androidParameters.packageName + expect( + uri.queryParameters['apn'], + androidPackageName, + ); + // iosParameters.bundleId + expect( + uri.queryParameters['ibi'], + iosBundleId, + ); + // link + expect( + uri.queryParameters['link'], + Uri.encodeFull(link), + ); + // uriPrefix + expect( + uri.host, + urlHost, + ); + }); + }); + + group('buildShortLink', () { + test('build a short dynamic link', () async { + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; + const String androidPackageName = + 'io.flutter.plugins.firebasedynamiclinksexample'; + const String iosBundleId = + 'io.flutter.plugins.firebase.dynamiclinksexample'; + const String urlHost = 'reactnativefirebase.page.link'; + const String link = 'https://dynamic.link.example/helloworld'; + + final DynamicLinkParameters parameters = DynamicLinkParameters( + uriPrefix: 'https://$urlHost', + link: Uri.parse(link), + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: const IosParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final ShortDynamicLink uri = + await dynamicLinks.buildShortLink(parameters); + + // androidParameters.minimumVersion + expect( + uri.shortUrl.host, + urlHost, + ); + + expect( + uri.shortUrl.path.length, + isNotNull, + ); + + expect( + uri.shortUrl.path.length, + lessThanOrEqualTo(16), + ); + }); + }); + + group('shortenUrl', () { + test('build url and shorten', () async { + FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; + const String androidPackageName = + 'io.flutter.plugins.firebasedynamiclinksexample'; + const String iosBundleId = + 'io.flutter.plugins.firebase.dynamiclinksexample'; + const String urlHost = 'reactnativefirebase.page.link'; + const String link = 'https://dynamic.link.example/helloworld'; + + final DynamicLinkParameters parameters = DynamicLinkParameters( + uriPrefix: 'https://$urlHost', + link: Uri.parse(link), + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + dynamicLinkParametersOptions: const DynamicLinkParametersOptions( + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, + ), + iosParameters: const IosParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await dynamicLinks.buildUrl(parameters); + final ShortDynamicLink shortLink = await dynamicLinks.shortenUrl(uri); + + expect(shortLink, isA()); + expect(shortLink.shortUrl, isA()); + }); + }); + + group('getInitialLink', () { + test('initial link', () async { + PendingDynamicLinkData? pendingLink = + await FirebaseDynamicLinks.instance.getInitialLink(); + + expect(pendingLink, isNull); + }); + }); + }); + + group('getDynamicLink', () { + test('dynamic link using uri', () async { + Uri uri = Uri.parse(''); + PendingDynamicLinkData? pendingLink = await FirebaseDynamicLinks.instance.getDynamicLink(uri); + + expect(pendingLink, isNull); + }); + }); + + group('onLink', () { + test('grab first stream event', () async { + PendingDynamicLinkData? pendingLink = + await FirebaseDynamicLinks.instance.onLink().first; + + expect(pendingLink, isNull); + }); + + test('test multiple times', () async { + StreamSubscription _onListenSubscription; + StreamSubscription _onListenSubscriptionSecond; + + _onListenSubscription = + FirebaseDynamicLinks.instance.onLink().listen((event) {}); + _onListenSubscriptionSecond = + FirebaseDynamicLinks.instance.onLink().listen((event) {}); + + await _onListenSubscription.cancel(); + await _onListenSubscriptionSecond.cancel(); + + _onListenSubscription = + FirebaseDynamicLinks.instance.onLink().listen((event) {}); + _onListenSubscriptionSecond = + FirebaseDynamicLinks.instance.onLink().listen((event) {}); + + await _onListenSubscription.cancel(); + await _onListenSubscriptionSecond.cancel(); }); }); } From 8f1fa388a1f403d7f6880d6a78776d28d1053eaa Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:34:12 +0000 Subject: [PATCH 047/125] format --- .../example/test_driver/instance_e2e.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index e9143f7935c2..4fb1db5efae9 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -178,7 +178,8 @@ void runInstanceTests() { group('getDynamicLink', () { test('dynamic link using uri', () async { Uri uri = Uri.parse(''); - PendingDynamicLinkData? pendingLink = await FirebaseDynamicLinks.instance.getDynamicLink(uri); + PendingDynamicLinkData? pendingLink = + await FirebaseDynamicLinks.instance.getDynamicLink(uri); expect(pendingLink, isNull); }); From 5e32ec0f076a9e8ae719962c48330a84caa07696 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:38:02 +0000 Subject: [PATCH 048/125] revert package path --- .../src/platform_interface/platform_interface_firestore.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart index 85328e60941f..9c36cacfdda3 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/platform_interface/platform_interface_firestore.dart @@ -6,7 +6,7 @@ import 'dart:async'; import 'dart:typed_data'; -import '../../cloud_firestore_platform_interface.dart'; +import 'package:cloud_firestore_platform_interface/cloud_firestore_platform_interface.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:meta/meta.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; From 8a8ac8b348e8b41031283565ce2ecefc1d276a64 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:40:11 +0000 Subject: [PATCH 049/125] chore(functions):revert MinimumOSVersion change --- .../cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist b/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist index 8d4492f977ad..9367d483e44e 100644 --- a/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/cloud_functions/cloud_functions/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 8.0 From f6775fddd2b8128fdfc19e76b60aed7c89d1bba1 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 14:49:55 +0000 Subject: [PATCH 050/125] chore(functions):reinstate ios config --- .../example/ios/Runner.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj b/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj index 857e8a92930e..7e97949b994c 100644 --- a/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/cloud_functions/cloud_functions/example/ios/Runner.xcodeproj/project.pbxproj @@ -311,6 +311,7 @@ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -364,6 +365,7 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; From 9b592de4c519a1298a3ddcd0adce2165773a52e6 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 15:52:49 +0000 Subject: [PATCH 051/125] test(dynamiclinks):test platform exception --- ...d_channel_firebase_dynamic_links_test.dart | 182 ++++++++++++------ .../test/mock.dart | 24 +-- 2 files changed, 133 insertions(+), 73 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index b53229446dcc..201d1f66beb4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -73,7 +73,9 @@ DynamicLinkParameters buildDynamicLinkParameters() { void main() { setupFirebaseDynamicLinksMocks(); - late TestMethodChannelFirebaseDynamicLinks? mockDynamicLinks; + + bool mockPlatformExceptionThrown = false; + late FirebaseDynamicLinksPlatform dynamicLinks; final List logger = []; int getInitialLinkCall = 1; @@ -84,6 +86,11 @@ void main() { handleMethodCall((call) async { logger.add(call); + + if (mockPlatformExceptionThrown) { + throw PlatformException(code: 'UNKNOWN'); + } + final Map returnUrl = { 'url': 'google.com', 'warnings': ['This is only a test link'], @@ -124,13 +131,16 @@ void main() { }); dynamicLinks = MethodChannelFirebaseDynamicLinks(app: app); - mockDynamicLinks = TestMethodChannelFirebaseDynamicLinks(app); }); setUp(() async { logger.clear(); }); + tearDown(() async { + mockPlatformExceptionThrown = false; + }); + group('getInitialLink()', () { test('link can be parsed', () async { final PendingDynamicLinkData? data = @@ -146,7 +156,9 @@ void main() { expect(logger, [ isMethodCall( 'FirebaseDynamicLinks#getInitialLink', - arguments: null, + arguments: { + 'appName': '[DEFAULT]', + }, ) ]); }); @@ -163,7 +175,9 @@ void main() { expect(logger, [ isMethodCall( 'FirebaseDynamicLinks#getInitialLink', - arguments: null, + arguments: { + 'appName': '[DEFAULT]', + }, ) ]); }); @@ -179,10 +193,20 @@ void main() { expect(logger, [ isMethodCall( 'FirebaseDynamicLinks#getInitialLink', - arguments: null, + arguments: { + 'appName': '[DEFAULT]', + }, ) ]); }); + + test( + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + + await testExceptionHandling(dynamicLinks.getInitialLink); + }); }); group('getDynamicLink()', () { @@ -197,9 +221,19 @@ void main() { isMethodCall('FirebaseDynamicLinks#getDynamicLink', arguments: { 'url': argument.toString(), + 'appName': '[DEFAULT]', }) ]); }); + + test( + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + final Uri argument = Uri.parse('short-link'); + await testExceptionHandling( + () => dynamicLinks.getDynamicLink(argument)); + }); }); group('shortenUrl()', () { test('shortenUrl', () async { @@ -225,61 +259,84 @@ void main() { ), ]); }); - group('buildUrl()', () { - test('buildUrl', () async { - DynamicLinkParameters options = buildDynamicLinkParameters(); - await dynamicLinks.buildUrl(options); + test( + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + final Uri url = Uri.parse('google.com'); + const DynamicLinkParametersOptions options = + DynamicLinkParametersOptions( + shortDynamicLinkPathLength: + ShortDynamicLinkPathLength.unguessable); + + await testExceptionHandling( + () => dynamicLinks.shortenUrl(url, options)); + }); + }); + group('buildUrl()', () { + test('buildUrl', () async { + DynamicLinkParameters options = buildDynamicLinkParameters(); + + await dynamicLinks.buildUrl(options); - expect(logger, [ - isMethodCall( - 'FirebaseDynamicLinks#buildUrl', - arguments: { - 'appName': '[DEFAULT]', - 'uriPrefix': 'https://', - 'link': 'link', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, - 'androidParameters': { - 'fallbackUrl': 'fallbackUrl', - 'minimumVersion': 1, - 'packageName': 'test-package' - }, - 'googleAnalyticsParameters': { - 'campaign': 'campaign', - 'content': 'content', - 'medium': 'medium', - 'source': 'source', - 'term': 'term' - }, - 'iosParameters': { - 'appStoreId': 'appStoreId', - 'bundleId': 'bundleId', - 'customScheme': 'customScheme', - 'fallbackUrl': 'fallbackUrl', - 'ipadBundleId': 'ipadBundleId', - 'ipadFallbackUrl': 'ipadFallbackUrl', - 'minimumVersion': 'minimumVersion', - }, - 'itunesConnectAnalyticsParameters': { - 'affiliateToken': 'affiliateToken', - 'campaignToken': 'campaignToken', - 'providerToken': 'providerToken', - }, - 'navigationInfoParameters': { - 'forcedRedirectEnabled': true, - }, - 'socialMetaTagParameters': { - 'description': 'description', - 'imageUrl': 'imageUrl', - 'title': 'title', - }, + expect(logger, [ + isMethodCall( + 'FirebaseDynamicLinks#buildUrl', + arguments: { + 'appName': '[DEFAULT]', + 'uriPrefix': 'https://', + 'link': 'link', + 'dynamicLinkParametersOptions': { + 'shortDynamicLinkPathLength': + ShortDynamicLinkPathLength.unguessable.index, }, - ), - ]); - }); + 'androidParameters': { + 'fallbackUrl': 'fallbackUrl', + 'minimumVersion': 1, + 'packageName': 'test-package' + }, + 'googleAnalyticsParameters': { + 'campaign': 'campaign', + 'content': 'content', + 'medium': 'medium', + 'source': 'source', + 'term': 'term' + }, + 'iosParameters': { + 'appStoreId': 'appStoreId', + 'bundleId': 'bundleId', + 'customScheme': 'customScheme', + 'fallbackUrl': 'fallbackUrl', + 'ipadBundleId': 'ipadBundleId', + 'ipadFallbackUrl': 'ipadFallbackUrl', + 'minimumVersion': 'minimumVersion', + }, + 'itunesConnectAnalyticsParameters': { + 'affiliateToken': 'affiliateToken', + 'campaignToken': 'campaignToken', + 'providerToken': 'providerToken', + }, + 'navigationInfoParameters': { + 'forcedRedirectEnabled': true, + }, + 'socialMetaTagParameters': { + 'description': 'description', + 'imageUrl': 'imageUrl', + 'title': 'title', + }, + }, + ), + ]); + }); + + test( + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + DynamicLinkParameters options = buildDynamicLinkParameters(); + + await testExceptionHandling(() => dynamicLinks.buildUrl(options)); }); }); @@ -303,7 +360,7 @@ void main() { 'link': 'link', 'ios': {'minimumVersion': 'minimumVersion'} }); - // TODO find out why event isn't emitted + // TODO find out why event isn't emitted. also catch error. // await expectLater( // stream, // emits(isA() @@ -366,6 +423,15 @@ void main() { ), ]); }); + + test( + 'catch a [PlatformException] error and throws a [FirebaseException] error', + () async { + mockPlatformExceptionThrown = true; + DynamicLinkParameters options = buildDynamicLinkParameters(); + + await testExceptionHandling(() => dynamicLinks.buildShortLink(options)); + }); }); }); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart index 8ec82cac22e4..094ea699c831 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +11,7 @@ typedef MethodCallCallback = dynamic Function(MethodCall methodCall); typedef Callback = void Function(MethodCall call); int mockHandleId = 0; + int get nextMockHandleId => mockHandleId++; void setupFirebaseDynamicLinksMocks([Callback? customHandlers]) { @@ -81,17 +81,11 @@ Future injectEventChannelResponse( ); } -// TODO update error handling and test -// Future testExceptionHandling( -// String type, -// void Function() testMethod, -// ) async { -// await expectLater( -// () async => testMethod(), -// anyOf([ -// completes, -// if (type == 'PLATFORM' || type == 'EXCEPTION') -// throwsA(isA()) -// ]), -// ); -// } +Future testExceptionHandling( + void Function() testMethod, +) async { + await expectLater( + () async => testMethod(), + anyOf([completes, throwsA(isA())]), + ); +} From e134f41e45b14209cc5a6ccc1d3b91abc82f6e4c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 15:55:32 +0000 Subject: [PATCH 052/125] chore(dynamiclinks):revert remote config change. wrong PR --- .../example/ios/Flutter/AppFrameworkInfo.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist b/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist index 3a9c234f96d4..6c2de8086bcd 100644 --- a/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/firebase_remote_config/firebase_remote_config/example/ios/Flutter/AppFrameworkInfo.plist @@ -25,6 +25,6 @@ arm64 MinimumOSVersion - 9.0 + 8.0 From 229a90a776b6611f833fd91e8e36a32be43368a7 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 15:55:48 +0000 Subject: [PATCH 053/125] chore(dynamiclinks): rm code comment --- .../firebase_dynamic_links/lib/firebase_dynamic_links.dart | 3 +-- .../lib/src/firebase_dynamic_links.dart | 3 +-- .../firebase_dynamic_links/test/mock.dart | 1 - .../lib/firebase_dynamic_links_platform_interface.dart | 1 - .../lib/src/dynamic_link_parameters.dart | 1 - .../method_channel_firebase_dynamic_links.dart | 1 - .../lib/src/method_channel/utils/exception.dart | 1 - .../platform_interface_firebase_dynamic_links.dart | 6 +----- .../test/android_parameters_test.dart | 1 - .../test/dynamic_link_parameter_options_test.dart | 1 - .../test/dynamic_link_test.dart | 1 - .../test/ios_parameters_test.dart | 1 - .../test/itunes_connect_analytics_parameters_test.dart | 1 - .../test/navigation_info_parameters_test.dart | 1 - .../test/pending_dynamic_link_data_test.dart | 1 - .../platform_interface_firebase_dynamic_links_test.dart | 1 - .../test/short_dynamic_link_test.dart | 1 - .../test/social_meta_tag_parameters_test.dart | 1 - 18 files changed, 3 insertions(+), 24 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index c34ab5e9b3ee..314310266537 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -1,5 +1,4 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 3f06ccbd599c..0220de241c34 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -1,5 +1,4 @@ -// ignore_for_file: require_trailing_commas -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart index 31e65af535df..7b9b0b70feab 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/mock.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart index bf79c7f7dd40..87e9909bb2ff 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index d4cad4f2b25e..add65f47d1be 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index ae83ac6aaae8..8e359316e33c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart index c1b728230593..4486047cffc0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 35e90a603805..1e4e8ee41128 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. @@ -8,13 +7,10 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; import 'package:meta/meta.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; -import '../../firebase_dynamic_links_platform_interface.dart'; import '../method_channel/method_channel_firebase_dynamic_links.dart'; -// import '../persistence_settings.dart'; -// import '../method_channel/method_channel_firestore.dart'; - /// Defines an interface to work with Dynamic Links across platforms abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { /// The [FirebaseApp] this instance was initialized with. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart index be10ba8f72da..231c8a1b6bad 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart index 04d21d2df994..d4690e23ecc2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart index e0e8b3a82ca6..f7ec26abbe61 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart index 17c39b350c73..8d160403bbee 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart index ae82ea2c8637..6733e4487b27 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart index 0a0a030501da..fb6bd34ae60c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart index c0a1911e9ab1..03f1a520bba5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart index fa9508e855f2..8e6c217d26dd 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart index caabee58aa62..a50bb9408f03 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart index ece2ec3b9907..a00f14ebf0d4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. From ca0cda9dc3fa93ebdebac8b66bf5054befbe141c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 17:07:52 +0000 Subject: [PATCH 054/125] chore(dynamic-links): throw if different app on iOS platform --- .../lib/firebase_dynamic_links.dart | 2 ++ .../lib/src/firebase_dynamic_links.dart | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 314310266537..5bf8d16780f5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -27,5 +27,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links ShortDynamicLinkPathLength, SocialMetaTagParameters; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; +import 'dart:io' show Platform; +import 'package:flutter/services.dart'; part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 0220de241c34..b860cc69c31d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -21,16 +21,18 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } /// Returns an instance using a specified [FirebaseApp]. + /// Note; multi-app support is only supported on android. static FirebaseDynamicLinks instanceFor({required FirebaseApp app}) { - if (_cachedInstances.containsKey(app.name)) { - return _cachedInstances[app.name]!; + if (Platform.isAndroid || app.name == defaultFirebaseAppName) { + return _cachedInstances.putIfAbsent(app.name, () { + return FirebaseDynamicLinks._(app: app); + }); } - //TODO notify user or even throw error that default only for web and iOS?? - FirebaseDynamicLinks newInstance = FirebaseDynamicLinks._(app: app); - _cachedInstances[app.name] = newInstance; - - return newInstance; + throw PlatformException( + code: 'default-app', + message: 'Firebase Dynamic Links has multi-app support for android only.', + ); } // Cached and lazily loaded instance of [FirebaseDynamicLinksPlatform] to avoid @@ -65,20 +67,23 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { return _delegate.getDynamicLink(url); } - /// Listen to a stream for the latest dynamic link events + /// Listen to a stream for the latest dynamic link events. Stream onLink() { return _delegate.onLink(); } + /// Returns the shortened Dynamic Link, link flow chart, and warnings from the requested Dynamic Link. Future shortenUrl(Uri url, [DynamicLinkParametersOptions? options]) async { return _delegate.shortenUrl(url, options); } + /// Creates a Dynamic Link from the parameters. Future buildUrl(DynamicLinkParameters parameters) async { return _delegate.buildUrl(parameters); } + /// Creates a shortened Dynamic Link from the parameters. Future buildShortLink( DynamicLinkParameters parameters) async { return _delegate.buildShortLink(parameters); From 509d89e142d694ffe8ae73c3a423bfbebc81a471 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 17:39:08 +0000 Subject: [PATCH 055/125] chore(dynamic-links): analyze issues --- melos.yaml | 2 +- .../src/method_channel/utils/exception.dart | 3 +- .../example/lib/main.dart | 1 - .../example/pubspec.yaml | 8 +- .../firebase_dynamic_links_e2e.dart | 19 +++-- .../lib/firebase_dynamic_links.dart | 2 - .../lib/src/firebase_dynamic_links.dart | 9 +- .../firebase_dynamic_links/pubspec.yaml | 1 + .../test/firebase_dynamic_links_test.dart | 7 +- .../lib/src/android_parameters.dart | 7 +- .../itunes_connect_analytics_parameters.dart | 7 +- ...method_channel_firebase_dynamic_links.dart | 72 +++++++++------- .../src/method_channel/utils/exception.dart | 14 ++-- ...form_interface_firebase_dynamic_links.dart | 9 +- .../lib/src/short_dynamic_link.dart | 7 +- .../test/android_parameters_test.dart | 6 +- .../dynamic_link_parameter_options_test.dart | 20 +++-- .../test/dynamic_link_test.dart | 6 +- .../test/ios_parameters_test.dart | 8 +- ...nes_connect_analytics_parameters_test.dart | 6 +- ...d_channel_firebase_dynamic_links_test.dart | 16 ++-- .../test/mock.dart | 4 +- .../test/navigation_info_parameters_test.dart | 10 ++- .../test/pending_dynamic_link_data_test.dart | 44 ++++++---- ...interface_firebase_dynamic_links_test.dart | 82 ++++++++++++++----- .../test/short_dynamic_link_test.dart | 13 ++- .../test/social_meta_tag_parameters_test.dart | 17 ++-- 27 files changed, 263 insertions(+), 137 deletions(-) diff --git a/melos.yaml b/melos.yaml index 9773e2a71f6d..473e761e779d 100644 --- a/melos.yaml +++ b/melos.yaml @@ -1,7 +1,7 @@ name: FlutterFire packages: - - packages/** + - packages/firebase_dynamic_links/** ignore: # TODO Excluded - pending rewrite to use latest SDKs. diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart index 235d91e8cb8b..423258642cd8 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart @@ -23,7 +23,8 @@ Exception convertPlatformException(Object exception) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException) { + PlatformException platformException, +) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index eb4c742abfb4..3355364019e5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -7,7 +7,6 @@ import 'dart:async'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml index 7e798410968e..7537624239ba 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/pubspec.yaml @@ -15,14 +15,14 @@ dependencies: url_launcher: ^6.0.2 dependency_overrides: - firebase_dynamic_links: - path: ../ - firebase_dynamic_links_platform_interface: - path: ../../firebase_dynamic_links_platform_interface firebase_core: path: ../../../firebase_core/firebase_core firebase_core_platform_interface: path: ../../../firebase_core/firebase_core_platform_interface + firebase_dynamic_links: + path: ../ + firebase_dynamic_links_platform_interface: + path: ../../firebase_dynamic_links_platform_interface dev_dependencies: drive: 1.0.0-1.0.nullsafety.1 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart index 5df860b85c01..2378d5af8168 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/firebase_dynamic_links_e2e.dart @@ -11,15 +11,16 @@ import 'instance_e2e.dart'; void testsMain() { setUpAll(() async { await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', - appId: '1:448618578101:ios:4cd06f56e36384acac3efc', - messagingSenderId: '448618578101', - projectId: 'react-native-firebase-testing', - authDomain: 'react-native-firebase-testing.firebaseapp.com', - iosClientId: - '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', - )); + options: const FirebaseOptions( + apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', + appId: '1:448618578101:ios:4cd06f56e36384acac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + ), + ); }); runInstanceTests(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 5bf8d16780f5..744d97a77f84 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -11,11 +11,9 @@ import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart' show AndroidParameters, - DynamicLink, DynamicLinkParameters, DynamicLinkParametersOptions, FirebaseDynamicLinksPlatform, - FirebasePluginPlatform, GoogleAnalyticsParameters, IosParameters, ItunesConnectAnalyticsParameters, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index b860cc69c31d..1f52cad58a38 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -73,8 +73,10 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } /// Returns the shortened Dynamic Link, link flow chart, and warnings from the requested Dynamic Link. - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { + Future shortenUrl( + Uri url, [ + DynamicLinkParametersOptions? options, + ]) async { return _delegate.shortenUrl(url, options); } @@ -85,7 +87,8 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { /// Creates a shortened Dynamic Link from the parameters. Future buildShortLink( - DynamicLinkParameters parameters) async { + DynamicLinkParameters parameters, + ) async { return _delegate.buildShortLink(parameters); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml index 7c99c2aefd49..4f2de72edfab 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: flutter: sdk: flutter meta: ^1.3.0 + plugin_platform_interface: ^2.0.2 dev_dependencies: flutter_test: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 8dcf7ce9dc36..d7f64099587b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -309,8 +309,11 @@ Future testFutureData() { Uri uri = Uri.parse('mock'); class MockFirebaseDynamicLinks extends Mock - with MockPlatformInterfaceMixin - implements TestFirebaseDynamicLinksPlatform { + with + MockPlatformInterfaceMixin + implements +// ignore: avoid_implementing_value_types + TestFirebaseDynamicLinksPlatform { @override Future getInitialLink() { return super.noSuchMethod( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart index e7ec24423425..25f76f830e68 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -1,7 +1,10 @@ /// The Dynamic Link Android parameters. class AndroidParameters { - const AndroidParameters( - {this.fallbackUrl, this.minimumVersion, required this.packageName}); + const AndroidParameters({ + this.fallbackUrl, + this.minimumVersion, + required this.packageName, + }); /// The link to open when the app isn’t installed. /// diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart index fa656de9587c..9e7ae63a9b99 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -1,7 +1,10 @@ /// The Dynamic Link iTunes Connect parameters. class ItunesConnectAnalyticsParameters { - const ItunesConnectAnalyticsParameters( - {this.affiliateToken, this.campaignToken, this.providerToken}); + const ItunesConnectAnalyticsParameters({ + this.affiliateToken, + this.campaignToken, + this.providerToken, + }); /// The iTunes Connect affiliate token. final String? affiliateToken; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 8e359316e33c..5cb307a9f641 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -50,7 +50,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } PendingDynamicLinkData? getPendingDynamicLinkDataFromMap( - Map? linkData) { + Map? linkData, + ) { if (linkData == null) return null; final link = linkData['link']; @@ -84,7 +85,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { try { final Map? linkData = await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getInitialLink', _withChannelDefaults({})); + 'FirebaseDynamicLinks#getInitialLink', + _withChannelDefaults({}), + ); return getPendingDynamicLinkDataFromMap(linkData); } on PlatformException catch (e, s) { @@ -97,8 +100,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { try { final Map? linkData = await channel.invokeMapMethod( - 'FirebaseDynamicLinks#getDynamicLink', - _withChannelDefaults({'url': url.toString()})); + 'FirebaseDynamicLinks#getDynamicLink', + _withChannelDefaults({'url': url.toString()}), + ); return getPendingDynamicLinkDataFromMap(linkData); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); @@ -115,13 +119,18 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { onListen: () async { // ignore: cast_nullable_to_non_nullable String name = await channel.invokeMethod( - 'FirebaseDynamicLinks#onLink', _withChannelDefaults({})) as String; + 'FirebaseDynamicLinks#onLink', + _withChannelDefaults({}), + ) as String; final events = onLinkChannel(name); - snapshotStream = events.receiveBroadcastStream().listen((event) { - controller.add(getPendingDynamicLinkDataFromMap(event)); - }, onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }); + snapshotStream = events.receiveBroadcastStream().listen( + (event) { + controller.add(getPendingDynamicLinkDataFromMap(event)); + }, + onError: (error, stack) { + controller.addError(convertPlatformException(error), stack); + }, + ); }, onCancel: () { snapshotStream?.cancel(); @@ -132,17 +141,20 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { + Future shortenUrl( + Uri url, [ + DynamicLinkParametersOptions? options, + ]) async { try { final Map? reply = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( - 'FirebaseDynamicLinks#shortenUrl', - _withChannelDefaults({ - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.asMap(), - })); + 'FirebaseDynamicLinks#shortenUrl', + _withChannelDefaults({ + 'url': url.toString(), + 'dynamicLinkParametersOptions': options?.asMap(), + }), + ); return _parseShortLink(reply!); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); @@ -152,9 +164,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future buildUrl(DynamicLinkParameters parameters) async { try { - final String? url = await MethodChannelFirebaseDynamicLinks.channel - .invokeMethod('FirebaseDynamicLinks#buildUrl', - _withChannelDefaults(parameters.asMap())); + final String? url = + await MethodChannelFirebaseDynamicLinks.channel.invokeMethod( + 'FirebaseDynamicLinks#buildUrl', + _withChannelDefaults(parameters.asMap()), + ); return Uri.parse(url!); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); @@ -163,14 +177,15 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future buildShortLink( - DynamicLinkParameters parameters) async { + DynamicLinkParameters parameters, + ) async { try { final Map? response = - await MethodChannelFirebaseDynamicLinks - .channel + await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( - 'FirebaseDynamicLinks#buildShortLink', - _withChannelDefaults(parameters.asMap())); + 'FirebaseDynamicLinks#buildShortLink', + _withChannelDefaults(parameters.asMap()), + ); return _parseShortLink(response!); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); @@ -180,8 +195,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ShortDynamicLink _parseShortLink(Map response) { final List? warnings = response['warnings']; return ShortDynamicLink( - shortUrl: Uri.parse(response['url']), - warnings: warnings?.cast(), - previewLink: response['previewLink']); + shortUrl: Uri.parse(response['url']), + warnings: warnings?.cast(), + previewLink: response['previewLink'], + ); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart index 4486047cffc0..4d9a471f33a6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -22,8 +22,9 @@ Exception convertPlatformException(Object exception) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, - [StackTrace? stackTrace]) { + PlatformException platformException, [ + StackTrace? stackTrace, +]) { Map? details = platformException.details != null ? Map.from(platformException.details) : null; @@ -37,8 +38,9 @@ FirebaseException platformExceptionToFirebaseException( } return FirebaseException( - plugin: 'firebase_dynamic_links', - code: code, - message: message, - stackTrace: stackTrace); + plugin: 'firebase_dynamic_links', + code: code, + message: message, + stackTrace: stackTrace, + ); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 1e4e8ee41128..c9192f72253f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -72,8 +72,10 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { /// /// This method may be used for shortening a custom URL that was not generated /// using [DynamicLinkBuilder]. - Future shortenUrl(Uri url, - [DynamicLinkParametersOptions? options]) async { + Future shortenUrl( + Uri url, [ + DynamicLinkParametersOptions? options, + ]) async { throw UnimplementedError('shortenUrl() is not implemented'); } @@ -84,7 +86,8 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { /// Generate a short Dynamic Link URL. Future buildShortLink( - DynamicLinkParameters parameters) async { + DynamicLinkParameters parameters, + ) async { throw UnimplementedError('buildShortLink() is not implemented'); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index 9881d19c4db0..853b6cee8a79 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -1,7 +1,10 @@ /// Response from creating a short dynamic link with [DynamicLinkBuilder]. class ShortDynamicLink { - const ShortDynamicLink( - {required this.shortUrl, this.warnings, this.previewLink}); + const ShortDynamicLink({ + required this.shortUrl, + this.warnings, + this.previewLink, + }); /// Short url value. final Uri shortUrl; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart index 231c8a1b6bad..fcbcf6a3325e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/android_parameters_test.dart @@ -37,8 +37,10 @@ void main() { }); test('toString', () { - expect(androidParams.toString(), - equals('$AndroidParameters(${androidParams.asMap})')); + expect( + androidParams.toString(), + equals('$AndroidParameters(${androidParams.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart index d4690e23ecc2..bb2a8fdcec48 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart @@ -14,8 +14,10 @@ void main() { group('Constructor', () { test('returns an instance of [DynamicLinkParametersOptions]', () { expect(dynamicLinkOptions, isA()); - expect(dynamicLinkOptions.shortDynamicLinkPathLength, - ShortDynamicLinkPathLength.short); + expect( + dynamicLinkOptions.shortDynamicLinkPathLength, + ShortDynamicLinkPathLength.short, + ); }); group('asMap', () { @@ -23,16 +25,20 @@ void main() { final result = dynamicLinkOptions.asMap(); expect(result, isA>()); - expect(result['shortDynamicLinkPathLength'], - ShortDynamicLinkPathLength.short.index); + expect( + result['shortDynamicLinkPathLength'], + ShortDynamicLinkPathLength.short.index, + ); }); }); test('toString', () { expect( - dynamicLinkOptions.toString(), - equals( - '$DynamicLinkParametersOptions(${dynamicLinkOptions.asMap})')); + dynamicLinkOptions.toString(), + equals( + '$DynamicLinkParametersOptions(${dynamicLinkOptions.asMap})', + ), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart index f7ec26abbe61..8ed57f3d04d5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart @@ -26,8 +26,10 @@ void main() { }); test('toString', () { - expect(dynamicLink.toString(), - equals('$DynamicLink(${dynamicLink.asMap})')); + expect( + dynamicLink.toString(), + equals('$DynamicLink(${dynamicLink.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart index 8d160403bbee..7bbfa01baac8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart @@ -48,7 +48,9 @@ void main() { expect(result['customScheme'], iosParams.customScheme); expect(result['fallbackUrl'], iosParams.fallbackUrl.toString()); expect( - result['ipadFallbackUrl'], iosParams.ipadFallbackUrl.toString()); + result['ipadFallbackUrl'], + iosParams.ipadFallbackUrl.toString(), + ); expect(result['ipadBundleId'], iosParams.ipadBundleId); expect(result['minimumVersion'], iosParams.minimumVersion); }); @@ -56,7 +58,9 @@ void main() { test('toString', () { expect( - iosParams.toString(), equals('$IosParameters(${iosParams.asMap})')); + iosParams.toString(), + equals('$IosParameters(${iosParams.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart index 6733e4487b27..40337d264794 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart @@ -38,8 +38,10 @@ void main() { }); test('toString', () { - expect(itunesParams.toString(), - equals('$ItunesConnectAnalyticsParameters(${itunesParams.asMap})')); + expect( + itunesParams.toString(), + equals('$ItunesConnectAnalyticsParameters(${itunesParams.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index 201d1f66beb4..16950831dd33 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -3,7 +3,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; @@ -104,7 +103,6 @@ void main() { return returnUrl; case 'FirebaseDynamicLinks#onLink': const String name = 'FirebaseDynamicLinks#onLink'; - print('RRRRRRR'); handleEventChannel(name, logger); return name; case 'FirebaseDynamicLinks#getInitialLink': @@ -353,13 +351,13 @@ void main() { }); test('listens to incoming changes', () async { - Stream stream = - dynamicLinks.onLink().asBroadcastStream(); - - await injectEventChannelResponse('FirebaseDynamicLinks#onLink', { - 'link': 'link', - 'ios': {'minimumVersion': 'minimumVersion'} - }); + // Stream stream = + // dynamicLinks.onLink().asBroadcastStream(); + // + // await injectEventChannelResponse('FirebaseDynamicLinks#onLink', { + // 'link': 'link', + // 'ios': {'minimumVersion': 'minimumVersion'} + // }); // TODO find out why event isn't emitted. also catch error. // await expectLater( // stream, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart index 094ea699c831..b82bea110a87 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/mock.dart @@ -72,7 +72,9 @@ void handleEventChannel( } Future injectEventChannelResponse( - String channelName, Map event) async { + String channelName, + Map event, +) async { await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage( channelName, MethodChannelFirebaseDynamicLinks.channel.codec diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart index fb6bd34ae60c..6eef03b26a35 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/navigation_info_parameters_test.dart @@ -24,13 +24,17 @@ void main() { expect(result, isA>()); expect( - result['forcedRedirectEnabled'], navParams.forcedRedirectEnabled); + result['forcedRedirectEnabled'], + navParams.forcedRedirectEnabled, + ); }); }); test('toString', () { - expect(navParams.toString(), - equals('$NavigationInfoParameters(${navParams.asMap})')); + expect( + navParams.toString(), + equals('$NavigationInfoParameters(${navParams.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart index 03f1a520bba5..84d7ec326ee0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart @@ -11,7 +11,9 @@ void main() { String minimumVersionIos = 'minimum version'; int clickTimestamp = 12345345; PendingDynamicLinkDataAndroid androidData = PendingDynamicLinkDataAndroid( - minimumVersion: minimumVersion, clickTimestamp: clickTimestamp); + minimumVersion: minimumVersion, + clickTimestamp: clickTimestamp, + ); PendingDynamicLinkDataIOS iosData = PendingDynamicLinkDataIOS(minimumVersion: minimumVersionIos); @@ -23,12 +25,18 @@ void main() { test('returns an instance of [PendingDynamicLinkData]', () { expect(pendingDynamicLinkData, isA()); expect(pendingDynamicLinkData.link, link); - expect(pendingDynamicLinkData.android?.clickTimestamp, - androidData.clickTimestamp); - expect(pendingDynamicLinkData.android?.minimumVersion, - androidData.minimumVersion); expect( - pendingDynamicLinkData.ios?.minimumVersion, iosData.minimumVersion); + pendingDynamicLinkData.android?.clickTimestamp, + androidData.clickTimestamp, + ); + expect( + pendingDynamicLinkData.android?.minimumVersion, + androidData.minimumVersion, + ); + expect( + pendingDynamicLinkData.ios?.minimumVersion, + iosData.minimumVersion, + ); }); group('asMap', () { @@ -36,19 +44,27 @@ void main() { final result = pendingDynamicLinkData.asMap(); expect(result, isA>()); - expect(result['android']['clickTimestamp'], - pendingDynamicLinkData.android?.clickTimestamp); - expect(result['android']['minimumVersion'], - pendingDynamicLinkData.android?.minimumVersion); - expect(result['ios']['minimumVersion'], - pendingDynamicLinkData.ios?.minimumVersion); + expect( + result['android']['clickTimestamp'], + pendingDynamicLinkData.android?.clickTimestamp, + ); + expect( + result['android']['minimumVersion'], + pendingDynamicLinkData.android?.minimumVersion, + ); + expect( + result['ios']['minimumVersion'], + pendingDynamicLinkData.ios?.minimumVersion, + ); expect(result['link'], pendingDynamicLinkData.link.toString()); }); }); test('toString', () { - expect(pendingDynamicLinkData.toString(), - equals('$PendingDynamicLinkData(${pendingDynamicLinkData.asMap})')); + expect( + pendingDynamicLinkData.toString(), + equals('$PendingDynamicLinkData(${pendingDynamicLinkData.asMap})'), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart index 8e6c217d26dd..617926998122 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -38,16 +38,22 @@ void main() { }); test('Constructor', () { - expect(firebaseDynamicLinksPlatformPlatform, - isA()); + expect( + firebaseDynamicLinksPlatformPlatform, + isA(), + ); expect(firebaseDynamicLinksPlatformPlatform, isA()); }); test('get.instance', () { - expect(FirebaseDynamicLinksPlatform.instance, - isA()); - expect(FirebaseDynamicLinksPlatform.instance.app.name, - equals(defaultFirebaseAppName)); + expect( + FirebaseDynamicLinksPlatform.instance, + isA(), + ); + expect( + FirebaseDynamicLinksPlatform.instance.app.name, + equals(defaultFirebaseAppName), + ); }); group('set.instance', () { @@ -55,58 +61,92 @@ void main() { FirebaseDynamicLinksPlatform.instance = TestFirebaseDynamicLinksPlatform(secondaryApp!); - expect(FirebaseDynamicLinksPlatform.instance, - isA()); expect( - FirebaseDynamicLinksPlatform.instance.app.name, equals('testApp2')); + FirebaseDynamicLinksPlatform.instance, + isA(), + ); + expect( + FirebaseDynamicLinksPlatform.instance.app.name, + equals('testApp2'), + ); }); }); test('throws if .getInitialLink', () { expect( () => firebaseDynamicLinksPlatformPlatform!.getInitialLink(), - throwsA(isA().having((e) => e.message, 'message', - 'getInitialLink() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'getInitialLink() is not implemented', + ), + ), ); }); test('throws if .getDynamicLink', () { expect( () => firebaseDynamicLinksPlatformPlatform!.getDynamicLink(link), - throwsA(isA().having((e) => e.message, 'message', - 'getDynamicLink() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'getDynamicLink() is not implemented', + ), + ), ); }); test('throws if .onLink', () { expect( () => firebaseDynamicLinksPlatformPlatform!.onLink(), - throwsA(isA().having( - (e) => e.message, 'message', 'onLink() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'onLink() is not implemented', + ), + ), ); }); test('throws if .shortenUrl', () { expect( () => firebaseDynamicLinksPlatformPlatform!.shortenUrl(link), - throwsA(isA().having( - (e) => e.message, 'message', 'shortenUrl() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'shortenUrl() is not implemented', + ), + ), ); }); test('throws if .buildUrl', () { expect( () => firebaseDynamicLinksPlatformPlatform!.buildUrl(parameters), - throwsA(isA().having( - (e) => e.message, 'message', 'buildUrl() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'buildUrl() is not implemented', + ), + ), ); }); test('throws if .buildShortLink', () { expect( () => firebaseDynamicLinksPlatformPlatform!.buildShortLink(parameters), - throwsA(isA().having((e) => e.message, 'message', - 'buildShortLink() is not implemented')), + throwsA( + isA().having( + (e) => e.message, + 'message', + 'buildShortLink() is not implemented', + ), + ), ); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart index a50bb9408f03..5d5e933e8634 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart @@ -12,7 +12,10 @@ void main() { group('$ShortDynamicLink', () { ShortDynamicLink shortLink = ShortDynamicLink( - shortUrl: link, previewLink: previewLink, warnings: warnings); + shortUrl: link, + previewLink: previewLink, + warnings: warnings, + ); group('Constructor', () { test('returns an instance of [ShortDynamicLink]', () { @@ -34,8 +37,12 @@ void main() { }); test('toString', () { - expect(shortLink.toString(), - equals('$ShortDynamicLink(${shortLink.asMap})')); + expect( + shortLink.toString(), + equals( + '$ShortDynamicLink(${shortLink.asMap})', + ), + ); }); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart index a00f14ebf0d4..61bf0a0a2153 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/social_meta_tag_parameters_test.dart @@ -12,7 +12,10 @@ void main() { group('$SocialMetaTagParameters', () { SocialMetaTagParameters socialMetaTagParameters = SocialMetaTagParameters( - description: description, title: title, imageUrl: imageUrl); + description: description, + title: title, + imageUrl: imageUrl, + ); group('Constructor', () { test('returns an instance of [SocialMetaTagParameters]', () { @@ -30,15 +33,19 @@ void main() { expect(result['description'], socialMetaTagParameters.description); expect(result['title'], socialMetaTagParameters.title); expect( - result['imageUrl'], socialMetaTagParameters.imageUrl.toString()); + result['imageUrl'], + socialMetaTagParameters.imageUrl.toString(), + ); }); }); test('toString', () { expect( - socialMetaTagParameters.toString(), - equals( - '$SocialMetaTagParameters(${socialMetaTagParameters.asMap})')); + socialMetaTagParameters.toString(), + equals( + '$SocialMetaTagParameters(${socialMetaTagParameters.asMap})', + ), + ); }); }); }); From 490b4932cf5ac2990e1bb6cce1fa052f10ce20f2 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 17:45:39 +0000 Subject: [PATCH 056/125] test(dynamic-links): fix universal tests --- .../test/firebase_dynamic_links_test.dart | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index d7f64099587b..4a3d8d6ebc0c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -78,17 +78,10 @@ void main() { late FirebaseDynamicLinks dynamicLinks; group('$FirebaseDynamicLinks', () { - setUp(() async { + setUpAll(() async { FirebaseDynamicLinksPlatform.instance = mockDynamicLinksPlatform; - await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: '', - appId: '', - messagingSenderId: '', - projectId: '', - ), - ); + await Firebase.initializeApp(); dynamicLinks = FirebaseDynamicLinks.instance; }); From c88e34a10418d944ce19f3ed0141ff6fbc2e534d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 20:09:55 +0000 Subject: [PATCH 057/125] test(dynamic-links): fix e2e tests --- .../FirebaseDynamicLinksPlugin.java | 13 ++++++------- .../example/test_driver/instance_e2e.dart | 19 ++++++------------- ...method_channel_firebase_dynamic_links.dart | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java index 795be176f207..09b4217ad9ed 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java @@ -130,10 +130,9 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); break; case "FirebaseDynamicLinks#shortenUrl": - DynamicLink.Builder urlBuilderShorten = setupParameters(call.arguments()); - urlBuilderShorten.setLongLink(Uri.parse(call.argument("url"))); - methodCallTask = - buildShortLink(urlBuilderShorten, call.argument("dynamicLinkParametersOptions")); + DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink(); + builder.setLongLink(Uri.parse(call.argument("url"))); + methodCallTask = buildShortLink(builder, call.argument("dynamicLinkParametersOptions")); break; case "FirebaseDynamicLinks#getDynamicLink": case "FirebaseDynamicLinks#getInitialLink": @@ -175,7 +174,6 @@ private Task> buildShortLink( cachedThreadPool, () -> { Integer suffix = null; - if (dynamicLinkParametersOptions != null) { Integer shortDynamicLinkPathLength = (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); @@ -200,15 +198,16 @@ private Task> buildShortLink( } else { shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); } + List warnings = new ArrayList<>(); for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { warnings.add(warning.getMessage()); } - result.put("url", shortLink.getShortLink()); + result.put("url", shortLink.getShortLink().toString()); result.put("warnings", warnings); - result.put("previewLink", shortLink.getPreviewLink()); + result.put("previewLink", shortLink.getPreviewLink().toString()); return result; }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 4fb1db5efae9..624671d6b52d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -27,7 +27,7 @@ void runInstanceTests() { test('build normal dynamic links', () async { FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; + 'io.flutter.plugins.firebase.dynamiclinksexample'; const String iosBundleId = 'com.google.FirebaseCppDynamicLinksTestApp.dev'; const String urlHost = 'reactnativefirebase.page.link'; @@ -88,7 +88,7 @@ void runInstanceTests() { test('build a short dynamic link', () async { FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; + 'io.flutter.plugins.firebase.dynamiclinksexample'; const String iosBundleId = 'io.flutter.plugins.firebase.dynamiclinksexample'; const String urlHost = 'reactnativefirebase.page.link'; @@ -115,18 +115,18 @@ void runInstanceTests() { // androidParameters.minimumVersion expect( - uri.shortUrl.host, + uri.shortUrl.host.toString(), urlHost, ); expect( - uri.shortUrl.path.length, - isNotNull, + uri.shortUrl.pathSegments.length, + equals(1), ); expect( uri.shortUrl.path.length, - lessThanOrEqualTo(16), + lessThanOrEqualTo(18), ); }); }); @@ -186,13 +186,6 @@ void runInstanceTests() { }); group('onLink', () { - test('grab first stream event', () async { - PendingDynamicLinkData? pendingLink = - await FirebaseDynamicLinks.instance.onLink().first; - - expect(pendingLink, isNull); - }); - test('test multiple times', () async { StreamSubscription _onListenSubscription; StreamSubscription _onListenSubscriptionSecond; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 5cb307a9f641..a5ada42763f9 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -197,7 +197,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return ShortDynamicLink( shortUrl: Uri.parse(response['url']), warnings: warnings?.cast(), - previewLink: response['previewLink'], + previewLink: Uri.parse(response['previewLink']), ); } } From 61a8ba90f73ea3e619c638a3b58292b1d53482e9 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 20:34:18 +0000 Subject: [PATCH 058/125] test(dynamic-links, ios): nullable preview link --- .../method_channel/method_channel_firebase_dynamic_links.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index a5ada42763f9..e84d687e2cbd 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -197,7 +197,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return ShortDynamicLink( shortUrl: Uri.parse(response['url']), warnings: warnings?.cast(), - previewLink: Uri.parse(response['previewLink']), + previewLink: response['previewLink'] != null ? Uri.parse(response['previewLink']) : null, ); } } From cb7851779f6d14ba6f33d67bd7e7eef1da168f23 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 20:36:23 +0000 Subject: [PATCH 059/125] chore: revert melos.yaml --- melos.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melos.yaml b/melos.yaml index 473e761e779d..9773e2a71f6d 100644 --- a/melos.yaml +++ b/melos.yaml @@ -1,7 +1,7 @@ name: FlutterFire packages: - - packages/firebase_dynamic_links/** + - packages/** ignore: # TODO Excluded - pending rewrite to use latest SDKs. From c52c6c5c372e57e5cd83e96993a4dfc986509e3f Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 20:49:20 +0000 Subject: [PATCH 060/125] refactor(dynamic_links, android): packages --- .../android/src/main/AndroidManifest.xml | 2 +- .../dynamiclinks}/Constants.java | 2 +- .../FirebaseDynamicLinksPlugin.java | 16 ++++++++-------- .../FlutterFirebaseAppRegistrar.java | 2 +- .../dynamiclinks}/OnLinkStreamHandler.java | 2 +- .../dynamiclinks}/Utils.java | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/{firebasedynamiclinks => firebase/dynamiclinks}/Constants.java (68%) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/{firebasedynamiclinks => firebase/dynamiclinks}/FirebaseDynamicLinksPlugin.java (95%) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/{firebasedynamiclinks => firebase/dynamiclinks}/FlutterFirebaseAppRegistrar.java (90%) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/{firebasedynamiclinks => firebase/dynamiclinks}/OnLinkStreamHandler.java (94%) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/{firebasedynamiclinks => firebase/dynamiclinks}/Utils.java (95%) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml index 663e4f0f3de9..15cb83aa9bec 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ - diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java similarity index 68% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java index a6d23e052198..cfdda1ae9ef1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Constants.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java @@ -1,4 +1,4 @@ -package io.flutter.plugins.firebasedynamiclinks; +package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; public class Constants { public static final String APP_NAME = "appName"; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java similarity index 95% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java index 09b4217ad9ed..fd6bd9e96cd0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package io.flutter.plugins.firebasedynamiclinks; +package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; import android.app.Activity; import android.content.Intent; @@ -46,7 +46,7 @@ public class FirebaseDynamicLinksPlugin private MethodChannel channel; @Nullable private BinaryMessenger messenger; - private final Map + private final Map streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -108,7 +108,7 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments @Override public boolean onNewIntent(Intent intent) { // Passes intent to every listener for different app instances the user may create - for (io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler instance : + for (OnLinkStreamHandler instance : streamHandlers.values()) { instance.sinkEvent(intent); } @@ -155,9 +155,9 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re } else { Exception exception = task.getException(); result.error( - io.flutter.plugins.firebasedynamiclinks.Constants.DEFAULT_ERROR_CODE, + Constants.DEFAULT_ERROR_CODE, exception != null ? exception.getMessage() : null, - io.flutter.plugins.firebasedynamiclinks.Utils.getExceptionDetails(exception)); + Utils.getExceptionDetails(exception)); } }); } @@ -235,7 +235,7 @@ private Task> getDynamicLink( return null; } - return io.flutter.plugins.firebasedynamiclinks.Utils.getMapFromPendingDynamicLinkData( + return Utils.getMapFromPendingDynamicLinkData( pendingDynamicLink); }); } @@ -363,8 +363,8 @@ private Task registerOnLinkListener( return Tasks.call( cachedThreadPool, () -> { - final io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler handler = - new io.flutter.plugins.firebasedynamiclinks.OnLinkStreamHandler(dynamicLinks); + final OnLinkStreamHandler handler = + new OnLinkStreamHandler(dynamicLinks); final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; final EventChannel channel = new EventChannel(messenger, name); channel.setStreamHandler(handler); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java similarity index 90% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java index dbf3822c7a24..df2486711bc1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/FlutterFirebaseAppRegistrar.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package io.flutter.plugins.firebasedynamiclinks; +package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; import androidx.annotation.Keep; import com.google.firebase.components.Component; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java similarity index 94% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java index 28be9425f352..c9621084ad9e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/OnLinkStreamHandler.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java @@ -1,4 +1,4 @@ -package io.flutter.plugins.firebasedynamiclinks; +package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; import android.content.Intent; import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java similarity index 95% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java index 7527bd5e5d97..e3f03896bea3 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebasedynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java @@ -1,4 +1,4 @@ -package io.flutter.plugins.firebasedynamiclinks; +package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; import android.net.Uri; import androidx.annotation.Nullable; From 9e2f56c640b46f01084fc6b4dde30775e9216691 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 20:57:41 +0000 Subject: [PATCH 061/125] refactor(dynamic_links, android): packages --- .../io/flutter/plugins/firebase/dynamiclinks/Constants.java | 2 +- .../firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java | 2 +- ...ksPlugin.java => FlutterFirebaseDynamicLinksPlugin.java} | 6 +++--- .../plugins/firebase/dynamiclinks/OnLinkStreamHandler.java | 2 +- .../io/flutter/plugins/firebase/dynamiclinks/Utils.java | 2 +- .../firebase_dynamic_links/pubspec.yaml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) rename packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/{FirebaseDynamicLinksPlugin.java => FlutterFirebaseDynamicLinksPlugin.java} (98%) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java index cfdda1ae9ef1..ccbfc4efa5d4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Constants.java @@ -1,4 +1,4 @@ -package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; +package io.flutter.plugins.firebase.dynamiclinks; public class Constants { public static final String APP_NAME = "appName"; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java index df2486711bc1..329ba3fc981f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseAppRegistrar.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; +package io.flutter.plugins.firebase.dynamiclinks; import androidx.annotation.Keep; import com.google.firebase.components.Component; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java similarity index 98% rename from packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java rename to packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index fd6bd9e96cd0..d690e7944a87 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; +package io.flutter.plugins.firebase.dynamiclinks; import android.app.Activity; import android.content.Intent; @@ -35,7 +35,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; -public class FirebaseDynamicLinksPlugin +public class FlutterFirebaseDynamicLinksPlugin implements FlutterFirebasePlugin, FlutterPlugin, ActivityAware, @@ -157,7 +157,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re result.error( Constants.DEFAULT_ERROR_CODE, exception != null ? exception.getMessage() : null, - Utils.getExceptionDetails(exception)); + io.flutter.plugins.firebase.dynamiclinks.Utils.getExceptionDetails(exception)); } }); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java index c9621084ad9e..9e2713b9c806 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java @@ -1,4 +1,4 @@ -package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; +package io.flutter.plugins.firebase.dynamiclinks; import android.content.Intent; import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java index e3f03896bea3..e241c7e0ac5e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java @@ -1,4 +1,4 @@ -package android.src.main.java.io.flutter.plugins.firebase.dynamiclinks; +package io.flutter.plugins.firebase.dynamiclinks; import android.net.Uri; import androidx.annotation.Nullable; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml index 4f2de72edfab..e23932b396f0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml @@ -29,7 +29,7 @@ flutter: plugin: platforms: android: - package: io.flutter.plugins.firebasedynamiclinks - pluginClass: FirebaseDynamicLinksPlugin + package: io.flutter.plugins.firebase.dynamiclinks + pluginClass: FlutterFirebaseDynamicLinksPlugin ios: pluginClass: FLTFirebaseDynamicLinksPlugin From 8e26f05766a9dca99612cd2e668457f15eaa0677 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 21:01:37 +0000 Subject: [PATCH 062/125] refactor(dynamic_links, android): AndroidManifest.xml --- .../firebase_dynamic_links/android/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml index 15cb83aa9bec..ca9eb6daabf3 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ - From 95f10bf7ea62667c51665cc558a6b17cbc44c0f1 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 21:39:36 +0000 Subject: [PATCH 063/125] chore(dynamic_links): fic CI issues --- .../FlutterFirebaseDynamicLinksPlugin.java | 12 ++++------ .../example/test_driver/instance_e2e.dart | 2 +- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 22 +++++++++---------- ...method_channel_firebase_dynamic_links.dart | 4 +++- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index d690e7944a87..d2f4369f5544 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -46,8 +46,7 @@ public class FlutterFirebaseDynamicLinksPlugin private MethodChannel channel; @Nullable private BinaryMessenger messenger; - private final Map - streamHandlers = new HashMap<>(); + private final Map streamHandlers = new HashMap<>(); private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -108,8 +107,7 @@ static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments @Override public boolean onNewIntent(Intent intent) { // Passes intent to every listener for different app instances the user may create - for (OnLinkStreamHandler instance : - streamHandlers.values()) { + for (OnLinkStreamHandler instance : streamHandlers.values()) { instance.sinkEvent(intent); } return false; @@ -235,8 +233,7 @@ private Task> getDynamicLink( return null; } - return Utils.getMapFromPendingDynamicLinkData( - pendingDynamicLink); + return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); }); } @@ -363,8 +360,7 @@ private Task registerOnLinkListener( return Tasks.call( cachedThreadPool, () -> { - final OnLinkStreamHandler handler = - new OnLinkStreamHandler(dynamicLinks); + final OnLinkStreamHandler handler = new OnLinkStreamHandler(dynamicLinks); final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; final EventChannel channel = new EventChannel(messenger, name); channel.setStreamHandler(handler); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 624671d6b52d..f4f76eed41eb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -115,7 +115,7 @@ void runInstanceTests() { // androidParameters.minimumVersion expect( - uri.shortUrl.host.toString(), + uri.shortUrl.host, urlHost, ); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 0a8efefa42c3..5b24ed9a0cbf 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -37,10 +37,10 @@ NSString *message = @"An unknown error has occurred."; if (error == nil) { return @{ - kCode : code, - kMessage : message, - @"additionalData" : @{}, - }; + kCode : code, + kMessage : message, + @"additionalData" : @{}, + }; } NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; @@ -48,7 +48,7 @@ dictionary[kMessage] = [error localizedDescription]; id additionalData = [NSMutableDictionary dictionary]; - if([error userInfo] != nil){ + if ([error userInfo] != nil) { additionalData = [error userInfo]; } @@ -320,18 +320,18 @@ - (void)registerOnLinkListener:(id)arguments // Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { if (error) { - if (_initialLink == nil) { // store initial error to pass back to user if getInitialLink is called _initialError = error; } - NSDictionary * errorDetails = getDictionaryFromNSError(error); + NSDictionary *errorDetails = getDictionaryFromNSError(error); - FlutterError * flutterError = [FLTFirebasePlugin createFlutterErrorFromCode:errorDetails[kCode] - message:errorDetails[kMessage] - optionalDetails:errorDetails - andOptionalNSError:error]; + FlutterError *flutterError = + [FLTFirebasePlugin createFlutterErrorFromCode:errorDetails[kCode] + message:errorDetails[kMessage] + optionalDetails:errorDetails + andOptionalNSError:error]; NSLog(@"FLTFirebaseDynamicLinks: Unknown error occurred when attempting to handle a dynamic " @"link: %@", diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index e84d687e2cbd..31aa908670e9 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -197,7 +197,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return ShortDynamicLink( shortUrl: Uri.parse(response['url']), warnings: warnings?.cast(), - previewLink: response['previewLink'] != null ? Uri.parse(response['previewLink']) : null, + previewLink: response['previewLink'] != null + ? Uri.parse(response['previewLink']) + : null, ); } } From fd7134f267c9a5d9b80b6292a14adddd02fc3ba0 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 16 Nov 2021 22:15:25 +0000 Subject: [PATCH 064/125] chore(dynamic_links, android): change package --- .../firebase_dynamic_links/android/build.gradle | 2 +- .../firebase_dynamic_links/android/src/main/AndroidManifest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle index 5b56ac4c2727..392261047a2e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/build.gradle @@ -1,4 +1,4 @@ -group 'io.flutter.plugins.firebasedynamiclinks' +group 'io.flutter.plugins.firebase.dynamiclinks' version '1.0-SNAPSHOT' buildscript { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml index ca9eb6daabf3..376bea6cd392 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="io.flutter.plugins.firebase.dynamiclinks"> From 5e8c71b67689d40e4a3014f4ceb95619ccdf2229 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 09:13:03 +0000 Subject: [PATCH 065/125] chore: CI update --- .github/workflows/firebase_dynamic_links.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/firebase_dynamic_links.yaml b/.github/workflows/firebase_dynamic_links.yaml index 7b52969fd7bb..f53b9f2baa24 100644 --- a/.github/workflows/firebase_dynamic_links.yaml +++ b/.github/workflows/firebase_dynamic_links.yaml @@ -40,11 +40,10 @@ jobs: - name: "Drive Example" uses: reactivecircus/android-emulator-runner@v2 with: - api-level: 28 + api-level: 29 arch: x86_64 - # Firebase Database works without Google Play Services, so we don't use the `googleapis` - # emulator target as it's considerably slower on CI. - target: default + # Firebase Dynamic Links requires Google Play Services, so we use the `googleapis` + target: googleapis profile: Nexus 5X script: ./.github/workflows/scripts/drive-example.sh android From 353df06a1af7a66f638ce2b1a53aeb4b6731e5af Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 09:23:57 +0000 Subject: [PATCH 066/125] chore: CI update --- .github/workflows/firebase_dynamic_links.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/firebase_dynamic_links.yaml b/.github/workflows/firebase_dynamic_links.yaml index f53b9f2baa24..4ce0ce62b662 100644 --- a/.github/workflows/firebase_dynamic_links.yaml +++ b/.github/workflows/firebase_dynamic_links.yaml @@ -42,8 +42,8 @@ jobs: with: api-level: 29 arch: x86_64 - # Firebase Dynamic Links requires Google Play Services, so we use the `googleapis` - target: googleapis + # Firebase Dynamic Links requires Google Play Services, so we use the `google_apis` + target: google_apis profile: Nexus 5X script: ./.github/workflows/scripts/drive-example.sh android From 9e27941fd3092b1244a4b30ff6dd6e6b5bc491fa Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 10:14:56 +0000 Subject: [PATCH 067/125] chore: CHANGELOG.md fix for CI --- .../firebase_dynamic_links_platform_interface/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md index ea062ddb2331..a0f083857730 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md @@ -1,3 +1,3 @@ -## 1.0.0-dev.1 +# 0.0.1 - Initial release. From c00ca6c0b390cd34511d1477846ffdaa9e463993 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 10:15:22 +0000 Subject: [PATCH 068/125] chore(dynamic_link): tweaks for android --- .../firebase_dynamic_links/example/android/app/build.gradle | 6 +++--- .../example/test_driver/instance_e2e.dart | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle index 096a11864303..d2dbe6457e6e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/build.gradle @@ -25,16 +25,16 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 29 + compileSdkVersion 31 lintOptions { disable 'InvalidPackage' } defaultConfig { - applicationId "io.flutter.plugins.firebasedynamiclinksexample" + applicationId "io.flutter.plugins.firebase.dynamiclinksexample" minSdkVersion 19 - targetSdkVersion 29 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index f4f76eed41eb..982913803f93 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -31,7 +31,7 @@ void runInstanceTests() { const String iosBundleId = 'com.google.FirebaseCppDynamicLinksTestApp.dev'; const String urlHost = 'reactnativefirebase.page.link'; - const String link = 'https://dynamic.link.example/helloworld'; + const String link = 'https://invertase.io'; final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://$urlHost', @@ -92,7 +92,7 @@ void runInstanceTests() { const String iosBundleId = 'io.flutter.plugins.firebase.dynamiclinksexample'; const String urlHost = 'reactnativefirebase.page.link'; - const String link = 'https://dynamic.link.example/helloworld'; + const String link = 'https://invertase.io'; final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://$urlHost', @@ -139,7 +139,7 @@ void runInstanceTests() { const String iosBundleId = 'io.flutter.plugins.firebase.dynamiclinksexample'; const String urlHost = 'reactnativefirebase.page.link'; - const String link = 'https://dynamic.link.example/helloworld'; + const String link = 'https://invertase.io'; final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://$urlHost', From e70b4fb9eac81e463726cb9c546d7429937fb8ec Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 16:12:37 +0000 Subject: [PATCH 069/125] refactor(dynamic_link): update event handling --- .../FlutterFirebaseDynamicLinksPlugin.java | 235 ++++++++---------- .../dynamiclinks/OnLinkStreamHandler.java | 43 ---- .../ios/Runner.xcodeproj/project.pbxproj | 11 +- .../example/ios/Runner/Info.plist | 2 +- .../example/ios/Runner/Runner.entitlements | 7 +- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 58 +---- .../ios/Classes/FLTOnLinkStreamHandler.m | 34 --- ...method_channel_firebase_dynamic_links.dart | 57 ++--- 8 files changed, 156 insertions(+), 291 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index d2f4369f5544..cdf7cd2ecd2f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -7,8 +7,10 @@ import android.app.Activity; import android.content.Intent; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; + import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.Tasks; import com.google.firebase.FirebaseApp; @@ -16,6 +18,7 @@ import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; import com.google.firebase.dynamiclinks.PendingDynamicLinkData; import com.google.firebase.dynamiclinks.ShortDynamicLink; + import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; @@ -28,6 +31,7 @@ import io.flutter.plugin.common.PluginRegistry.NewIntentListener; import io.flutter.plugins.firebase.core.FlutterFirebasePlugin; import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,17 +40,16 @@ import java.util.concurrent.atomic.AtomicReference; public class FlutterFirebaseDynamicLinksPlugin - implements FlutterFirebasePlugin, - FlutterPlugin, - ActivityAware, - MethodCallHandler, - NewIntentListener { + implements FlutterFirebasePlugin, + FlutterPlugin, + ActivityAware, + MethodCallHandler, + NewIntentListener { private final AtomicReference activity = new AtomicReference<>(null); private MethodChannel channel; - @Nullable private BinaryMessenger messenger; - - private final Map streamHandlers = new HashMap<>(); + @Nullable + private BinaryMessenger messenger; private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -68,7 +71,6 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { channel.setMethodCallHandler(null); channel = null; messenger = null; - removeEventListeners(); } @Override @@ -97,19 +99,31 @@ public void onDetachedFromActivity() { detachToActivity(); } - static FirebaseDynamicLinks getDynamicLinkInstance(Map arguments) { - String appName = (String) Objects.requireNonNull(arguments.get(Constants.APP_NAME)); - FirebaseApp app = FirebaseApp.getInstance(appName); + static FirebaseDynamicLinks getDynamicLinkInstance(@Nullable Map arguments) { + if (arguments != null) { + String appName = (String) arguments.get(Constants.APP_NAME); + if (appName != null) { + FirebaseApp app = FirebaseApp.getInstance(appName); + return FirebaseDynamicLinks.getInstance(app); + } + } - return FirebaseDynamicLinks.getInstance(app); + return FirebaseDynamicLinks.getInstance(); } @Override public boolean onNewIntent(Intent intent) { - // Passes intent to every listener for different app instances the user may create - for (OnLinkStreamHandler instance : streamHandlers.values()) { - instance.sinkEvent(intent); - } + getDynamicLinkInstance(null) + .getDynamicLink(intent) + .addOnSuccessListener( + pendingDynamicLinkData -> { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + channel.invokeMethod("FirebaseDynamicLink#onLinkSuccess", dynamicLink); + }) + .addOnFailureListener( + exception -> + channel.invokeMethod("FirebaseDynamicLink#onLinkError", Utils.getExceptionDetails(exception))); return false; } @@ -136,28 +150,23 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re case "FirebaseDynamicLinks#getInitialLink": methodCallTask = getDynamicLink(dynamicLinks, call.argument("url")); break; - case "FirebaseDynamicLinks#onLink": - methodCallTask = - registerOnLinkListener( - Objects.requireNonNull(call.argument(Constants.APP_NAME)), dynamicLinks); - break; default: result.notImplemented(); return; } methodCallTask.addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - result.success(task.getResult()); - } else { - Exception exception = task.getException(); - result.error( - Constants.DEFAULT_ERROR_CODE, - exception != null ? exception.getMessage() : null, - io.flutter.plugins.firebase.dynamiclinks.Utils.getExceptionDetails(exception)); - } - }); + task -> { + if (task.isSuccessful()) { + result.success(task.getResult()); + } else { + Exception exception = task.getException(); + result.error( + Constants.DEFAULT_ERROR_CODE, + exception != null ? exception.getMessage() : null, + io.flutter.plugins.firebase.dynamiclinks.Utils.getExceptionDetails(exception)); + } + }); } private String buildUrl(Map arguments) { @@ -167,74 +176,74 @@ private String buildUrl(Map arguments) { } private Task> buildShortLink( - DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { + DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { return Tasks.call( - cachedThreadPool, - () -> { - Integer suffix = null; - if (dynamicLinkParametersOptions != null) { - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); - if (shortDynamicLinkPathLength != null) { - switch (shortDynamicLinkPathLength) { - case 0: - suffix = ShortDynamicLink.Suffix.UNGUESSABLE; - break; - case 1: - suffix = ShortDynamicLink.Suffix.SHORT; - break; - default: - break; - } + cachedThreadPool, + () -> { + Integer suffix = null; + if (dynamicLinkParametersOptions != null) { + Integer shortDynamicLinkPathLength = + (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); + if (shortDynamicLinkPathLength != null) { + switch (shortDynamicLinkPathLength) { + case 0: + suffix = ShortDynamicLink.Suffix.UNGUESSABLE; + break; + case 1: + suffix = ShortDynamicLink.Suffix.SHORT; + break; + default: + break; } } + } - Map result = new HashMap<>(); - ShortDynamicLink shortLink; - if (suffix != null) { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); - } else { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); - } + Map result = new HashMap<>(); + ShortDynamicLink shortLink; + if (suffix != null) { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); + } else { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); + } - List warnings = new ArrayList<>(); + List warnings = new ArrayList<>(); - for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { - warnings.add(warning.getMessage()); - } + for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { + warnings.add(warning.getMessage()); + } - result.put("url", shortLink.getShortLink().toString()); - result.put("warnings", warnings); - result.put("previewLink", shortLink.getPreviewLink().toString()); + result.put("url", shortLink.getShortLink().toString()); + result.put("warnings", warnings); + result.put("previewLink", shortLink.getPreviewLink().toString()); - return result; - }); + return result; + }); } private Task> getDynamicLink( - FirebaseDynamicLinks dynamicLinks, @Nullable String url) { + FirebaseDynamicLinks dynamicLinks, @Nullable String url) { return Tasks.call( - cachedThreadPool, - () -> { - PendingDynamicLinkData pendingDynamicLink; - - if (url != null) { - pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); - } else { - // If there's no activity or initial Intent, then there's no initial dynamic link. - if (activity.get() == null || activity.get().getIntent() == null) { - return null; - } - pendingDynamicLink = - Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); - } - - if (pendingDynamicLink == null) { + cachedThreadPool, + () -> { + PendingDynamicLinkData pendingDynamicLink; + + if (url != null) { + pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); + } else { + // If there's no activity or initial Intent, then there's no initial dynamic link. + if (activity.get() == null || activity.get().getIntent() == null) { return null; } + pendingDynamicLink = + Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); + } + + if (pendingDynamicLink == null) { + return null; + } - return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); - }); + return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + }); } private DynamicLink.Builder setupParameters(Map arguments) { @@ -247,14 +256,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setLink(Uri.parse(link)); Map androidParameters = - (Map) arguments.get("androidParameters"); + (Map) arguments.get("androidParameters"); if (androidParameters != null) { String packageName = valueFor("packageName", androidParameters); String fallbackUrl = valueFor("fallbackUrl", androidParameters); Integer minimumVersion = valueFor("minimumVersion", androidParameters); DynamicLink.AndroidParameters.Builder builder = - new DynamicLink.AndroidParameters.Builder(packageName); + new DynamicLink.AndroidParameters.Builder(packageName); if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); @@ -263,7 +272,7 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map googleAnalyticsParameters = - (Map) arguments.get("googleAnalyticsParameters"); + (Map) arguments.get("googleAnalyticsParameters"); if (googleAnalyticsParameters != null) { String campaign = valueFor("campaign", googleAnalyticsParameters); String content = valueFor("content", googleAnalyticsParameters); @@ -272,7 +281,7 @@ private DynamicLink.Builder setupParameters(Map arguments) { String term = valueFor("term", googleAnalyticsParameters); DynamicLink.GoogleAnalyticsParameters.Builder builder = - new DynamicLink.GoogleAnalyticsParameters.Builder(); + new DynamicLink.GoogleAnalyticsParameters.Builder(); if (campaign != null) builder.setCampaign(campaign); if (content != null) builder.setContent(content); @@ -306,14 +315,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map itunesConnectAnalyticsParameters = - (Map) arguments.get("itunesConnectAnalyticsParameters"); + (Map) arguments.get("itunesConnectAnalyticsParameters"); if (itunesConnectAnalyticsParameters != null) { String affiliateToken = valueFor("affiliateToken", itunesConnectAnalyticsParameters); String campaignToken = valueFor("campaignToken", itunesConnectAnalyticsParameters); String providerToken = valueFor("providerToken", itunesConnectAnalyticsParameters); DynamicLink.ItunesConnectAnalyticsParameters.Builder builder = - new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); + new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); if (affiliateToken != null) builder.setAffiliateToken(affiliateToken); if (campaignToken != null) builder.setCampaignToken(campaignToken); @@ -323,12 +332,12 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map navigationInfoParameters = - (Map) arguments.get("navigationInfoParameters"); + (Map) arguments.get("navigationInfoParameters"); if (navigationInfoParameters != null) { Boolean forcedRedirectEnabled = valueFor("forcedRedirectEnabled", navigationInfoParameters); DynamicLink.NavigationInfoParameters.Builder builder = - new DynamicLink.NavigationInfoParameters.Builder(); + new DynamicLink.NavigationInfoParameters.Builder(); if (forcedRedirectEnabled != null) builder.setForcedRedirectEnabled(forcedRedirectEnabled); @@ -336,14 +345,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map socialMetaTagParameters = - (Map) arguments.get("socialMetaTagParameters"); + (Map) arguments.get("socialMetaTagParameters"); if (socialMetaTagParameters != null) { String description = valueFor("description", socialMetaTagParameters); String imageUrl = valueFor("imageUrl", socialMetaTagParameters); String title = valueFor("title", socialMetaTagParameters); DynamicLink.SocialMetaTagParameters.Builder builder = - new DynamicLink.SocialMetaTagParameters.Builder(); + new DynamicLink.SocialMetaTagParameters.Builder(); if (description != null) builder.setDescription(description); if (imageUrl != null) builder.setImageUrl(Uri.parse(imageUrl)); @@ -355,20 +364,6 @@ private DynamicLink.Builder setupParameters(Map arguments) { return dynamicLinkBuilder; } - private Task registerOnLinkListener( - @NonNull String appName, FirebaseDynamicLinks dynamicLinks) { - return Tasks.call( - cachedThreadPool, - () -> { - final OnLinkStreamHandler handler = new OnLinkStreamHandler(dynamicLinks); - final String name = METHOD_CHANNEL_NAME + "/get-link/" + appName; - final EventChannel channel = new EventChannel(messenger, name); - channel.setStreamHandler(handler); - streamHandlers.put(channel, handler); - return name; - }); - } - private static T valueFor(String key, Map map) { @SuppressWarnings("unchecked") T result = (T) map.get(key); @@ -383,21 +378,9 @@ public Task> getPluginConstantsForFirebaseApp(FirebaseApp fi @Override public Task didReinitializeFirebaseCore() { return Tasks.call( - cachedThreadPool, - () -> { - removeEventListeners(); - return null; - }); - } - - private void removeEventListeners() { - for (EventChannel eventChannel : streamHandlers.keySet()) { - StreamHandler streamHandler = streamHandlers.get(eventChannel); - assert streamHandler != null; - streamHandler.onCancel(null); - eventChannel.setStreamHandler(null); - } - - streamHandlers.clear(); + cachedThreadPool, + () -> { + return null; + }); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java deleted file mode 100644 index 9e2713b9c806..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/OnLinkStreamHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -package io.flutter.plugins.firebase.dynamiclinks; - -import android.content.Intent; -import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.EventChannel.StreamHandler; -import java.util.Map; - -public class OnLinkStreamHandler implements StreamHandler { - private EventChannel.EventSink events; - private final FirebaseDynamicLinks dynamicLinks; - - public OnLinkStreamHandler(FirebaseDynamicLinks dynamicLinks) { - this.dynamicLinks = dynamicLinks; - } - - public void sinkEvent(Intent intent) { - dynamicLinks - .getDynamicLink(intent) - .addOnSuccessListener( - pendingDynamicLinkData -> { - Map dynamicLink = - Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - events.success(dynamicLink); - }) - .addOnFailureListener( - exception -> - events.error( - Constants.DEFAULT_ERROR_CODE, - exception.getMessage(), - Utils.getExceptionDetails(exception))); - } - - @Override - public void onListen(Object arguments, EventChannel.EventSink events) { - this.events = events; - } - - @Override - public void onCancel(Object arguments) { - // Do nothing - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj index 51f949c78cda..7a5983ce5725 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj @@ -172,6 +172,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = YYX2P3XVJ7; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.SafariKeychain = { @@ -403,10 +404,11 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -418,7 +420,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; + PRODUCT_BUNDLE_IDENTIFIER = io.invertase.testing; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -431,10 +433,11 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -446,7 +449,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseCppDynamicLinksTestApp.dev; + PRODUCT_BUNDLE_IDENTIFIER = io.invertase.testing; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist index f24bc9d4f80d..4b8da07a8393 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Info.plist @@ -27,7 +27,7 @@ Bundle ID CFBundleURLSchemes - com.google.FirebaseCppDynamicLinksTestApp.dev + io.invertase.testing diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements index 0c67376ebacb..7c0178128b5f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner/Runner.entitlements @@ -1,5 +1,10 @@ - + + com.apple.developer.associated-domains + + applinks:reactnativefirebase.page.link + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 5b24ed9a0cbf..15c2f3439425 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -5,7 +5,6 @@ #import #import -#import "Private/FLTOnLinkStreamHandler.h" #import "Public/FLTFirebaseDynamicLinksPlugin.h" NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; @@ -61,19 +60,16 @@ @implementation FLTFirebaseDynamicLinksPlugin { NSObject *_binaryMessenger; - NSMutableDictionary *_eventChannels; - NSMutableDictionary *_streamHandlers; } #pragma mark - FlutterPlugin -- (instancetype)init:(NSObject *)messenger { +- (instancetype)init:(NSObject *)messenger withChannel:(FlutterMethodChannel *)channel { self = [super init]; if (self) { [[FLTFirebasePluginRegistry sharedInstance] registerFirebasePlugin:self]; _binaryMessenger = messenger; - _eventChannels = [NSMutableDictionary dictionary]; - _streamHandlers = [NSMutableDictionary dictionary]; + _channel = channel; } return self; } @@ -82,7 +78,7 @@ + (void)registerWithRegistrar:(NSObject *)registrar { [FlutterMethodChannel methodChannelWithName:kFLTFirebaseDynamicLinksChannelName binaryMessenger:[registrar messenger]]; FLTFirebaseDynamicLinksPlugin *instance = - [[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger]; + [[FLTFirebaseDynamicLinksPlugin alloc] init:registrar.messenger withChannel:channel]; [registrar addMethodCallDelegate:instance channel:channel]; @@ -96,15 +92,6 @@ + (void)registerWithRegistrar:(NSObject *)registrar { } - (void)cleanupWithCompletion:(void (^)(void))completion { - for (FlutterEventChannel *channel in self->_eventChannels.allValues) { - [channel setStreamHandler:nil]; - } - [self->_eventChannels removeAllObjects]; - for (NSObject *handler in self->_streamHandlers.allValues) { - [handler onCancelWithArguments:nil]; - } - [self->_streamHandlers removeAllObjects]; - if (completion != nil) completion(); } @@ -159,8 +146,6 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result [self getInitialLink:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { [self getDynamicLink:call.arguments withMethodCallResult:methodCallResult]; - } else if ([@"FirebaseDynamicLinks#onLink" isEqualToString:call.method]) { - [self registerOnLinkListener:call.arguments withMethodCallResult:methodCallResult]; } else { result(FlutterMethodNotImplemented); } @@ -261,13 +246,17 @@ - (BOOL)application:(UIApplication *)application void (^__block __weak weakCompletionBlock)(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error); - weakCompletionBlock = completionBlock = ^(FIRDynamicLink *_Nullable dynamicLink, NSError *_Nullable error) { if (!error && dynamicLink && dynamicLink.url) { [self onDeepLinkResult:dynamicLink error:nil]; } + if(!error && dynamicLink && !dynamicLink.url){ + NSLog(@"FLTFirebaseDynamicLinks: The url has not been supplied with the dynamic link." + @"Please try opening your app with the long dynamic link to see if that works" + ); + } // Per Apple Tech Support, a network failure could occur when returning from background on // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 // So we'll retry the request once @@ -279,7 +268,7 @@ - (BOOL)application:(UIApplication *)application } if (error && retried) { - // Need to update any stream listener the universal link failed + // Need to update any event channel the universal link failed [self onDeepLinkResult:nil error:error]; } }; @@ -300,23 +289,6 @@ - (void)checkForDynamicLink:(NSURL *)url { } } -- (void)registerOnLinkListener:(id)arguments - withMethodCallResult:(FLTFirebaseMethodCallResult *)result { - NSString *name = [NSString - stringWithFormat:@"%@/get-link/%@", kFLTFirebaseDynamicLinksChannelName, kDefaultAppName]; - - FlutterEventChannel *channel = [FlutterEventChannel eventChannelWithName:name - binaryMessenger:_binaryMessenger]; - - FLTOnLinkStreamHandler *handler = [[FLTOnLinkStreamHandler alloc] init]; - [channel setStreamHandler:handler]; - - [_eventChannels setObject:channel forKey:name]; - [_streamHandlers setObject:handler forKey:name]; - - result.success(name); -} - // Used to action events from firebase-ios-sdk custom & universal dynamic link event listeners - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError *_Nullable)error { if (error) { @@ -337,18 +309,10 @@ - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError * @"link: %@", flutterError); - for (id key in _streamHandlers) { - FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; - [eventHandler sinkEvent:flutterError]; - } - + [_channel invokeMethod:@"FirebaseDynamicLink#onLinkError" arguments:flutterError]; } else { NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); - - for (id key in _streamHandlers) { - FLTOnLinkStreamHandler *eventHandler = [_streamHandlers objectForKey:key]; - [eventHandler sinkEvent:dictionary]; - } + [_channel invokeMethod:@"FirebaseDynamicLink#onLinkSuccess" arguments:dictionary]; } if (_initialLink == nil && dynamicLink.url != nil) { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m deleted file mode 100644 index eca0bfa90f1c..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTOnLinkStreamHandler.m +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "Private/FLTOnLinkStreamHandler.h" -#import "Public/FLTFirebaseDynamicLinksPlugin.h" - -@implementation FLTOnLinkStreamHandler { - FlutterEventSink events; -} - -- (instancetype)init { - self = [super init]; - - return self; -} - -- (void)sinkEvent:(id)event { - // Can be data or error - events(event); -} - -- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventHandler { - events = eventHandler; - - return nil; -} - -- (FlutterError *)onCancelWithArguments:(id)arguments { - // Do nothing - return nil; -} - -@end diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 31aa908670e9..ea03ef5e1397 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -16,7 +16,24 @@ import 'utils/exception.dart'; class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { /// Create an instance of [MethodChannelFirebaseDynamicLinks] with optional [FirebaseApp] MethodChannelFirebaseDynamicLinks({FirebaseApp? app}) - : super(appInstance: app); + : super(appInstance: app) { + channel.setMethodCallHandler((MethodCall call) async { + switch (call.method) { + case 'FirebaseDynamicLink#onLinkSuccess': + Map event = + Map.from(call.arguments); + _onLinkController.add(getPendingDynamicLinkDataFromMap(event)); + break; + case 'FirebaseDynamicLink#onLinkError': + Map error = + Map.from(call.arguments); + _onLinkController.addError(convertPlatformException(error)); + break; + default: + throw UnimplementedError('${call.method} has not been implemented'); + } + }); + } /// The [FirebaseApp] instance to which this [FirebaseDynamicLinks] belongs. /// @@ -27,13 +44,9 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'plugins.flutter.io/firebase_dynamic_links', ); - /// The [EventChannel] used for onLink - static EventChannel onLinkChannel(String name) { - return EventChannel( - name, - channel.codec, - ); - } + /// The [StreamController] used to update on the latest dynamic link received. + final StreamController _onLinkController = + StreamController.broadcast(); /// Gets a [FirebaseDynamicLinksPlatform] with specific arguments such as a different /// [FirebaseApp]. @@ -111,33 +124,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Stream onLink() { - StreamSubscription? snapshotStream; - late StreamController - controller; // ignore: close_sinks - - controller = StreamController.broadcast( - onListen: () async { - // ignore: cast_nullable_to_non_nullable - String name = await channel.invokeMethod( - 'FirebaseDynamicLinks#onLink', - _withChannelDefaults({}), - ) as String; - final events = onLinkChannel(name); - snapshotStream = events.receiveBroadcastStream().listen( - (event) { - controller.add(getPendingDynamicLinkDataFromMap(event)); - }, - onError: (error, stack) { - controller.addError(convertPlatformException(error), stack); - }, - ); - }, - onCancel: () { - snapshotStream?.cancel(); - }, - ); - - return controller.stream; + return _onLinkController.stream; } @override From 143aa0e33e26e229a2b9cdb4536c5f3e5859db59 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 16:12:57 +0000 Subject: [PATCH 070/125] chore(dynamic_link): update example --- .../example/lib/main.dart | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 3355364019e5..24e947189651 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -14,15 +14,16 @@ import 'package:url_launcher/url_launcher.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', - appId: '1:448618578101:ios:4cd06f56e36384acac3efc', - messagingSenderId: '448618578101', - projectId: 'react-native-firebase-testing', - authDomain: 'react-native-firebase-testing.firebaseapp.com', - iosClientId: - '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', - )); + options: const FirebaseOptions( + apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', + appId: '1:448618578101:ios:4cd06f56e36384acac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + ), + ); runApp(MaterialApp( title: 'Dynamic Links Example', routes: { @@ -79,17 +80,17 @@ class _MainScreenState extends State<_MainScreen> { }); final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://cx4k7.app.goo.gl', - link: Uri.parse('https://dynamic.link.example/helloworld'), + uriPrefix: 'https://reactnativefirebase.page.link', + link: Uri.parse('https://invertase.io/helloworld'), androidParameters: const AndroidParameters( - packageName: 'io.flutter.plugins.firebasedynamiclinksexample', + packageName: 'io.flutter.plugins.firebase.dynamiclinksexample', minimumVersion: 0, ), dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), iosParameters: const IosParameters( - bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev', + bundleId: 'io.invertase.testing', minimumVersion: '0', ), ); From 9eef0fe180f8ccb057bda674d3811e5b363903b4 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 16:18:43 +0000 Subject: [PATCH 071/125] format --- .../FlutterFirebaseDynamicLinksPlugin.java | 197 +++++++++--------- .../example/lib/main.dart | 2 +- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 8 +- 3 files changed, 100 insertions(+), 107 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index cdf7cd2ecd2f..c8b535756cee 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -7,10 +7,8 @@ import android.app.Activity; import android.content.Intent; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.google.android.gms.tasks.Task; import com.google.android.gms.tasks.Tasks; import com.google.firebase.FirebaseApp; @@ -18,38 +16,32 @@ import com.google.firebase.dynamiclinks.FirebaseDynamicLinks; import com.google.firebase.dynamiclinks.PendingDynamicLinkData; import com.google.firebase.dynamiclinks.ShortDynamicLink; - import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.EventChannel.StreamHandler; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.PluginRegistry.NewIntentListener; import io.flutter.plugins.firebase.core.FlutterFirebasePlugin; import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; public class FlutterFirebaseDynamicLinksPlugin - implements FlutterFirebasePlugin, - FlutterPlugin, - ActivityAware, - MethodCallHandler, - NewIntentListener { + implements FlutterFirebasePlugin, + FlutterPlugin, + ActivityAware, + MethodCallHandler, + NewIntentListener { private final AtomicReference activity = new AtomicReference<>(null); private MethodChannel channel; - @Nullable - private BinaryMessenger messenger; + @Nullable private BinaryMessenger messenger; private static final String METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_dynamic_links"; @@ -114,16 +106,17 @@ static FirebaseDynamicLinks getDynamicLinkInstance(@Nullable Map @Override public boolean onNewIntent(Intent intent) { getDynamicLinkInstance(null) - .getDynamicLink(intent) - .addOnSuccessListener( - pendingDynamicLinkData -> { - Map dynamicLink = - Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - channel.invokeMethod("FirebaseDynamicLink#onLinkSuccess", dynamicLink); - }) - .addOnFailureListener( - exception -> - channel.invokeMethod("FirebaseDynamicLink#onLinkError", Utils.getExceptionDetails(exception))); + .getDynamicLink(intent) + .addOnSuccessListener( + pendingDynamicLinkData -> { + Map dynamicLink = + Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); + channel.invokeMethod("FirebaseDynamicLink#onLinkSuccess", dynamicLink); + }) + .addOnFailureListener( + exception -> + channel.invokeMethod( + "FirebaseDynamicLink#onLinkError", Utils.getExceptionDetails(exception))); return false; } @@ -156,17 +149,17 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re } methodCallTask.addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - result.success(task.getResult()); - } else { - Exception exception = task.getException(); - result.error( - Constants.DEFAULT_ERROR_CODE, - exception != null ? exception.getMessage() : null, - io.flutter.plugins.firebase.dynamiclinks.Utils.getExceptionDetails(exception)); - } - }); + task -> { + if (task.isSuccessful()) { + result.success(task.getResult()); + } else { + Exception exception = task.getException(); + result.error( + Constants.DEFAULT_ERROR_CODE, + exception != null ? exception.getMessage() : null, + io.flutter.plugins.firebase.dynamiclinks.Utils.getExceptionDetails(exception)); + } + }); } private String buildUrl(Map arguments) { @@ -176,74 +169,74 @@ private String buildUrl(Map arguments) { } private Task> buildShortLink( - DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { + DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { return Tasks.call( - cachedThreadPool, - () -> { - Integer suffix = null; - if (dynamicLinkParametersOptions != null) { - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); - if (shortDynamicLinkPathLength != null) { - switch (shortDynamicLinkPathLength) { - case 0: - suffix = ShortDynamicLink.Suffix.UNGUESSABLE; - break; - case 1: - suffix = ShortDynamicLink.Suffix.SHORT; - break; - default: - break; + cachedThreadPool, + () -> { + Integer suffix = null; + if (dynamicLinkParametersOptions != null) { + Integer shortDynamicLinkPathLength = + (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); + if (shortDynamicLinkPathLength != null) { + switch (shortDynamicLinkPathLength) { + case 0: + suffix = ShortDynamicLink.Suffix.UNGUESSABLE; + break; + case 1: + suffix = ShortDynamicLink.Suffix.SHORT; + break; + default: + break; + } } } - } - Map result = new HashMap<>(); - ShortDynamicLink shortLink; - if (suffix != null) { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); - } else { - shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); - } + Map result = new HashMap<>(); + ShortDynamicLink shortLink; + if (suffix != null) { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink(suffix)); + } else { + shortLink = Tasks.await(urlBuilder.buildShortDynamicLink()); + } - List warnings = new ArrayList<>(); + List warnings = new ArrayList<>(); - for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { - warnings.add(warning.getMessage()); - } + for (ShortDynamicLink.Warning warning : shortLink.getWarnings()) { + warnings.add(warning.getMessage()); + } - result.put("url", shortLink.getShortLink().toString()); - result.put("warnings", warnings); - result.put("previewLink", shortLink.getPreviewLink().toString()); + result.put("url", shortLink.getShortLink().toString()); + result.put("warnings", warnings); + result.put("previewLink", shortLink.getPreviewLink().toString()); - return result; - }); + return result; + }); } private Task> getDynamicLink( - FirebaseDynamicLinks dynamicLinks, @Nullable String url) { + FirebaseDynamicLinks dynamicLinks, @Nullable String url) { return Tasks.call( - cachedThreadPool, - () -> { - PendingDynamicLinkData pendingDynamicLink; - - if (url != null) { - pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); - } else { - // If there's no activity or initial Intent, then there's no initial dynamic link. - if (activity.get() == null || activity.get().getIntent() == null) { - return null; + cachedThreadPool, + () -> { + PendingDynamicLinkData pendingDynamicLink; + + if (url != null) { + pendingDynamicLink = Tasks.await(dynamicLinks.getDynamicLink(Uri.parse(url))); + } else { + // If there's no activity or initial Intent, then there's no initial dynamic link. + if (activity.get() == null || activity.get().getIntent() == null) { + return null; + } + pendingDynamicLink = + Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } - pendingDynamicLink = - Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); - } - if (pendingDynamicLink == null) { - return null; - } + if (pendingDynamicLink == null) { + return null; + } - return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); - }); + return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); + }); } private DynamicLink.Builder setupParameters(Map arguments) { @@ -256,14 +249,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { dynamicLinkBuilder.setLink(Uri.parse(link)); Map androidParameters = - (Map) arguments.get("androidParameters"); + (Map) arguments.get("androidParameters"); if (androidParameters != null) { String packageName = valueFor("packageName", androidParameters); String fallbackUrl = valueFor("fallbackUrl", androidParameters); Integer minimumVersion = valueFor("minimumVersion", androidParameters); DynamicLink.AndroidParameters.Builder builder = - new DynamicLink.AndroidParameters.Builder(packageName); + new DynamicLink.AndroidParameters.Builder(packageName); if (fallbackUrl != null) builder.setFallbackUrl(Uri.parse(fallbackUrl)); if (minimumVersion != null) builder.setMinimumVersion(minimumVersion); @@ -272,7 +265,7 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map googleAnalyticsParameters = - (Map) arguments.get("googleAnalyticsParameters"); + (Map) arguments.get("googleAnalyticsParameters"); if (googleAnalyticsParameters != null) { String campaign = valueFor("campaign", googleAnalyticsParameters); String content = valueFor("content", googleAnalyticsParameters); @@ -281,7 +274,7 @@ private DynamicLink.Builder setupParameters(Map arguments) { String term = valueFor("term", googleAnalyticsParameters); DynamicLink.GoogleAnalyticsParameters.Builder builder = - new DynamicLink.GoogleAnalyticsParameters.Builder(); + new DynamicLink.GoogleAnalyticsParameters.Builder(); if (campaign != null) builder.setCampaign(campaign); if (content != null) builder.setContent(content); @@ -315,14 +308,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map itunesConnectAnalyticsParameters = - (Map) arguments.get("itunesConnectAnalyticsParameters"); + (Map) arguments.get("itunesConnectAnalyticsParameters"); if (itunesConnectAnalyticsParameters != null) { String affiliateToken = valueFor("affiliateToken", itunesConnectAnalyticsParameters); String campaignToken = valueFor("campaignToken", itunesConnectAnalyticsParameters); String providerToken = valueFor("providerToken", itunesConnectAnalyticsParameters); DynamicLink.ItunesConnectAnalyticsParameters.Builder builder = - new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); + new DynamicLink.ItunesConnectAnalyticsParameters.Builder(); if (affiliateToken != null) builder.setAffiliateToken(affiliateToken); if (campaignToken != null) builder.setCampaignToken(campaignToken); @@ -332,12 +325,12 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map navigationInfoParameters = - (Map) arguments.get("navigationInfoParameters"); + (Map) arguments.get("navigationInfoParameters"); if (navigationInfoParameters != null) { Boolean forcedRedirectEnabled = valueFor("forcedRedirectEnabled", navigationInfoParameters); DynamicLink.NavigationInfoParameters.Builder builder = - new DynamicLink.NavigationInfoParameters.Builder(); + new DynamicLink.NavigationInfoParameters.Builder(); if (forcedRedirectEnabled != null) builder.setForcedRedirectEnabled(forcedRedirectEnabled); @@ -345,14 +338,14 @@ private DynamicLink.Builder setupParameters(Map arguments) { } Map socialMetaTagParameters = - (Map) arguments.get("socialMetaTagParameters"); + (Map) arguments.get("socialMetaTagParameters"); if (socialMetaTagParameters != null) { String description = valueFor("description", socialMetaTagParameters); String imageUrl = valueFor("imageUrl", socialMetaTagParameters); String title = valueFor("title", socialMetaTagParameters); DynamicLink.SocialMetaTagParameters.Builder builder = - new DynamicLink.SocialMetaTagParameters.Builder(); + new DynamicLink.SocialMetaTagParameters.Builder(); if (description != null) builder.setDescription(description); if (imageUrl != null) builder.setImageUrl(Uri.parse(imageUrl)); @@ -378,9 +371,9 @@ public Task> getPluginConstantsForFirebaseApp(FirebaseApp fi @Override public Task didReinitializeFirebaseCore() { return Tasks.call( - cachedThreadPool, - () -> { - return null; - }); + cachedThreadPool, + () -> { + return null; + }); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 24e947189651..27195c266fd6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -21,7 +21,7 @@ Future main() async { projectId: 'react-native-firebase-testing', authDomain: 'react-native-firebase-testing.firebaseapp.com', iosClientId: - '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', + '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', ), ); runApp(MaterialApp( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 15c2f3439425..ac2d7a32934a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -64,7 +64,8 @@ @implementation FLTFirebaseDynamicLinksPlugin { #pragma mark - FlutterPlugin -- (instancetype)init:(NSObject *)messenger withChannel:(FlutterMethodChannel *)channel { +- (instancetype)init:(NSObject *)messenger + withChannel:(FlutterMethodChannel *)channel { self = [super init]; if (self) { [[FLTFirebasePluginRegistry sharedInstance] registerFirebasePlugin:self]; @@ -252,10 +253,9 @@ - (BOOL)application:(UIApplication *)application [self onDeepLinkResult:dynamicLink error:nil]; } - if(!error && dynamicLink && !dynamicLink.url){ + if (!error && dynamicLink && !dynamicLink.url) { NSLog(@"FLTFirebaseDynamicLinks: The url has not been supplied with the dynamic link." - @"Please try opening your app with the long dynamic link to see if that works" - ); + @"Please try opening your app with the long dynamic link to see if that works"); } // Per Apple Tech Support, a network failure could occur when returning from background on // iOS 12. https://github.com/AFNetworking/AFNetworking/issues/4279#issuecomment-447108981 From 2eaf222574662c4c62572209760fb28941a45777 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 16:45:36 +0000 Subject: [PATCH 072/125] test(dynamic_links): update todo --- .../method_channel_firebase_dynamic_links_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index 16950831dd33..a3e533fa0d79 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -101,8 +101,8 @@ void main() { return returnUrl; case 'FirebaseDynamicLinks#shortenUrl': return returnUrl; - case 'FirebaseDynamicLinks#onLink': - const String name = 'FirebaseDynamicLinks#onLink'; + case 'FirebaseDynamicLink#onLinkSuccess': + const String name = 'FirebaseDynamicLink#onLinkSuccess'; handleEventChannel(name, logger); return name; case 'FirebaseDynamicLinks#getInitialLink': @@ -354,7 +354,7 @@ void main() { // Stream stream = // dynamicLinks.onLink().asBroadcastStream(); // - // await injectEventChannelResponse('FirebaseDynamicLinks#onLink', { + // await injectEventChannelResponse('FirebaseDynamicLink#onLinkSuccess', { // 'link': 'link', // 'ios': {'minimumVersion': 'minimumVersion'} // }); From 28245bfb7af546e088d8ceaec5aa0dc90527952d Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 16:50:34 +0000 Subject: [PATCH 073/125] chore(dynamic_links, android): app manifest --- .../example/android/app/src/main/AndroidManifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml index 3906eecd9efa..3609fff1be49 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,5 @@ + package="io.flutter.plugins.firebase.dynamiclinksexample"> From c0c304445eee8187f0fdbda132018028918f1af4 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 17 Nov 2021 19:54:42 +0000 Subject: [PATCH 074/125] chore: rm android warning --- .../dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java | 4 ---- .../java/io/flutter/plugins/firebase/dynamiclinks/Utils.java | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index c8b535756cee..e31c47571196 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -231,10 +231,6 @@ private Task> getDynamicLink( Tasks.await(dynamicLinks.getDynamicLink(activity.get().getIntent())); } - if (pendingDynamicLink == null) { - return null; - } - return Utils.getMapFromPendingDynamicLinkData(pendingDynamicLink); }); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java index e241c7e0ac5e..f72826a58b2b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java @@ -22,6 +22,10 @@ static Map getExceptionDetails(@Nullable Exception exception) { static Map getMapFromPendingDynamicLinkData( PendingDynamicLinkData pendingDynamicLinkData) { + if(pendingDynamicLinkData == null){ + return null; + } + Map dynamicLink = new HashMap<>(); Uri link = pendingDynamicLinkData.getLink(); From 6e8ce086c1bc6248cd442f7c0d789fcc77f56384 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 08:47:53 +0000 Subject: [PATCH 075/125] chore(dynamic_links, ios): add GoogleService-Info.plist --- .../example/ios/GoogleService-Info.plist | 38 +++++++++++++++++++ .../ios/Runner.xcodeproj/project.pbxproj | 4 ++ 2 files changed, 42 insertions(+) create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/GoogleService-Info.plist diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/GoogleService-Info.plist b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/GoogleService-Info.plist new file mode 100644 index 000000000000..0c11fd920572 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/GoogleService-Info.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 448618578101-4km55qmv55tguvnivgjdiegb3r0jquv5.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.448618578101-4km55qmv55tguvnivgjdiegb3r0jquv5 + ANDROID_CLIENT_ID + 448618578101-26jgjs0rtl4ts2i667vjb28kldvs2kp6.apps.googleusercontent.com + API_KEY + AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0 + GCM_SENDER_ID + 448618578101 + PLIST_VERSION + 1 + BUNDLE_ID + io.invertase.testing + PROJECT_ID + react-native-firebase-testing + STORAGE_BUCKET + react-native-firebase-testing.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:448618578101:ios:3e76955ab6d49ecaac3efc + DATABASE_URL + https://react-native-firebase-testing.firebaseio.com + + diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj index 7a5983ce5725..97e00a42ac00 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/ios/Runner.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 46EC2B98274648FE00B16F88 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 46EC2B97274648FE00B16F88 /* GoogleService-Info.plist */; }; 8FF283695FD42FAFAA6F2588 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; @@ -39,6 +40,7 @@ 23C87C2196BFAAA7E465A745 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3BEA489D8A0A4C9E6F14F37D /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 46EC2B97274648FE00B16F88 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -79,6 +81,7 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + 46EC2B97274648FE00B16F88 /* GoogleService-Info.plist */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, @@ -212,6 +215,7 @@ 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + 46EC2B98274648FE00B16F88 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 16257a48cf01a3dd202793a94b6abd30c9b84d0b Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 08:49:48 +0000 Subject: [PATCH 076/125] chore(dynamic_links): Update example app --- .../example/lib/main.dart | 75 +++++++++++++------ 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 27195c266fd6..6fa572488c20 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -4,6 +4,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:io' show Platform; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; @@ -13,17 +14,24 @@ import 'package:url_launcher/url_launcher.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: const FirebaseOptions( - apiKey: 'AIzaSyCuu4tbv9CwwTudNOweMNstzZHIDBhgJxA', - appId: '1:448618578101:ios:4cd06f56e36384acac3efc', - messagingSenderId: '448618578101', - projectId: 'react-native-firebase-testing', - authDomain: 'react-native-firebase-testing.firebaseapp.com', - iosClientId: - '448618578101-m53gtqfnqipj12pts10590l37npccd2r.apps.googleusercontent.com', - ), - ); + if (Platform.isAndroid) { + // Android will work via Dart initialisation + await Firebase.initializeApp( + options: const FirebaseOptions( + apiKey: 'AIzaSyAHAsf51D0A407EklG1bs-5wA7EbyfNFg0', + appId: '1:448618578101:ios:3e76955ab6d49ecaac3efc', + messagingSenderId: '448618578101', + projectId: 'react-native-firebase-testing', + authDomain: 'react-native-firebase-testing.firebaseapp.com', + iosClientId: + '448618578101-4km55qmv55tguvnivgjdiegb3r0jquv5.apps.googleusercontent.com', + ), + ); + } else { + // iOS requires that there is a GoogleService-Inof.plist otherwise getInitialLink & getDynamicLink will not work correctly. + // iOS also requires you run in release mode to test dynamic links ("flutter run --release"). + await Firebase.initializeApp(); + } runApp(MaterialApp( title: 'Dynamic Links Example', routes: { @@ -43,12 +51,14 @@ class _MainScreenState extends State<_MainScreen> { bool _isCreatingLink = false; FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; - String _testString = + final String _testString = 'To test: long press link and then copy and click from a non-browser ' "app. Make sure this isn't being tested on iOS simulator and iOS xcode " 'is properly setup. Look at firebase_dynamic_links/README.md for more ' 'details.'; + final String DynamicLink = 'https://test-app/helloworld'; + @override void initState() { super.initState(); @@ -57,21 +67,13 @@ class _MainScreenState extends State<_MainScreen> { Future initDynamicLinks() async { dynamicLinks.onLink().listen((dynamicLinkData) { - if (dynamicLinkData != null) { + if (dynamicLinkData != null && dynamicLinkData.link != null) { Navigator.pushNamed(context, dynamicLinkData.link.path); } }).onError((error) { print('onLink error'); print(error.message); }); - - final PendingDynamicLinkData? data = await dynamicLinks.getInitialLink(); - final Uri? deepLink = data?.link; - - if (deepLink != null) { - // ignore: unawaited_futures - Navigator.pushNamed(context, deepLink.path); - } } Future _createDynamicLink(bool short) async { @@ -81,7 +83,7 @@ class _MainScreenState extends State<_MainScreen> { final DynamicLinkParameters parameters = DynamicLinkParameters( uriPrefix: 'https://reactnativefirebase.page.link', - link: Uri.parse('https://invertase.io/helloworld'), + link: Uri.parse(DynamicLink), androidParameters: const AndroidParameters( packageName: 'io.flutter.plugins.firebase.dynamiclinksexample', minimumVersion: 0, @@ -125,6 +127,35 @@ class _MainScreenState extends State<_MainScreen> { ButtonBar( alignment: MainAxisAlignment.center, children: [ + ElevatedButton( + onPressed: () async { + // comment out the above onLink() event listener to test `getInitialLink()` when your app is first opened pressing + // the dynamic link. + final PendingDynamicLinkData? data = + await dynamicLinks.getInitialLink(); + final Uri? deepLink = data?.link; + + if (deepLink != null) { + // ignore: unawaited_futures + Navigator.pushNamed(context, deepLink.path); + } + }, + child: const Text('getInitialLink')), + ElevatedButton( + onPressed: () async { + // comment out the above onLink() event listener to test `getDynamicLink(url)` when your app is first opened pressing + // the dynamic link. + final PendingDynamicLinkData? data = + await dynamicLinks + .getDynamicLink(Uri.parse(DynamicLink)); + final Uri? deepLink = data?.link; + + if (deepLink != null) { + // ignore: unawaited_futures + Navigator.pushNamed(context, deepLink.path); + } + }, + child: const Text('getInitialLink')), ElevatedButton( onPressed: !_isCreatingLink ? () => _createDynamicLink(false) From ce4fc0cceaa709d873f0c834d2fa8cc47f210e19 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 08:49:58 +0000 Subject: [PATCH 077/125] formatting --- .../java/io/flutter/plugins/firebase/dynamiclinks/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java index f72826a58b2b..fc29ca8a2a55 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java @@ -22,7 +22,7 @@ static Map getExceptionDetails(@Nullable Exception exception) { static Map getMapFromPendingDynamicLinkData( PendingDynamicLinkData pendingDynamicLinkData) { - if(pendingDynamicLinkData == null){ + if (pendingDynamicLinkData == null) { return null; } From edc156fd5250d560158a79bbad8e2a27a290bf84 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 08:56:51 +0000 Subject: [PATCH 078/125] chore: analyze issue --- .../firebase_dynamic_links/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 6fa572488c20..54e8cb3b5c05 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -67,7 +67,7 @@ class _MainScreenState extends State<_MainScreen> { Future initDynamicLinks() async { dynamicLinks.onLink().listen((dynamicLinkData) { - if (dynamicLinkData != null && dynamicLinkData.link != null) { + if (dynamicLinkData != null) { Navigator.pushNamed(context, dynamicLinkData.link.path); } }).onError((error) { From de3af481399f405b2a55665857893ae537cbda04 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 09:03:32 +0000 Subject: [PATCH 079/125] chore: name --- .../firebase_dynamic_links/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 54e8cb3b5c05..cb38cceb2b47 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -155,7 +155,7 @@ class _MainScreenState extends State<_MainScreen> { Navigator.pushNamed(context, deepLink.path); } }, - child: const Text('getInitialLink')), + child: const Text('getDynamicLink')), ElevatedButton( onPressed: !_isCreatingLink ? () => _createDynamicLink(false) From 98832725dfff0f9c50d3e7967aa817847bdf803e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:21:33 +0000 Subject: [PATCH 080/125] chore(dynamic_links): update license headers --- .../dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java | 2 +- .../java/io/flutter/plugins/firebase/dynamiclinks/Utils.java | 4 ++++ .../firebase_dynamic_links/example/lib/main.dart | 1 - .../ios/Classes/Private/FLTOnLinkStreamHandler.h | 2 -- .../ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h | 2 +- .../test/firebase_dynamic_links_test.dart | 1 - .../firebase_dynamic_links_platform_interface/LICENSE | 2 +- .../lib/src/android_parameters.dart | 4 ++++ .../lib/src/dynamic_link.dart | 4 ++++ .../lib/src/dynamic_link_parameter_options.dart | 4 ++++ .../lib/src/google_analytics_parameters.dart | 4 ++++ .../lib/src/ios_parameters.dart | 4 ++++ .../lib/src/itunes_connect_analytics_parameters.dart | 4 ++++ .../lib/src/navigation_info_parameters.dart | 4 ++++ .../lib/src/pending_dynamic_link_data.dart | 4 ++++ .../lib/src/pending_dynamic_link_data_android.dart | 4 ++++ .../lib/src/pending_dynamic_link_data_ios.dart | 4 ++++ .../lib/src/short_dynamic_link.dart | 4 ++++ .../lib/src/short_dynamic_link_path_length.dart | 4 ++++ .../lib/src/social_meta_tag_parameters.dart | 4 ++++ .../test/dynamic_link_parameters_test.dart | 1 - 21 files changed, 59 insertions(+), 8 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index e31c47571196..78e9d34f78e1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java index fc29ca8a2a55..78ca8670c922 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/Utils.java @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + package io.flutter.plugins.firebase.dynamiclinks; import android.net.Uri; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index cb38cceb2b47..7f9e897223e2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h index 815a297f969a..a4c5f3c7b513 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h @@ -1,5 +1,3 @@ - - // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h index f804938594f6..416f974f7c44 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 4a3d8d6ebc0c..e5a54432811b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE index 5b8ff6261110..e8a438415fb0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/LICENSE @@ -1,4 +1,4 @@ -Copyright 2017, the Chromium project authors. All rights reserved. +Copyright 2021, the Chromium project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart index 25f76f830e68..96b0ccd24788 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/android_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// The Dynamic Link Android parameters. class AndroidParameters { const AndroidParameters({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart index c47944683ae0..ca0e93293725 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// Response from creating a dynamic link with [DynamicLinkBuilder]. class DynamicLink { const DynamicLink({required this.url}); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart index 1bfaf4f5bdc8..7d91428e8ed0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'short_dynamic_link_path_length.dart'; /// Options class for defining how Dynamic Link URLs are generated. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart index e2b6927f0c3e..adaddcfba1d8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// The Dynamic Link analytics parameters. class GoogleAnalyticsParameters { const GoogleAnalyticsParameters({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart index 0a54273797a5..0853003192d4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// The Dynamic Link iOS parameters. class IosParameters { const IosParameters({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart index 9e7ae63a9b99..d660c4b62a7d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// The Dynamic Link iTunes Connect parameters. class ItunesConnectAnalyticsParameters { const ItunesConnectAnalyticsParameters({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart index db98a91943e5..a9a499d58682 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/navigation_info_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// Options class for defining navigation behavior of the Dynamic Link. class NavigationInfoParameters { const NavigationInfoParameters({this.forcedRedirectEnabled}); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart index e294db053cb8..512d4bd39871 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'pending_dynamic_link_data_android.dart'; import 'pending_dynamic_link_data_ios.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart index 272f9f70b7e4..3fb14e061d35 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_android.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// Provides android specific data from received dynamic link. class PendingDynamicLinkDataAndroid { const PendingDynamicLinkDataAndroid({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart index 30789ed6dff7..6dde7dcfd23b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// Provides iOS specific data from received dynamic link. class PendingDynamicLinkDataIOS { const PendingDynamicLinkDataIOS({this.minimumVersion}); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index 853b6cee8a79..350a2dd44682 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// Response from creating a short dynamic link with [DynamicLinkBuilder]. class ShortDynamicLink { const ShortDynamicLink({ diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart index 5d04fc6e7fcc..5629090caac4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart @@ -1,2 +1,6 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// For specifying length for short Dynamic Links. enum ShortDynamicLinkPathLength { unguessable, short } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart index 87c581522ac1..46a8fbca9890 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/social_meta_tag_parameters.dart @@ -1,3 +1,7 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + /// The Dynamic Link Social Meta Tag parameters. class SocialMetaTagParameters { const SocialMetaTagParameters({this.description, this.imageUrl, this.title}); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index f68e62c3f5f7..cd5339ed39a7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -1,4 +1,3 @@ -// ignore_for_file: require_trailing_commas // Copyright 2021, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. From 34e71ed6943c5a1755103244dd578cb3bdc12e50 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:29:21 +0000 Subject: [PATCH 081/125] chore(dynamic_links): rm required necessity for params --- .../lib/src/google_analytics_parameters.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart index adaddcfba1d8..3c4d34e0c78e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/google_analytics_parameters.dart @@ -5,10 +5,10 @@ /// The Dynamic Link analytics parameters. class GoogleAnalyticsParameters { const GoogleAnalyticsParameters({ - required String this.campaign, + this.campaign, this.content, - required String this.medium, - required String this.source, + this.medium, + this.source, this.term, }); From fc30145371efef827975b8630fc45cafa5c958f1 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:31:37 +0000 Subject: [PATCH 082/125] chore(dynamic_links): rename class --- .../lib/firebase_dynamic_links.dart | 2 +- .../test/firebase_dynamic_links_test.dart | 4 ++-- .../lib/src/dynamic_link_parameters.dart | 2 +- .../lib/src/itunes_connect_analytics_parameters.dart | 6 +++--- .../test/dynamic_link_parameters_test.dart | 4 ++-- .../test/itunes_connect_analytics_parameters_test.dart | 10 +++++----- .../method_channel_firebase_dynamic_links_test.dart | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 744d97a77f84..6ba52674d1c9 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -16,7 +16,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links FirebaseDynamicLinksPlatform, GoogleAnalyticsParameters, IosParameters, - ItunesConnectAnalyticsParameters, + ITunesConnectAnalyticsParameters, NavigationInfoParameters, PendingDynamicLinkData, PendingDynamicLinkDataAndroid, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index e5a54432811b..d4343e347956 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -38,8 +38,8 @@ DynamicLinkParameters buildDynamicLinkParameters() { ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), minimumVersion: 'minimumVersion'); - ItunesConnectAnalyticsParameters itunes = - const ItunesConnectAnalyticsParameters( + ITunesConnectAnalyticsParameters itunes = + const ITunesConnectAnalyticsParameters( affiliateToken: 'affiliateToken', campaignToken: 'campaignToken', providerToken: 'providerToken', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index add65f47d1be..27a7ccc361bb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -42,7 +42,7 @@ class DynamicLinkParameters { final IosParameters? iosParameters; /// iTunes Connect parameters for a generated Dynamic Link URL. - final ItunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; + final ITunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; /// The link the target app will open. /// diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart index d660c4b62a7d..595319f63440 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/itunes_connect_analytics_parameters.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. /// The Dynamic Link iTunes Connect parameters. -class ItunesConnectAnalyticsParameters { - const ItunesConnectAnalyticsParameters({ +class ITunesConnectAnalyticsParameters { + const ITunesConnectAnalyticsParameters({ this.affiliateToken, this.campaignToken, this.providerToken, @@ -27,6 +27,6 @@ class ItunesConnectAnalyticsParameters { @override String toString() { - return '$ItunesConnectAnalyticsParameters($asMap)'; + return '$ITunesConnectAnalyticsParameters($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index cd5339ed39a7..d8e4dabdc44a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -28,8 +28,8 @@ void main() { ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), minimumVersion: 'minimumVersion'); - ItunesConnectAnalyticsParameters itunesParams = - const ItunesConnectAnalyticsParameters( + ITunesConnectAnalyticsParameters itunesParams = + const ITunesConnectAnalyticsParameters( affiliateToken: 'affiliateToken', campaignToken: 'campaignToken', providerToken: 'providerToken', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart index 40337d264794..fa208cdd6d5b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/itunes_connect_analytics_parameters_test.dart @@ -10,9 +10,9 @@ void main() { String campaignToken = 'campaignToken'; String providerToken = 'providerToken'; - group('$ItunesConnectAnalyticsParameters', () { - ItunesConnectAnalyticsParameters itunesParams = - ItunesConnectAnalyticsParameters( + group('$ITunesConnectAnalyticsParameters', () { + ITunesConnectAnalyticsParameters itunesParams = + ITunesConnectAnalyticsParameters( affiliateToken: affiliateToken, campaignToken: campaignToken, providerToken: providerToken, @@ -20,7 +20,7 @@ void main() { group('Constructor', () { test('returns an instance of [ItunesConnectAnalyticsParameters]', () { - expect(itunesParams, isA()); + expect(itunesParams, isA()); expect(itunesParams.affiliateToken, affiliateToken); expect(itunesParams.campaignToken, campaignToken); expect(itunesParams.providerToken, providerToken); @@ -40,7 +40,7 @@ void main() { test('toString', () { expect( itunesParams.toString(), - equals('$ItunesConnectAnalyticsParameters(${itunesParams.asMap})'), + equals('$ITunesConnectAnalyticsParameters(${itunesParams.asMap})'), ); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index a3e533fa0d79..e199291671e7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -36,8 +36,8 @@ DynamicLinkParameters buildDynamicLinkParameters() { ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), minimumVersion: 'minimumVersion'); - ItunesConnectAnalyticsParameters itunes = - const ItunesConnectAnalyticsParameters( + ITunesConnectAnalyticsParameters itunes = + const ITunesConnectAnalyticsParameters( affiliateToken: 'affiliateToken', campaignToken: 'campaignToken', providerToken: 'providerToken', From ff8bda1d8d673df449a93a3b85ce048aedb791cd Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:38:57 +0000 Subject: [PATCH 083/125] chore(dynamic_links): setMethodCallHandler; set once --- .../method_channel_firebase_dynamic_links.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index ea03ef5e1397..cf0ecd245c07 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -17,6 +17,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { /// Create an instance of [MethodChannelFirebaseDynamicLinks] with optional [FirebaseApp] MethodChannelFirebaseDynamicLinks({FirebaseApp? app}) : super(appInstance: app) { + if (_initialized) return; + channel.setMethodCallHandler((MethodCall call) async { switch (call.method) { case 'FirebaseDynamicLink#onLinkSuccess': @@ -33,8 +35,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { throw UnimplementedError('${call.method} has not been implemented'); } }); + _initialized = true; } + static bool _initialized = false; + /// The [FirebaseApp] instance to which this [FirebaseDynamicLinks] belongs. /// /// If null, the default [FirebaseApp] is used. From 53a7ddb3d83793d8f0f692b897bb4cb86628b3dd Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:40:20 +0000 Subject: [PATCH 084/125] chore(dynamic_links): _getPendingDynamicLinkDataFromMap; make private --- .../method_channel_firebase_dynamic_links.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index cf0ecd245c07..2721f6411a58 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -24,7 +24,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { case 'FirebaseDynamicLink#onLinkSuccess': Map event = Map.from(call.arguments); - _onLinkController.add(getPendingDynamicLinkDataFromMap(event)); + _onLinkController.add(_getPendingDynamicLinkDataFromMap(event)); break; case 'FirebaseDynamicLink#onLinkError': Map error = @@ -67,7 +67,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { }..addAll(other); } - PendingDynamicLinkData? getPendingDynamicLinkDataFromMap( + PendingDynamicLinkData? _getPendingDynamicLinkDataFromMap( Map? linkData, ) { if (linkData == null) return null; @@ -107,7 +107,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { _withChannelDefaults({}), ); - return getPendingDynamicLinkDataFromMap(linkData); + return _getPendingDynamicLinkDataFromMap(linkData); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); } @@ -121,7 +121,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'FirebaseDynamicLinks#getDynamicLink', _withChannelDefaults({'url': url.toString()}), ); - return getPendingDynamicLinkDataFromMap(linkData); + return _getPendingDynamicLinkDataFromMap(linkData); } on PlatformException catch (e, s) { throw platformExceptionToFirebaseException(e, s); } From 900ac2f1ffe8f3cd79bc34ed5bc20c0dd62cd86f Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:41:30 +0000 Subject: [PATCH 085/125] chore(dynamic_links): update error handling --- .../method_channel_firebase_dynamic_links.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 2721f6411a58..a0ff359cb03d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -108,7 +108,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ); return _getPendingDynamicLinkDataFromMap(linkData); - } on PlatformException catch (e, s) { + } catch (e, s) { throw platformExceptionToFirebaseException(e, s); } } @@ -122,7 +122,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { _withChannelDefaults({'url': url.toString()}), ); return _getPendingDynamicLinkDataFromMap(linkData); - } on PlatformException catch (e, s) { + } catch (e, s) { throw platformExceptionToFirebaseException(e, s); } } @@ -148,7 +148,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { }), ); return _parseShortLink(reply!); - } on PlatformException catch (e, s) { + } catch (e, s) { throw platformExceptionToFirebaseException(e, s); } } @@ -162,7 +162,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { _withChannelDefaults(parameters.asMap()), ); return Uri.parse(url!); - } on PlatformException catch (e, s) { + } catch (e, s) { throw platformExceptionToFirebaseException(e, s); } } @@ -179,7 +179,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { _withChannelDefaults(parameters.asMap()), ); return _parseShortLink(response!); - } on PlatformException catch (e, s) { + } catch (e, s) { throw platformExceptionToFirebaseException(e, s); } } From af7c2237d191d09fd6d7b0061f6542bf4b26d242 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 11:42:54 +0000 Subject: [PATCH 086/125] chore(dynamic_links): update class name: PendingDynamicLinkDataiOS --- .../firebase_dynamic_links/lib/firebase_dynamic_links.dart | 2 +- .../test/firebase_dynamic_links_test.dart | 2 +- .../method_channel_firebase_dynamic_links.dart | 4 ++-- .../lib/src/pending_dynamic_link_data.dart | 2 +- .../lib/src/pending_dynamic_link_data_ios.dart | 6 +++--- .../test/pending_dynamic_link_data_test.dart | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 6ba52674d1c9..d66105e0d445 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -20,7 +20,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links NavigationInfoParameters, PendingDynamicLinkData, PendingDynamicLinkDataAndroid, - PendingDynamicLinkDataIOS, + PendingDynamicLinkDataiOS, ShortDynamicLink, ShortDynamicLinkPathLength, SocialMetaTagParameters; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index d4343e347956..8c5d44adb5f7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -288,7 +288,7 @@ class TestPendingDynamicLinkData extends PendingDynamicLinkData { android: PendingDynamicLinkDataAndroid( clickTimestamp: mockClickTimestamp, minimumVersion: mockMinimumVersionAndroid), - ios: PendingDynamicLinkDataIOS( + ios: PendingDynamicLinkDataiOS( minimumVersion: mockMinimumVersionIOS)); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index a0ff359cb03d..fa7b6f01cdec 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -84,11 +84,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ); } - PendingDynamicLinkDataIOS? iosData; + PendingDynamicLinkDataiOS? iosData; if (linkData['ios'] != null) { final Map data = linkData['ios']; iosData = - PendingDynamicLinkDataIOS(minimumVersion: data['minimumVersion']); + PendingDynamicLinkDataiOS(minimumVersion: data['minimumVersion']); } return PendingDynamicLinkData( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart index 512d4bd39871..e723e70f21d8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -19,7 +19,7 @@ class PendingDynamicLinkData { /// /// Can be null if [link] equals null or dynamic link was not received on an /// iOS device. - final PendingDynamicLinkDataIOS? ios; + final PendingDynamicLinkDataiOS? ios; /// Deep link parameter of the dynamic link. final Uri link; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart index 6dde7dcfd23b..25020d214b2b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. /// Provides iOS specific data from received dynamic link. -class PendingDynamicLinkDataIOS { - const PendingDynamicLinkDataIOS({this.minimumVersion}); +class PendingDynamicLinkDataiOS { + const PendingDynamicLinkDataiOS({this.minimumVersion}); /// The minimum version of your app that can open the link. /// @@ -19,6 +19,6 @@ class PendingDynamicLinkDataIOS { @override String toString() { - return '$PendingDynamicLinkDataIOS($asMap)'; + return '$PendingDynamicLinkDataiOS($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart index 84d7ec326ee0..5b1f9b2186f6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart @@ -14,8 +14,8 @@ void main() { minimumVersion: minimumVersion, clickTimestamp: clickTimestamp, ); - PendingDynamicLinkDataIOS iosData = - PendingDynamicLinkDataIOS(minimumVersion: minimumVersionIos); + PendingDynamicLinkDataiOS iosData = + PendingDynamicLinkDataiOS(minimumVersion: minimumVersionIos); group('$PendingDynamicLinkData', () { PendingDynamicLinkData pendingDynamicLinkData = From 82ddb2cf901d8d573093ed80a8cb712d613a7d9c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 12:10:32 +0000 Subject: [PATCH 087/125] chore(dynamic_links): rm unnecessary prop --- .../platform_interface_firebase_dynamic_links.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index c9192f72253f..a97a8c099261 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -37,7 +37,7 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { /// It will always default to [MethodChannelFirebaseDynamicLinks] /// if no other implementation was provided. static FirebaseDynamicLinksPlatform get instance { - return _instance ??= MethodChannelFirebaseDynamicLinks(app: Firebase.app()); + return _instance ??= MethodChannelFirebaseDynamicLinks(); } static FirebaseDynamicLinksPlatform? _instance; From 91e3983133e261a2861f77ca45b12a1198ecb740 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 12:12:34 +0000 Subject: [PATCH 088/125] chore(dynamic_links): switch back to PendingDynamicLinkDataIOS --- .../firebase_dynamic_links/lib/firebase_dynamic_links.dart | 2 +- .../test/firebase_dynamic_links_test.dart | 2 +- .../method_channel_firebase_dynamic_links.dart | 4 ++-- .../lib/src/pending_dynamic_link_data.dart | 2 +- .../lib/src/pending_dynamic_link_data_ios.dart | 6 +++--- .../test/pending_dynamic_link_data_test.dart | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index d66105e0d445..6ba52674d1c9 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -20,7 +20,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links NavigationInfoParameters, PendingDynamicLinkData, PendingDynamicLinkDataAndroid, - PendingDynamicLinkDataiOS, + PendingDynamicLinkDataIOS, ShortDynamicLink, ShortDynamicLinkPathLength, SocialMetaTagParameters; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 8c5d44adb5f7..d4343e347956 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -288,7 +288,7 @@ class TestPendingDynamicLinkData extends PendingDynamicLinkData { android: PendingDynamicLinkDataAndroid( clickTimestamp: mockClickTimestamp, minimumVersion: mockMinimumVersionAndroid), - ios: PendingDynamicLinkDataiOS( + ios: PendingDynamicLinkDataIOS( minimumVersion: mockMinimumVersionIOS)); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index fa7b6f01cdec..a0ff359cb03d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -84,11 +84,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ); } - PendingDynamicLinkDataiOS? iosData; + PendingDynamicLinkDataIOS? iosData; if (linkData['ios'] != null) { final Map data = linkData['ios']; iosData = - PendingDynamicLinkDataiOS(minimumVersion: data['minimumVersion']); + PendingDynamicLinkDataIOS(minimumVersion: data['minimumVersion']); } return PendingDynamicLinkData( diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart index e723e70f21d8..512d4bd39871 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data.dart @@ -19,7 +19,7 @@ class PendingDynamicLinkData { /// /// Can be null if [link] equals null or dynamic link was not received on an /// iOS device. - final PendingDynamicLinkDataiOS? ios; + final PendingDynamicLinkDataIOS? ios; /// Deep link parameter of the dynamic link. final Uri link; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart index 25020d214b2b..6dde7dcfd23b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/pending_dynamic_link_data_ios.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. /// Provides iOS specific data from received dynamic link. -class PendingDynamicLinkDataiOS { - const PendingDynamicLinkDataiOS({this.minimumVersion}); +class PendingDynamicLinkDataIOS { + const PendingDynamicLinkDataIOS({this.minimumVersion}); /// The minimum version of your app that can open the link. /// @@ -19,6 +19,6 @@ class PendingDynamicLinkDataiOS { @override String toString() { - return '$PendingDynamicLinkDataiOS($asMap)'; + return '$PendingDynamicLinkDataIOS($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart index 5b1f9b2186f6..84d7ec326ee0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/pending_dynamic_link_data_test.dart @@ -14,8 +14,8 @@ void main() { minimumVersion: minimumVersion, clickTimestamp: clickTimestamp, ); - PendingDynamicLinkDataiOS iosData = - PendingDynamicLinkDataiOS(minimumVersion: minimumVersionIos); + PendingDynamicLinkDataIOS iosData = + PendingDynamicLinkDataIOS(minimumVersion: minimumVersionIos); group('$PendingDynamicLinkData', () { PendingDynamicLinkData pendingDynamicLinkData = From e124aa9f2c2ff184fe257ef5ca0417603f26312c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 12:19:27 +0000 Subject: [PATCH 089/125] chore(dynamic_links): method channel error handling --- .../method_channel_firebase_dynamic_links.dart | 14 +++++++++----- .../lib/src/method_channel/utils/exception.dart | 7 +++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index a0ff359cb03d..dfcf3ac3fcfb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -109,7 +109,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return _getPendingDynamicLinkDataFromMap(linkData); } catch (e, s) { - throw platformExceptionToFirebaseException(e, s); + throw convertPlatformException(e, s); } } @@ -121,9 +121,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'FirebaseDynamicLinks#getDynamicLink', _withChannelDefaults({'url': url.toString()}), ); + return _getPendingDynamicLinkDataFromMap(linkData); } catch (e, s) { - throw platformExceptionToFirebaseException(e, s); + throw convertPlatformException(e, s); } } @@ -147,9 +148,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'dynamicLinkParametersOptions': options?.asMap(), }), ); + return _parseShortLink(reply!); } catch (e, s) { - throw platformExceptionToFirebaseException(e, s); + throw convertPlatformException(e, s); } } @@ -161,9 +163,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'FirebaseDynamicLinks#buildUrl', _withChannelDefaults(parameters.asMap()), ); + return Uri.parse(url!); } catch (e, s) { - throw platformExceptionToFirebaseException(e, s); + throw convertPlatformException(e, s); } } @@ -178,9 +181,10 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { 'FirebaseDynamicLinks#buildShortLink', _withChannelDefaults(parameters.asMap()), ); + return _parseShortLink(response!); } catch (e, s) { - throw platformExceptionToFirebaseException(e, s); + throw convertPlatformException(e, s); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart index 4d9a471f33a6..a928e64e7864 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/utils/exception.dart @@ -8,12 +8,15 @@ import 'package:flutter/services.dart'; /// Catches a [PlatformException] and returns an [Exception]. /// /// If the [Exception] is a [PlatformException], a [FirebaseException] is returned. -Exception convertPlatformException(Object exception) { +Exception convertPlatformException( + Object exception, [ + StackTrace? stackTrace, +]) { if (exception is! Exception || exception is! PlatformException) { throw exception; } - return platformExceptionToFirebaseException(exception); + return platformExceptionToFirebaseException(exception, stackTrace); } /// Converts a [PlatformException] into a [FirebaseException]. From 8307bfb329689517c87b0374f0cf2c84913174ee Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 12:19:39 +0000 Subject: [PATCH 090/125] chore(dynamic_links): PI code comments --- .../platform_interface_firebase_dynamic_links.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index a97a8c099261..9dbb125549f4 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -55,10 +55,21 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('delegateFor() is not implemented'); } + /// Attempts to retrieve the dynamic link which launched the app. + /// + /// This method always returns a Future. That Future completes to null if + /// there is no pending dynamic link or any call to this method after the + /// the first attempt. Future getInitialLink() { throw UnimplementedError('getInitialLink() is not implemented'); } + /// Determine if the app has a pending dynamic link and provide access to + /// the dynamic link parameters. A pending dynamic link may have been + /// previously captured when a user clicked on a dynamic link, or + /// may be present in the dynamicLinkUri parameter. If both are present, + /// the previously captured dynamic link will take precedence. The captured + /// data will be removed after first access. Future getDynamicLink(Uri url) async { throw UnimplementedError('getDynamicLink() is not implemented'); } From dc820592c81d15eae46038a529fb482a5c3dce0e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 18 Nov 2021 13:07:03 +0000 Subject: [PATCH 091/125] chore(dynamic_links): analyse issues --- .../example/lib/main.dart | 114 +++++----- .../test/firebase_dynamic_links_test.dart | 202 +++++++++++------- .../test/dynamic_link_parameters_test.dart | 193 ++++++++++------- 3 files changed, 307 insertions(+), 202 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 7f9e897223e2..4224961c749d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -27,17 +27,19 @@ Future main() async { ), ); } else { - // iOS requires that there is a GoogleService-Inof.plist otherwise getInitialLink & getDynamicLink will not work correctly. + // iOS requires that there is a GoogleService-Info.plist otherwise getInitialLink & getDynamicLink will not work correctly. // iOS also requires you run in release mode to test dynamic links ("flutter run --release"). await Firebase.initializeApp(); } - runApp(MaterialApp( - title: 'Dynamic Links Example', - routes: { - '/': (BuildContext context) => _MainScreen(), - '/helloworld': (BuildContext context) => _DynamicLinkScreen(), - }, - )); + runApp( + MaterialApp( + title: 'Dynamic Links Example', + routes: { + '/': (BuildContext context) => _MainScreen(), + '/helloworld': (BuildContext context) => _DynamicLinkScreen(), + }, + ), + ); } class _MainScreen extends StatefulWidget { @@ -118,15 +120,16 @@ class _MainScreenState extends State<_MainScreen> { appBar: AppBar( title: const Text('Dynamic Links Example'), ), - body: Builder(builder: (BuildContext context) { - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ButtonBar( - alignment: MainAxisAlignment.center, - children: [ - ElevatedButton( + body: Builder( + builder: (BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + ElevatedButton( onPressed: () async { // comment out the above onLink() event listener to test `getInitialLink()` when your app is first opened pressing // the dynamic link. @@ -139,8 +142,9 @@ class _MainScreenState extends State<_MainScreen> { Navigator.pushNamed(context, deepLink.path); } }, - child: const Text('getInitialLink')), - ElevatedButton( + child: const Text('getInitialLink'), + ), + ElevatedButton( onPressed: () async { // comment out the above onLink() event listener to test `getDynamicLink(url)` when your app is first opened pressing // the dynamic link. @@ -154,43 +158,45 @@ class _MainScreenState extends State<_MainScreen> { Navigator.pushNamed(context, deepLink.path); } }, - child: const Text('getDynamicLink')), - ElevatedButton( - onPressed: !_isCreatingLink - ? () => _createDynamicLink(false) - : null, - child: const Text('Get Long Link'), - ), - ElevatedButton( - onPressed: !_isCreatingLink - ? () => _createDynamicLink(true) - : null, - child: const Text('Get Short Link'), + child: const Text('getDynamicLink'), + ), + ElevatedButton( + onPressed: !_isCreatingLink + ? () => _createDynamicLink(false) + : null, + child: const Text('Get Long Link'), + ), + ElevatedButton( + onPressed: !_isCreatingLink + ? () => _createDynamicLink(true) + : null, + child: const Text('Get Short Link'), + ), + ], + ), + InkWell( + onTap: () async { + if (_linkMessage != null) { + await launch(_linkMessage!); + } + }, + onLongPress: () { + Clipboard.setData(ClipboardData(text: _linkMessage)); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Copied Link!')), + ); + }, + child: Text( + _linkMessage ?? '', + style: const TextStyle(color: Colors.blue), ), - ], - ), - InkWell( - onTap: () async { - if (_linkMessage != null) { - await launch(_linkMessage!); - } - }, - onLongPress: () { - Clipboard.setData(ClipboardData(text: _linkMessage)); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('Copied Link!')), - ); - }, - child: Text( - _linkMessage ?? '', - style: const TextStyle(color: Colors.blue), ), - ), - Text(_linkMessage == null ? '' : _testString) - ], - ), - ); - }), + Text(_linkMessage == null ? '' : _testString) + ], + ), + ); + }, + ), ), ); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index d4343e347956..58e67241b66f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -23,20 +23,22 @@ DynamicLinkParameters buildDynamicLinkParameters() { ); GoogleAnalyticsParameters google = const GoogleAnalyticsParameters( - campaign: 'campaign', - medium: 'medium', - source: 'source', - term: 'term', - content: 'content'); + campaign: 'campaign', + medium: 'medium', + source: 'source', + term: 'term', + content: 'content', + ); IosParameters ios = IosParameters( - appStoreId: 'appStoreId', - bundleId: 'bundleId', - customScheme: 'customScheme', - fallbackUrl: Uri.parse('fallbackUrl'), - ipadBundleId: 'ipadBundleId', - ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), - minimumVersion: 'minimumVersion'); + appStoreId: 'appStoreId', + bundleId: 'bundleId', + customScheme: 'customScheme', + fallbackUrl: Uri.parse('fallbackUrl'), + ipadBundleId: 'ipadBundleId', + ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), + minimumVersion: 'minimumVersion', + ); ITunesConnectAnalyticsParameters itunes = const ITunesConnectAnalyticsParameters( @@ -47,28 +49,31 @@ DynamicLinkParameters buildDynamicLinkParameters() { DynamicLinkParametersOptions parametersOptions = const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, + ); Uri link = Uri.parse('link'); NavigationInfoParameters navigation = const NavigationInfoParameters(forcedRedirectEnabled: true); SocialMetaTagParameters social = SocialMetaTagParameters( - description: 'description', - imageUrl: Uri.parse('imageUrl'), - title: 'title'); + description: 'description', + imageUrl: Uri.parse('imageUrl'), + title: 'title', + ); String uriPrefix = 'https://'; return DynamicLinkParameters( - uriPrefix: uriPrefix, - link: link, - androidParameters: android, - dynamicLinkParametersOptions: parametersOptions, - googleAnalyticsParameters: google, - iosParameters: ios, - itunesConnectAnalyticsParameters: itunes, - navigationInfoParameters: navigation, - socialMetaTagParameters: social); + uriPrefix: uriPrefix, + link: link, + androidParameters: android, + dynamicLinkParametersOptions: parametersOptions, + googleAnalyticsParameters: google, + iosParameters: ios, + itunesConnectAnalyticsParameters: itunes, + navigationInfoParameters: navigation, + socialMetaTagParameters: social, + ); } void main() { @@ -92,9 +97,14 @@ void main() { const mockMinimumVersionIOS = 'ios minimum version'; Uri mockUri = Uri.parse('mock-scheme'); - when(dynamicLinks.getInitialLink()).thenAnswer((_) async => - TestPendingDynamicLinkData(mockUri, mockClickTimestamp, - mockMinimumVersionAndroid, mockMinimumVersionIOS)); + when(dynamicLinks.getInitialLink()).thenAnswer( + (_) async => TestPendingDynamicLinkData( + mockUri, + mockClickTimestamp, + mockMinimumVersionAndroid, + mockMinimumVersionIOS, + ), + ); final PendingDynamicLinkData? data = await dynamicLinks.getInitialLink(); @@ -128,9 +138,14 @@ void main() { const mockMinimumVersionAndroid = 21; const mockMinimumVersionIOS = 'min version'; - when(dynamicLinks.getDynamicLink(mockUri)).thenAnswer((_) async => - TestPendingDynamicLinkData(mockUri, mockClickTimestamp, - mockMinimumVersionAndroid, mockMinimumVersionIOS)); + when(dynamicLinks.getDynamicLink(mockUri)).thenAnswer( + (_) async => TestPendingDynamicLinkData( + mockUri, + mockClickTimestamp, + mockMinimumVersionAndroid, + mockMinimumVersionIOS, + ), + ); final PendingDynamicLinkData? data = await dynamicLinks.getDynamicLink(mockUri); @@ -152,9 +167,16 @@ void main() { const mockClickTimestamp = 239058435; const mockMinimumVersionAndroid = 33; const mockMinimumVersionIOS = 'on-link version'; - when(dynamicLinks.onLink()).thenAnswer((_) => Stream.value( - TestPendingDynamicLinkData(mockUri, mockClickTimestamp, - mockMinimumVersionAndroid, mockMinimumVersionIOS))); + when(dynamicLinks.onLink()).thenAnswer( + (_) => Stream.value( + TestPendingDynamicLinkData( + mockUri, + mockClickTimestamp, + mockMinimumVersionAndroid, + mockMinimumVersionIOS, + ), + ), + ); final PendingDynamicLinkData? data = await dynamicLinks.onLink().first; expect(data!.link.scheme, mockUri.scheme); @@ -175,14 +197,16 @@ void main() { List warnings = ['warning']; const DynamicLinkParametersOptions options = DynamicLinkParametersOptions( - shortDynamicLinkPathLength: - ShortDynamicLinkPathLength.unguessable); + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, + ); - when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer((_) async => - ShortDynamicLink( - shortUrl: mockUri, - warnings: warnings, - previewLink: previewLink)); + when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer( + (_) async => ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink, + ), + ); final shortDynamicLink = await dynamicLinks.shortenUrl(mockUri, options); @@ -236,13 +260,18 @@ void main() { DynamicLinkParameters params = DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); final shortLink = ShortDynamicLink( - shortUrl: mockUri, warnings: warnings, previewLink: previewLink); - - when(dynamicLinks.buildShortLink(params)).thenAnswer((_) async => - ShortDynamicLink( - shortUrl: mockUri, - warnings: warnings, - previewLink: previewLink)); + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink, + ); + + when(dynamicLinks.buildShortLink(params)).thenAnswer( + (_) async => ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink, + ), + ); final shortDynamicLink = await dynamicLinks.buildShortLink(params); @@ -260,13 +289,18 @@ void main() { List warnings = ['warning']; DynamicLinkParameters params = buildDynamicLinkParameters(); final shortLink = ShortDynamicLink( - shortUrl: mockUri, warnings: warnings, previewLink: previewLink); - - when(dynamicLinks.buildShortLink(params)).thenAnswer((_) async => - ShortDynamicLink( - shortUrl: mockUri, - warnings: warnings, - previewLink: previewLink)); + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink, + ); + + when(dynamicLinks.buildShortLink(params)).thenAnswer( + (_) async => ShortDynamicLink( + shortUrl: mockUri, + warnings: warnings, + previewLink: previewLink, + ), + ); final shortDynamicLink = await dynamicLinks.buildShortLink(params); @@ -281,15 +315,21 @@ void main() { } class TestPendingDynamicLinkData extends PendingDynamicLinkData { - TestPendingDynamicLinkData(mockUri, mockClickTimestamp, - mockMinimumVersionAndroid, mockMinimumVersionIOS) - : super( - link: mockUri, - android: PendingDynamicLinkDataAndroid( - clickTimestamp: mockClickTimestamp, - minimumVersion: mockMinimumVersionAndroid), - ios: PendingDynamicLinkDataIOS( - minimumVersion: mockMinimumVersionIOS)); + TestPendingDynamicLinkData( + mockUri, + mockClickTimestamp, + mockMinimumVersionAndroid, + mockMinimumVersionIOS, + ) : super( + link: mockUri, + android: PendingDynamicLinkDataAndroid( + clickTimestamp: mockClickTimestamp, + minimumVersion: mockMinimumVersionAndroid, + ), + ios: PendingDynamicLinkDataIOS( + minimumVersion: mockMinimumVersionIOS, + ), + ); } final testData = TestPendingDynamicLinkData(Uri.parse('uri'), null, null, null); @@ -343,18 +383,26 @@ class MockFirebaseDynamicLinks extends Mock } @override - Future shortenUrl(Uri uri, - [DynamicLinkParametersOptions? options]) { + Future shortenUrl( + Uri uri, [ + DynamicLinkParametersOptions? options, + ]) { return super.noSuchMethod( Invocation.method(#shortenUrl, [uri, options]), - returnValue: Future.value(ShortDynamicLink( + returnValue: Future.value( + ShortDynamicLink( shortUrl: uri, warnings: ['warning'], - previewLink: Uri.parse('preview'))), - returnValueForMissingStub: Future.value(ShortDynamicLink( + previewLink: Uri.parse('preview'), + ), + ), + returnValueForMissingStub: Future.value( + ShortDynamicLink( shortUrl: uri, warnings: ['warning'], - previewLink: Uri.parse('preview'))), + previewLink: Uri.parse('preview'), + ), + ), ); } @@ -362,14 +410,20 @@ class MockFirebaseDynamicLinks extends Mock Future buildShortLink(DynamicLinkParameters parameters) { return super.noSuchMethod( Invocation.method(#buildShortLink, [parameters]), - returnValue: Future.value(ShortDynamicLink( + returnValue: Future.value( + ShortDynamicLink( shortUrl: uri, warnings: ['warning'], - previewLink: Uri.parse('preview'))), - returnValueForMissingStub: Future.value(ShortDynamicLink( + previewLink: Uri.parse('preview'), + ), + ), + returnValueForMissingStub: Future.value( + ShortDynamicLink( shortUrl: uri, warnings: ['warning'], - previewLink: Uri.parse('preview'))), + previewLink: Uri.parse('preview'), + ), + ), ); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index d8e4dabdc44a..ffae4c04599d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -13,20 +13,22 @@ void main() { ); GoogleAnalyticsParameters googleParams = const GoogleAnalyticsParameters( - campaign: 'campaign', - medium: 'medium', - source: 'source', - term: 'term', - content: 'content'); + campaign: 'campaign', + medium: 'medium', + source: 'source', + term: 'term', + content: 'content', + ); IosParameters iosParams = IosParameters( - appStoreId: 'appStoreId', - bundleId: 'bundleId', - customScheme: 'customScheme', - fallbackUrl: Uri.parse('fallbackUrl'), - ipadBundleId: 'ipadBundleId', - ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), - minimumVersion: 'minimumVersion'); + appStoreId: 'appStoreId', + bundleId: 'bundleId', + customScheme: 'customScheme', + fallbackUrl: Uri.parse('fallbackUrl'), + ipadBundleId: 'ipadBundleId', + ipadFallbackUrl: Uri.parse('ipadFallbackUrl'), + minimumVersion: 'minimumVersion', + ); ITunesConnectAnalyticsParameters itunesParams = const ITunesConnectAnalyticsParameters( @@ -37,15 +39,17 @@ void main() { DynamicLinkParametersOptions parametersOptions = const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); + shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, + ); Uri link = Uri.parse('link'); NavigationInfoParameters navigation = const NavigationInfoParameters(forcedRedirectEnabled: true); SocialMetaTagParameters social = SocialMetaTagParameters( - description: 'description', - imageUrl: Uri.parse('imageUrl'), - title: 'title'); + description: 'description', + imageUrl: Uri.parse('imageUrl'), + title: 'title', + ); String uriPrefix = 'https://'; @@ -70,7 +74,9 @@ void main() { expect(dynamicLinkParams.googleAnalyticsParameters, googleParams); expect(dynamicLinkParams.iosParameters, iosParams); expect( - dynamicLinkParams.itunesConnectAnalyticsParameters, itunesParams); + dynamicLinkParams.itunesConnectAnalyticsParameters, + itunesParams, + ); expect(dynamicLinkParams.navigationInfoParameters, navigation); expect(dynamicLinkParams.socialMetaTagParameters, social); }); @@ -80,71 +86,110 @@ void main() { final result = dynamicLinkParams.asMap(); expect(result, isA>()); - expect(result['androidParameters']['fallbackUrl'], - dynamicLinkParams.androidParameters?.fallbackUrl.toString()); - expect(result['androidParameters']['minimumVersion'], - dynamicLinkParams.androidParameters?.minimumVersion); - expect(result['androidParameters']['packageName'], - dynamicLinkParams.androidParameters?.packageName); + expect( + result['androidParameters']['fallbackUrl'], + dynamicLinkParams.androidParameters?.fallbackUrl.toString(), + ); + expect( + result['androidParameters']['minimumVersion'], + dynamicLinkParams.androidParameters?.minimumVersion, + ); + expect( + result['androidParameters']['packageName'], + dynamicLinkParams.androidParameters?.packageName, + ); expect(result['uriPrefix'], dynamicLinkParams.uriPrefix); expect( - result['dynamicLinkParametersOptions'] - ['shortDynamicLinkPathLength'], - dynamicLinkParams.dynamicLinkParametersOptions - ?.shortDynamicLinkPathLength?.index); - expect(result['googleAnalyticsParameters']['campaign'], - dynamicLinkParams.googleAnalyticsParameters?.campaign); - expect(result['googleAnalyticsParameters']['content'], - dynamicLinkParams.googleAnalyticsParameters?.content); - expect(result['googleAnalyticsParameters']['medium'], - dynamicLinkParams.googleAnalyticsParameters?.medium); - expect(result['googleAnalyticsParameters']['source'], - dynamicLinkParams.googleAnalyticsParameters?.source); - expect(result['googleAnalyticsParameters']['term'], - dynamicLinkParams.googleAnalyticsParameters?.term); - expect(result['iosParameters']['appStoreId'], - dynamicLinkParams.iosParameters?.appStoreId); - expect(result['iosParameters']['bundleId'], - dynamicLinkParams.iosParameters?.bundleId); - expect(result['iosParameters']['customScheme'], - dynamicLinkParams.iosParameters?.customScheme); - expect(result['iosParameters']['fallbackUrl'], - dynamicLinkParams.iosParameters?.fallbackUrl.toString()); - expect(result['iosParameters']['ipadBundleId'], - dynamicLinkParams.iosParameters?.ipadBundleId); - expect(result['iosParameters']['ipadFallbackUrl'], - dynamicLinkParams.iosParameters?.ipadFallbackUrl.toString()); - expect(result['iosParameters']['minimumVersion'], - dynamicLinkParams.iosParameters?.minimumVersion); - expect( - result['itunesConnectAnalyticsParameters']['affiliateToken'], - dynamicLinkParams - .itunesConnectAnalyticsParameters?.affiliateToken); - expect( - result['itunesConnectAnalyticsParameters']['providerToken'], - dynamicLinkParams - .itunesConnectAnalyticsParameters?.providerToken); - expect( - result['itunesConnectAnalyticsParameters']['campaignToken'], - dynamicLinkParams - .itunesConnectAnalyticsParameters?.campaignToken); + result['dynamicLinkParametersOptions'] + ['shortDynamicLinkPathLength'], + dynamicLinkParams.dynamicLinkParametersOptions + ?.shortDynamicLinkPathLength?.index, + ); + expect( + result['googleAnalyticsParameters']['campaign'], + dynamicLinkParams.googleAnalyticsParameters?.campaign, + ); + expect( + result['googleAnalyticsParameters']['content'], + dynamicLinkParams.googleAnalyticsParameters?.content, + ); + expect( + result['googleAnalyticsParameters']['medium'], + dynamicLinkParams.googleAnalyticsParameters?.medium, + ); + expect( + result['googleAnalyticsParameters']['source'], + dynamicLinkParams.googleAnalyticsParameters?.source, + ); + expect( + result['googleAnalyticsParameters']['term'], + dynamicLinkParams.googleAnalyticsParameters?.term, + ); + expect( + result['iosParameters']['appStoreId'], + dynamicLinkParams.iosParameters?.appStoreId, + ); + expect( + result['iosParameters']['bundleId'], + dynamicLinkParams.iosParameters?.bundleId, + ); + expect( + result['iosParameters']['customScheme'], + dynamicLinkParams.iosParameters?.customScheme, + ); + expect( + result['iosParameters']['fallbackUrl'], + dynamicLinkParams.iosParameters?.fallbackUrl.toString(), + ); + expect( + result['iosParameters']['ipadBundleId'], + dynamicLinkParams.iosParameters?.ipadBundleId, + ); + expect( + result['iosParameters']['ipadFallbackUrl'], + dynamicLinkParams.iosParameters?.ipadFallbackUrl.toString(), + ); + expect( + result['iosParameters']['minimumVersion'], + dynamicLinkParams.iosParameters?.minimumVersion, + ); + expect( + result['itunesConnectAnalyticsParameters']['affiliateToken'], + dynamicLinkParams.itunesConnectAnalyticsParameters?.affiliateToken, + ); + expect( + result['itunesConnectAnalyticsParameters']['providerToken'], + dynamicLinkParams.itunesConnectAnalyticsParameters?.providerToken, + ); + expect( + result['itunesConnectAnalyticsParameters']['campaignToken'], + dynamicLinkParams.itunesConnectAnalyticsParameters?.campaignToken, + ); expect(result['link'], dynamicLinkParams.link.toString()); expect( - result['navigationInfoParameters']['forcedRedirectEnabled'], - dynamicLinkParams - .navigationInfoParameters?.forcedRedirectEnabled); - expect(result['socialMetaTagParameters']['description'], - dynamicLinkParams.socialMetaTagParameters?.description); - expect(result['socialMetaTagParameters']['imageUrl'], - dynamicLinkParams.socialMetaTagParameters?.imageUrl.toString()); - expect(result['socialMetaTagParameters']['title'], - dynamicLinkParams.socialMetaTagParameters?.title); + result['navigationInfoParameters']['forcedRedirectEnabled'], + dynamicLinkParams.navigationInfoParameters?.forcedRedirectEnabled, + ); + expect( + result['socialMetaTagParameters']['description'], + dynamicLinkParams.socialMetaTagParameters?.description, + ); + expect( + result['socialMetaTagParameters']['imageUrl'], + dynamicLinkParams.socialMetaTagParameters?.imageUrl.toString(), + ); + expect( + result['socialMetaTagParameters']['title'], + dynamicLinkParams.socialMetaTagParameters?.title, + ); }); }); test('toString', () { - expect(dynamicLinkParams.toString(), - equals('$DynamicLinkParameters(${dynamicLinkParams.asMap})')); + expect( + dynamicLinkParams.toString(), + equals('$DynamicLinkParameters(${dynamicLinkParams.asMap})'), + ); }); }); }); From a55da8a449a098b8ff6bdae1b024f368b0738814 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 24 Nov 2021 16:46:56 +0000 Subject: [PATCH 092/125] refactor(dynamic_links): ISOParameters naming --- .../firebase_dynamic_links/example/lib/main.dart | 2 +- .../example/test_driver/instance_e2e.dart | 6 +++--- .../lib/firebase_dynamic_links.dart | 2 +- .../test/firebase_dynamic_links_test.dart | 2 +- .../lib/src/dynamic_link_parameters.dart | 2 +- .../lib/src/ios_parameters.dart | 6 +++--- .../test/dynamic_link_parameters_test.dart | 2 +- .../test/ios_parameters_test.dart | 8 ++++---- .../method_channel_firebase_dynamic_links_test.dart | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 4224961c749d..c57617441462 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -92,7 +92,7 @@ class _MainScreenState extends State<_MainScreen> { dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: const IosParameters( + iosParameters: const IOSParameters( bundleId: 'io.invertase.testing', minimumVersion: '0', ), diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 982913803f93..7c0b649d5d75 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -43,7 +43,7 @@ void runInstanceTests() { dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: const IosParameters( + iosParameters: const IOSParameters( bundleId: iosBundleId, minimumVersion: '2', ), @@ -104,7 +104,7 @@ void runInstanceTests() { dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: const IosParameters( + iosParameters: const IOSParameters( bundleId: iosBundleId, minimumVersion: '2', ), @@ -151,7 +151,7 @@ void runInstanceTests() { dynamicLinkParametersOptions: const DynamicLinkParametersOptions( shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, ), - iosParameters: const IosParameters( + iosParameters: const IOSParameters( bundleId: iosBundleId, minimumVersion: '2', ), diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 6ba52674d1c9..37443f463bf0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -15,7 +15,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links DynamicLinkParametersOptions, FirebaseDynamicLinksPlatform, GoogleAnalyticsParameters, - IosParameters, + IOSParameters, ITunesConnectAnalyticsParameters, NavigationInfoParameters, PendingDynamicLinkData, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 58e67241b66f..e4e76489556d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -30,7 +30,7 @@ DynamicLinkParameters buildDynamicLinkParameters() { content: 'content', ); - IosParameters ios = IosParameters( + IOSParameters ios = IOSParameters( appStoreId: 'appStoreId', bundleId: 'bundleId', customScheme: 'customScheme', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index 27a7ccc361bb..44430bf57067 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -39,7 +39,7 @@ class DynamicLinkParameters { final GoogleAnalyticsParameters? googleAnalyticsParameters; /// iOS parameters for a generated Dynamic Link URL. - final IosParameters? iosParameters; + final IOSParameters? iosParameters; /// iTunes Connect parameters for a generated Dynamic Link URL. final ITunesConnectAnalyticsParameters? itunesConnectAnalyticsParameters; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart index 0853003192d4..e96f8b20ab8c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/ios_parameters.dart @@ -3,8 +3,8 @@ // found in the LICENSE file. /// The Dynamic Link iOS parameters. -class IosParameters { - const IosParameters({ +class IOSParameters { + const IOSParameters({ this.appStoreId, required this.bundleId, this.customScheme, @@ -62,6 +62,6 @@ class IosParameters { @override String toString() { - return '$IosParameters($asMap)'; + return '$IOSParameters($asMap)'; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index ffae4c04599d..b8b04a167c20 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -20,7 +20,7 @@ void main() { content: 'content', ); - IosParameters iosParams = IosParameters( + IOSParameters iosParams = IOSParameters( appStoreId: 'appStoreId', bundleId: 'bundleId', customScheme: 'customScheme', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart index 7bbfa01baac8..b1e9fd4f9dcc 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/ios_parameters_test.dart @@ -14,8 +14,8 @@ void main() { Uri fallbackUrl = Uri.parse('fallbackUrl'); Uri ipadFallbackUrl = Uri.parse('ipadFallbackUrl'); - group('$IosParameters', () { - IosParameters iosParams = IosParameters( + group('$IOSParameters', () { + IOSParameters iosParams = IOSParameters( appStoreId: appStoreId, bundleId: bundleId, customScheme: customScheme, @@ -27,7 +27,7 @@ void main() { group('Constructor', () { test('returns an instance of [IosParameters]', () { - expect(iosParams, isA()); + expect(iosParams, isA()); expect(iosParams.appStoreId, appStoreId); expect(iosParams.bundleId, bundleId); expect(iosParams.bundleId, bundleId); @@ -59,7 +59,7 @@ void main() { test('toString', () { expect( iosParams.toString(), - equals('$IosParameters(${iosParams.asMap})'), + equals('$IOSParameters(${iosParams.asMap})'), ); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index e199291671e7..befb6ba5adf5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -27,7 +27,7 @@ DynamicLinkParameters buildDynamicLinkParameters() { content: 'content', ); - IosParameters ios = IosParameters( + IOSParameters ios = IOSParameters( appStoreId: 'appStoreId', bundleId: 'bundleId', customScheme: 'customScheme', From 8a7ed3222825a6978cd99cc71421b4c32a35ef6f Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 24 Nov 2021 16:49:51 +0000 Subject: [PATCH 093/125] chore(dynamic_links): revert auth example pubspec.yaml --- packages/firebase_auth/firebase_auth/example/pubspec.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/firebase_auth/firebase_auth/example/pubspec.yaml b/packages/firebase_auth/firebase_auth/example/pubspec.yaml index fab109cc269d..7abfdd35da2b 100644 --- a/packages/firebase_auth/firebase_auth/example/pubspec.yaml +++ b/packages/firebase_auth/firebase_auth/example/pubspec.yaml @@ -9,8 +9,6 @@ dependencies: path: ../ firebase_core: path: ../../../firebase_core/firebase_core - firebase_dynamic_links: - path: ../../../firebase_dynamic_links/firebase_dynamic_links flutter: sdk: flutter flutter_signin_button: ^2.0.0 @@ -30,10 +28,6 @@ dependency_overrides: path: ../../../firebase_core/firebase_core_platform_interface firebase_core_web: path: ../../../firebase_core/firebase_core_web - firebase_dynamic_links: - path: ../../../firebase_dynamic_links/firebase_dynamic_links - firebase_dynamic_links_platform_interface: - path: ../../../firebase_dynamic_links/firebase_dynamic_links_platform_interface dev_dependencies: drive: 1.0.0-1.0.nullsafety.1 From 8fe4e26f0721387852b6f4c79574e0fdc0fcb510 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 24 Nov 2021 16:59:53 +0000 Subject: [PATCH 094/125] chore(dynamic_links): setup headers for DL usage docs --- docs/dynamic-links/usage.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index 269df4d4c1a6..fe326001b969 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -1,6 +1,12 @@ --- -title: Dynamic Links +title: Using Dynamic Links sidebar_label: Usage --- -Dynamic Links usage +## Getting started + +## Create a Dynamic Link + +## Listening for Dynamic Links + +## Get Dynamic Link From 2320b525e1fce4bc03cbc3123ce6c07934cca6b6 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 14:00:20 +0000 Subject: [PATCH 095/125] docs(dynamic_links): update universal code CHANGELOG.md for rework --- .../firebase_dynamic_links/CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index 64b0596effc9..b1cc44917858 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -1,3 +1,18 @@ +## UNRELEASED + +As part of our on-going work for [#6769](https://github.com/FirebaseExtended/flutterfire/issues/6979) this is our Firebase Dynamic Links rework changes. + +Overall, Firebase Dynamic Links has been heavily reworked to bring it inline with the federated plugin setup along with adding new features, +documentation and updating unit and end-to-end tests. + +- **`FirebaseDynamicLinks`** + +- **BREAKING**: `onLink()` method no longer accepts callback arguments for events. It returns a `Stream`; events & errors are now streamed to the user. +- **BREAKING**: `DynamicLinkParameters` class has been removed. `shortenUrl()` `buildUrl()` & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. + +- **NEW**: `DynamicLinkParameters` class is used to build parameters for `shortenUrl()` `buildUrl()` & `buildShortLink()`. +- **NEW**: Multi-app support now available for `android` only; `FirebaseDynamicLinks.instanceFor(app: app)`. + ## 3.0.1 - Update a dependency to the latest release. From 1133837baff70b4633dfc187d1b7a4010798a372 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 14:54:18 +0000 Subject: [PATCH 096/125] refactor(dynamic_links): update onLink() to onLink --- .../firebase_dynamic_links/example/lib/main.dart | 2 +- .../example/test_driver/instance_e2e.dart | 8 ++++---- .../lib/src/firebase_dynamic_links.dart | 4 ++-- .../test/firebase_dynamic_links_test.dart | 10 +++++----- .../method_channel_firebase_dynamic_links.dart | 2 +- .../platform_interface_firebase_dynamic_links.dart | 10 +++++----- .../method_channel_firebase_dynamic_links_test.dart | 2 +- ...platform_interface_firebase_dynamic_links_test.dart | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index c57617441462..0518625f39e2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -67,7 +67,7 @@ class _MainScreenState extends State<_MainScreen> { } Future initDynamicLinks() async { - dynamicLinks.onLink().listen((dynamicLinkData) { + dynamicLinks.onLink.listen((dynamicLinkData) { if (dynamicLinkData != null) { Navigator.pushNamed(context, dynamicLinkData.link.path); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 7c0b649d5d75..678aeeb74283 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -191,17 +191,17 @@ void runInstanceTests() { StreamSubscription _onListenSubscriptionSecond; _onListenSubscription = - FirebaseDynamicLinks.instance.onLink().listen((event) {}); + FirebaseDynamicLinks.instance.onLink.listen((event) {}); _onListenSubscriptionSecond = - FirebaseDynamicLinks.instance.onLink().listen((event) {}); + FirebaseDynamicLinks.instance.onLink.listen((event) {}); await _onListenSubscription.cancel(); await _onListenSubscriptionSecond.cancel(); _onListenSubscription = - FirebaseDynamicLinks.instance.onLink().listen((event) {}); + FirebaseDynamicLinks.instance.onLink.listen((event) {}); _onListenSubscriptionSecond = - FirebaseDynamicLinks.instance.onLink().listen((event) {}); + FirebaseDynamicLinks.instance.onLink.listen((event) {}); await _onListenSubscription.cancel(); await _onListenSubscriptionSecond.cancel(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 1f52cad58a38..0ce022b08c63 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -68,8 +68,8 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } /// Listen to a stream for the latest dynamic link events. - Stream onLink() { - return _delegate.onLink(); + Stream get onLink { + return _delegate.onLink; } /// Returns the shortened Dynamic Link, link flow chart, and warnings from the requested Dynamic Link. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index e4e76489556d..dd648f98b3a2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -167,7 +167,7 @@ void main() { const mockClickTimestamp = 239058435; const mockMinimumVersionAndroid = 33; const mockMinimumVersionIOS = 'on-link version'; - when(dynamicLinks.onLink()).thenAnswer( + when(dynamicLinks.onLink).thenAnswer( (_) => Stream.value( TestPendingDynamicLinkData( mockUri, @@ -178,7 +178,7 @@ void main() { ), ); - final PendingDynamicLinkData? data = await dynamicLinks.onLink().first; + final PendingDynamicLinkData? data = await dynamicLinks.onLink.first; expect(data!.link.scheme, mockUri.scheme); expect(data.android!.clickTimestamp, mockClickTimestamp); @@ -186,7 +186,7 @@ void main() { expect(data.ios!.minimumVersion, mockMinimumVersionIOS); - verify(dynamicLinks.onLink()); + verify(dynamicLinks.onLink); }); }); @@ -428,9 +428,9 @@ class MockFirebaseDynamicLinks extends Mock } @override - Stream onLink() { + Stream get onLink { return super.noSuchMethod( - Invocation.method(#onLink, []), + Invocation.getter(#onLink), returnValue: Stream.value(testData), returnValueForMissingStub: Stream.value(testData), ); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index dfcf3ac3fcfb..72782f4394a0 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -129,7 +129,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - Stream onLink() { + Stream get onLink { return _onLinkController.stream; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 9dbb125549f4..70abbbb655ba 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -55,6 +55,11 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('delegateFor() is not implemented'); } + /// Creates a stream for listening whenever a dynamic link becomes available + Stream get onLink { + throw UnimplementedError('onLink is not implemented'); + } + /// Attempts to retrieve the dynamic link which launched the app. /// /// This method always returns a Future. That Future completes to null if @@ -74,11 +79,6 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('getDynamicLink() is not implemented'); } - /// Creates a stream for listening whenever a dynamic link becomes available - Stream onLink() { - throw UnimplementedError('onLink() is not implemented'); - } - /// Shortens a Dynamic Link URL. /// /// This method may be used for shortening a custom URL that was not generated diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index befb6ba5adf5..ff19a3041431 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -347,7 +347,7 @@ void main() { test('returns [Stream]', () async { // Checks that `onLink` does not throw UnimplementedError - expect(dynamicLinks.onLink(), isNotNull); + expect(dynamicLinks.onLink, isNotNull); }); test('listens to incoming changes', () async { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart index 617926998122..7a9056bf96f6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -100,12 +100,12 @@ void main() { test('throws if .onLink', () { expect( - () => firebaseDynamicLinksPlatformPlatform!.onLink(), + () => firebaseDynamicLinksPlatformPlatform!.onLink, throwsA( isA().having( (e) => e.message, 'message', - 'onLink() is not implemented', + 'onLink is not implemented', ), ), ); From f3c0414337a10d6c158e65e952890eb725b406b6 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 15:02:20 +0000 Subject: [PATCH 097/125] docs(dynamic_links): update CHANGELOG.md --- .../firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index b1cc44917858..cb2c2d401c4f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -7,7 +7,7 @@ documentation and updating unit and end-to-end tests. - **`FirebaseDynamicLinks`** -- **BREAKING**: `onLink()` method no longer accepts callback arguments for events. It returns a `Stream`; events & errors are now streamed to the user. +- **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. - **BREAKING**: `DynamicLinkParameters` class has been removed. `shortenUrl()` `buildUrl()` & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. - **NEW**: `DynamicLinkParameters` class is used to build parameters for `shortenUrl()` `buildUrl()` & `buildShortLink()`. From 2178919560d0f08761ddfc4b5f3edbe3243cacae Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 15:20:19 +0000 Subject: [PATCH 098/125] refactor(dynamic_links): update buildUrl() to buildLink() --- .../FlutterFirebaseDynamicLinksPlugin.java | 2 +- .../example/lib/main.dart | 2 +- .../example/test_driver/instance_e2e.dart | 4 +-- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 2 +- .../lib/src/firebase_dynamic_links.dart | 4 +-- .../test/firebase_dynamic_links_test.dart | 30 +++++++++---------- ...method_channel_firebase_dynamic_links.dart | 4 +-- ...form_interface_firebase_dynamic_links.dart | 4 +-- ...d_channel_firebase_dynamic_links_test.dart | 8 ++--- ...interface_firebase_dynamic_links_test.dart | 6 ++-- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 78e9d34f78e1..19ae2c141e09 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -126,7 +126,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re FirebaseDynamicLinks dynamicLinks = getDynamicLinkInstance(call.arguments()); switch (call.method) { - case "FirebaseDynamicLinks#buildUrl": + case "FirebaseDynamicLinks#buildLink": String url = buildUrl(call.arguments()); result.success(url); return; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 0518625f39e2..9868ce17d5c2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -104,7 +104,7 @@ class _MainScreenState extends State<_MainScreen> { await dynamicLinks.buildShortLink(parameters); url = shortLink.shortUrl; } else { - url = await dynamicLinks.buildUrl(parameters); + url = await dynamicLinks.buildLink(parameters); } setState(() { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 678aeeb74283..f9c2be0d1577 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -49,7 +49,7 @@ void runInstanceTests() { ), ); - final Uri uri = await dynamicLinks.buildUrl(parameters); + final Uri uri = await dynamicLinks.buildLink(parameters); // androidParameters.minimumVersion expect( @@ -157,7 +157,7 @@ void runInstanceTests() { ), ); - final Uri uri = await dynamicLinks.buildUrl(parameters); + final Uri uri = await dynamicLinks.buildLink(parameters); final ShortDynamicLink shortLink = await dynamicLinks.shortenUrl(uri); expect(shortLink, isA()); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index ac2d7a32934a..b7ce922ae02b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -137,7 +137,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSLog(@"FLTFirebaseDynamicLinks: iOS plugin only supports the Firebase default app"); } - if ([@"FirebaseDynamicLinks#buildUrl" isEqualToString:call.method]) { + if ([@"FirebaseDynamicLinks#buildLink" isEqualToString:call.method]) { [self buildUrl:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#buildShortLink" isEqualToString:call.method]) { [self buildShortLink:call.arguments withMethodCallResult:methodCallResult]; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 0ce022b08c63..cdb96a355c35 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -81,8 +81,8 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } /// Creates a Dynamic Link from the parameters. - Future buildUrl(DynamicLinkParameters parameters) async { - return _delegate.buildUrl(parameters); + Future buildLink(DynamicLinkParameters parameters) async { + return _delegate.buildLink(parameters); } /// Creates a shortened Dynamic Link from the parameters. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index dd648f98b3a2..c7299b3ca897 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -219,36 +219,36 @@ void main() { }); }); - group('buildUrl', () { - test('buildUrl', () async { - final Uri mockUri = Uri.parse('buildUrl'); + group('buildLink', () { + test('buildLink', () async { + final Uri mockUri = Uri.parse('buildLink'); DynamicLinkParameters params = DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); - when(dynamicLinks.buildUrl(params)).thenAnswer((_) async => mockUri); + when(dynamicLinks.buildLink(params)).thenAnswer((_) async => mockUri); - final shortDynamicLink = await dynamicLinks.buildUrl(params); + final shortDynamicLink = await dynamicLinks.buildLink(params); expect(shortDynamicLink, mockUri); expect(shortDynamicLink.scheme, mockUri.scheme); expect(shortDynamicLink.path, mockUri.path); - verify(dynamicLinks.buildUrl(params)); + verify(dynamicLinks.buildLink(params)); }); - test("buildUrl with full 'DynamicLinkParameters' options", () async { - final Uri mockUri = Uri.parse('buildUrl'); + test("buildLink with full 'DynamicLinkParameters' options", () async { + final Uri mockUri = Uri.parse('buildLink'); DynamicLinkParameters params = buildDynamicLinkParameters(); - when(dynamicLinks.buildUrl(params)).thenAnswer((_) async => mockUri); + when(dynamicLinks.buildLink(params)).thenAnswer((_) async => mockUri); - final shortDynamicLink = await dynamicLinks.buildUrl(params); + final shortDynamicLink = await dynamicLinks.buildLink(params); expect(shortDynamicLink, mockUri); expect(shortDynamicLink.scheme, mockUri.scheme); expect(shortDynamicLink.path, mockUri.path); - verify(dynamicLinks.buildUrl(params)); + verify(dynamicLinks.buildLink(params)); }); }); @@ -365,11 +365,11 @@ class MockFirebaseDynamicLinks extends Mock } @override - Future buildUrl(DynamicLinkParameters parameters) { + Future buildLink(DynamicLinkParameters parameters) { return super.noSuchMethod( - Invocation.method(#getDynamicLink, [parameters]), - returnValue: Future.value(Uri.parse('buildUrl')), - returnValueForMissingStub: Future.value(Uri.parse('buildUrl')), + Invocation.method(#buildLink, [parameters]), + returnValue: Future.value(Uri.parse('buildLink')), + returnValueForMissingStub: Future.value(Uri.parse('buildLink')), ); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 72782f4394a0..ee6a524cdf26 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -156,11 +156,11 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - Future buildUrl(DynamicLinkParameters parameters) async { + Future buildLink(DynamicLinkParameters parameters) async { try { final String? url = await MethodChannelFirebaseDynamicLinks.channel.invokeMethod( - 'FirebaseDynamicLinks#buildUrl', + 'FirebaseDynamicLinks#buildLink', _withChannelDefaults(parameters.asMap()), ); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 70abbbb655ba..49260312ead2 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -91,8 +91,8 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { } /// Generate a long Dynamic Link URL. - Future buildUrl(DynamicLinkParameters parameters) async { - throw UnimplementedError('buildUrl() is not implemented'); + Future buildLink(DynamicLinkParameters parameters) async { + throw UnimplementedError('buildLink() is not implemented'); } /// Generate a short Dynamic Link URL. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index ff19a3041431..566c1f17a8dd 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -272,11 +272,11 @@ void main() { () => dynamicLinks.shortenUrl(url, options)); }); }); - group('buildUrl()', () { - test('buildUrl', () async { + group('buildLink()', () { + test('buildLink', () async { DynamicLinkParameters options = buildDynamicLinkParameters(); - await dynamicLinks.buildUrl(options); + await dynamicLinks.buildLink(options); expect(logger, [ isMethodCall( @@ -334,7 +334,7 @@ void main() { mockPlatformExceptionThrown = true; DynamicLinkParameters options = buildDynamicLinkParameters(); - await testExceptionHandling(() => dynamicLinks.buildUrl(options)); + await testExceptionHandling(() => dynamicLinks.buildLink(options)); }); }); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart index 7a9056bf96f6..f2eff945144d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -124,14 +124,14 @@ void main() { ); }); - test('throws if .buildUrl', () { + test('throws if .buildLink', () { expect( - () => firebaseDynamicLinksPlatformPlatform!.buildUrl(parameters), + () => firebaseDynamicLinksPlatformPlatform!.buildLink(parameters), throwsA( isA().having( (e) => e.message, 'message', - 'buildUrl() is not implemented', + 'buildLink() is not implemented', ), ), ); From 505f4ff61d12829047623acae39c27db070d29e6 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 15:20:34 +0000 Subject: [PATCH 099/125] docs(dynamic_links): CHANGELOG.md update --- .../firebase_dynamic_links/CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index cb2c2d401c4f..b5768f0d7dd1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -8,9 +8,12 @@ documentation and updating unit and end-to-end tests. - **`FirebaseDynamicLinks`** - **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. -- **BREAKING**: `DynamicLinkParameters` class has been removed. `shortenUrl()` `buildUrl()` & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. +- **BREAKING**: `DynamicLinkParameters` class has been removed. `buildLink()` (replaces `buildUrl()`) & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. + +- **NEW**: `buildLink()` which replaces the previous `DynamicLinkParameters().buildUrl()` +- **NEW**: `buildShortLink()` which replaces the previous `DynamicLinkParameters().buildShortLink()` +- **NEW**: `DynamicLinkParameters` class is used to build parameters for `buildLink()` & `buildShortLink()`. -- **NEW**: `DynamicLinkParameters` class is used to build parameters for `shortenUrl()` `buildUrl()` & `buildShortLink()`. - **NEW**: Multi-app support now available for `android` only; `FirebaseDynamicLinks.instanceFor(app: app)`. ## 3.0.1 From 51504cb7a7b274f55bc4243186e2da6d14606e78 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 16:20:29 +0000 Subject: [PATCH 100/125] refactor(dynamic_links): remove shortenUrl() --- .../FlutterFirebaseDynamicLinksPlugin.java | 5 --- .../example/test_driver/instance_e2e.dart | 34 ----------------- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 26 ------------- .../lib/src/firebase_dynamic_links.dart | 8 ---- .../test/firebase_dynamic_links_test.dart | 29 -------------- ...method_channel_firebase_dynamic_links.dart | 22 ----------- ...form_interface_firebase_dynamic_links.dart | 11 ------ ...d_channel_firebase_dynamic_links_test.dart | 38 ------------------- ...interface_firebase_dynamic_links_test.dart | 13 ------- 9 files changed, 186 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 19ae2c141e09..98247ec7e909 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -134,11 +134,6 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re DynamicLink.Builder urlBuilder = setupParameters(call.arguments()); methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); break; - case "FirebaseDynamicLinks#shortenUrl": - DynamicLink.Builder builder = FirebaseDynamicLinks.getInstance().createDynamicLink(); - builder.setLongLink(Uri.parse(call.argument("url"))); - methodCallTask = buildShortLink(builder, call.argument("dynamicLinkParametersOptions")); - break; case "FirebaseDynamicLinks#getDynamicLink": case "FirebaseDynamicLinks#getInitialLink": methodCallTask = getDynamicLink(dynamicLinks, call.argument("url")); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index f9c2be0d1577..f4b0828a62f8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -131,40 +131,6 @@ void runInstanceTests() { }); }); - group('shortenUrl', () { - test('build url and shorten', () async { - FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; - const String androidPackageName = - 'io.flutter.plugins.firebasedynamiclinksexample'; - const String iosBundleId = - 'io.flutter.plugins.firebase.dynamiclinksexample'; - const String urlHost = 'reactnativefirebase.page.link'; - const String link = 'https://invertase.io'; - - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://$urlHost', - link: Uri.parse(link), - androidParameters: const AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), - iosParameters: const IOSParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await dynamicLinks.buildLink(parameters); - final ShortDynamicLink shortLink = await dynamicLinks.shortenUrl(uri); - - expect(shortLink, isA()); - expect(shortLink.shortUrl, isA()); - }); - }); - group('getInitialLink', () { test('initial link', () async { PendingDynamicLinkData? pendingLink = diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index b7ce922ae02b..1641c68d83a6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -141,8 +141,6 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result [self buildUrl:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#buildShortLink" isEqualToString:call.method]) { [self buildShortLink:call.arguments withMethodCallResult:methodCallResult]; - } else if ([@"FirebaseDynamicLinks#shortenUrl" isEqualToString:call.method]) { - [self shortenUrl:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { [self getInitialLink:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getDynamicLink" isEqualToString:call.method]) { @@ -180,30 +178,6 @@ - (void)buildShortLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCall }]; } -- (void)shortenUrl:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { - FIRDynamicLinkComponentsOptions *options = [self setupOptions:arguments]; - NSURL *url = [NSURL URLWithString:arguments[kUrl]]; - - [FIRDynamicLinkComponents - shortenURL:url - options:options - completion:^(NSURL *_Nullable shortURL, NSArray *_Nullable warnings, - NSError *_Nullable error) { - if (error != nil) { - result.error(nil, nil, nil, error); - } else { - if (warnings == nil) { - warnings = [NSMutableArray array]; - } - - result.success(@{ - kUrl : [shortURL absoluteString], - @"warnings" : warnings, - }); - } - }]; -} - - (void)getInitialLink:(FLTFirebaseMethodCallResult *)result { _initiated = YES; NSMutableDictionary *dict = getDictionaryFromDynamicLink(_initialLink); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index cdb96a355c35..14276d899e4c 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -72,14 +72,6 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { return _delegate.onLink; } - /// Returns the shortened Dynamic Link, link flow chart, and warnings from the requested Dynamic Link. - Future shortenUrl( - Uri url, [ - DynamicLinkParametersOptions? options, - ]) async { - return _delegate.shortenUrl(url, options); - } - /// Creates a Dynamic Link from the parameters. Future buildLink(DynamicLinkParameters parameters) async { return _delegate.buildLink(parameters); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index c7299b3ca897..b56247dd3016 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -190,35 +190,6 @@ void main() { }); }); - group('shortenUrl', () { - test('shortenUrl', () async { - final Uri mockUri = Uri.parse('shortenUrl'); - final Uri previewLink = Uri.parse('previewLink'); - List warnings = ['warning']; - const DynamicLinkParametersOptions options = - DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, - ); - - when(dynamicLinks.shortenUrl(mockUri, options)).thenAnswer( - (_) async => ShortDynamicLink( - shortUrl: mockUri, - warnings: warnings, - previewLink: previewLink, - ), - ); - - final shortDynamicLink = - await dynamicLinks.shortenUrl(mockUri, options); - - expect(shortDynamicLink.previewLink, previewLink); - expect(shortDynamicLink.warnings, warnings); - expect(shortDynamicLink.shortUrl, mockUri); - - verify(dynamicLinks.shortenUrl(mockUri, options)); - }); - }); - group('buildLink', () { test('buildLink', () async { final Uri mockUri = Uri.parse('buildLink'); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index ee6a524cdf26..1cfeacb9178d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -133,28 +133,6 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { return _onLinkController.stream; } - @override - Future shortenUrl( - Uri url, [ - DynamicLinkParametersOptions? options, - ]) async { - try { - final Map? reply = - await MethodChannelFirebaseDynamicLinks.channel - .invokeMapMethod( - 'FirebaseDynamicLinks#shortenUrl', - _withChannelDefaults({ - 'url': url.toString(), - 'dynamicLinkParametersOptions': options?.asMap(), - }), - ); - - return _parseShortLink(reply!); - } catch (e, s) { - throw convertPlatformException(e, s); - } - } - @override Future buildLink(DynamicLinkParameters parameters) async { try { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 49260312ead2..3171a7e50209 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -79,17 +79,6 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { throw UnimplementedError('getDynamicLink() is not implemented'); } - /// Shortens a Dynamic Link URL. - /// - /// This method may be used for shortening a custom URL that was not generated - /// using [DynamicLinkBuilder]. - Future shortenUrl( - Uri url, [ - DynamicLinkParametersOptions? options, - ]) async { - throw UnimplementedError('shortenUrl() is not implemented'); - } - /// Generate a long Dynamic Link URL. Future buildLink(DynamicLinkParameters parameters) async { throw UnimplementedError('buildLink() is not implemented'); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index 566c1f17a8dd..76ff849d5985 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -233,45 +233,7 @@ void main() { () => dynamicLinks.getDynamicLink(argument)); }); }); - group('shortenUrl()', () { - test('shortenUrl', () async { - final Uri url = Uri.parse('google.com'); - const DynamicLinkParametersOptions options = - DynamicLinkParametersOptions( - shortDynamicLinkPathLength: - ShortDynamicLinkPathLength.unguessable); - await dynamicLinks.shortenUrl(url, options); - - expect(logger, [ - isMethodCall( - 'FirebaseDynamicLinks#shortenUrl', - arguments: { - 'url': url.toString(), - 'appName': '[DEFAULT]', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, - }, - ), - ]); - }); - - test( - 'catch a [PlatformException] error and throws a [FirebaseException] error', - () async { - mockPlatformExceptionThrown = true; - final Uri url = Uri.parse('google.com'); - const DynamicLinkParametersOptions options = - DynamicLinkParametersOptions( - shortDynamicLinkPathLength: - ShortDynamicLinkPathLength.unguessable); - - await testExceptionHandling( - () => dynamicLinks.shortenUrl(url, options)); - }); - }); group('buildLink()', () { test('buildLink', () async { DynamicLinkParameters options = buildDynamicLinkParameters(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart index f2eff945144d..e56cedcd2e4a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/platform_interface_tests/platform_interface_firebase_dynamic_links_test.dart @@ -111,19 +111,6 @@ void main() { ); }); - test('throws if .shortenUrl', () { - expect( - () => firebaseDynamicLinksPlatformPlatform!.shortenUrl(link), - throwsA( - isA().having( - (e) => e.message, - 'message', - 'shortenUrl() is not implemented', - ), - ), - ); - }); - test('throws if .buildLink', () { expect( () => firebaseDynamicLinksPlatformPlatform!.buildLink(parameters), From f4d612cca20ac90698d5af1584595fdae90694aa Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Mon, 29 Nov 2021 16:20:56 +0000 Subject: [PATCH 101/125] docs(dynamic_links): remove shortenUrl() in CHANGELOG.md --- .../firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index b5768f0d7dd1..f66307b71d06 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -9,6 +9,7 @@ documentation and updating unit and end-to-end tests. - **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. - **BREAKING**: `DynamicLinkParameters` class has been removed. `buildLink()` (replaces `buildUrl()`) & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. +- **BREAKING**: `DynamicLinkParameters.shortenUrl()` has been removed entirely. - **NEW**: `buildLink()` which replaces the previous `DynamicLinkParameters().buildUrl()` - **NEW**: `buildShortLink()` which replaces the previous `DynamicLinkParameters().buildShortLink()` From 08e80b382a1a03ed79747a36cf78684c8bc49872 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 30 Nov 2021 08:57:43 +0000 Subject: [PATCH 102/125] docs(dynamic_links): made a start --- docs/dynamic-links/usage.mdx | 82 +++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index fe326001b969..7da47330c575 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -1,12 +1,90 @@ --- -title: Using Dynamic Links +title: Dynamic Links sidebar_label: Usage --- -## Getting started +To start using the Dynamic Links package within your project, import it at the top of your project files: + +```dart +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +``` + +Before using Dynamic Links, you must first have ensured you have [initialized FlutterFire](../overview.mdx#initializing-flutterfire). + +To create a new Dynamic Links instance, call the [`instance`](!firebase_dynamic_links.FirebaseDynamicLinks.instance) getter on [`FirebaseDynamicLinks`](!firebase_dynamic_links.FirebaseDynamicLinks): + +```dart +FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; +``` + +By default, this allows you to interact with Dynamic Links using the default Firebase App used whilst installing FlutterFire on your +platform. + + +On `Android`, if you'd like to use Dynamic Links with a secondary Firebase App, use the [`instanceFor`](!firebase_dynamic_links.FirebaseDynamicLinks.instanceFor) method: + +```dart +// Android only +FirebaseApp secondaryApp = Firebase.app('SecondaryApp'); +FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instanceFor(app: secondaryApp); +``` ## Create a Dynamic Link +### Build Dynamic Link + +To build a dynamic link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dynamic_links.buildLink) API in your application code like so: + +```dart highlight={18} +final DynamicLinkParameters parameters = DynamicLinkParameters( + // The Firebase URI domain queried. You can view created URIs on your Firebase console + uriPrefix: 'https://example.page.link', + // The Dynamic Link passed to your application which you can use to affect change + link: Uri.parse('https://www.example.com/view-to-open'), + // Android application details needed for opening correct app on device/Play Store + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + // iOS application details needed for opening correct app on device/App Store + iosParameters: const IOSParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await dynamicLinks.buildLink(parameters); +``` + +### Build Short Dynamic Link + +You can also build a short dynamic link which makes the clickable URL shorter. This does entail an additional native SDK +request to the Firebase server whilst the above `buildLink()` does not. To build a short dynamic link, use the +[`FirebaseDynamicLinks.buildShortLink`](!firebase_dynamic_links.buildShortLink) API in your application code like so: + +```dart highlight={18} +final DynamicLinkParameters parameters = DynamicLinkParameters( + // The Firebase URI domain queried. You can view created URIs on your Firebase console + uriPrefix: 'https://example.page.link', + // The Dynamic Link passed to your application which you can use to affect change + link: Uri.parse('https://www.example.com/view-to-open'), + // Android application details needed for opening correct app on device/Play Store + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + // iOS application details needed for opening correct app on device/App Store + iosParameters: const IOSParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), + ); + + final Uri uri = await dynamicLinks.buildShortLink(parameters); +``` + ## Listening for Dynamic Links + + ## Get Dynamic Link From a0d72162762d78072306712748d1b57b57c8c16f Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 30 Nov 2021 10:58:28 +0000 Subject: [PATCH 103/125] chore(dynamic_links): update example --- .../firebase_dynamic_links/example/lib/main.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 9868ce17d5c2..df70c1ed9807 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -59,6 +59,7 @@ class _MainScreenState extends State<_MainScreen> { 'details.'; final String DynamicLink = 'https://test-app/helloworld'; + final String Link = "https://reactnativefirebase.page.link/bFkn"; @override void initState() { @@ -150,7 +151,7 @@ class _MainScreenState extends State<_MainScreen> { // the dynamic link. final PendingDynamicLinkData? data = await dynamicLinks - .getDynamicLink(Uri.parse(DynamicLink)); + .getDynamicLink(Uri.parse(Link)); final Uri? deepLink = data?.link; if (deepLink != null) { From 4720f056c35474624d142fba88b521d2659ace4e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 30 Nov 2021 11:01:20 +0000 Subject: [PATCH 104/125] chore(dynamic_links): update example --- .../firebase_dynamic_links/example/lib/main.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index df70c1ed9807..b71b64ef5cfa 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -132,8 +132,6 @@ class _MainScreenState extends State<_MainScreen> { children: [ ElevatedButton( onPressed: () async { - // comment out the above onLink() event listener to test `getInitialLink()` when your app is first opened pressing - // the dynamic link. final PendingDynamicLinkData? data = await dynamicLinks.getInitialLink(); final Uri? deepLink = data?.link; @@ -147,8 +145,6 @@ class _MainScreenState extends State<_MainScreen> { ), ElevatedButton( onPressed: () async { - // comment out the above onLink() event listener to test `getDynamicLink(url)` when your app is first opened pressing - // the dynamic link. final PendingDynamicLinkData? data = await dynamicLinks .getDynamicLink(Uri.parse(Link)); From 9e69929ba3d4f2abaa07a22a7264b1b234deed6e Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 30 Nov 2021 11:10:40 +0000 Subject: [PATCH 105/125] docs(dynamic_links): how to use --- docs/dynamic-links/usage.mdx | 114 ++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 35 deletions(-) diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index 7da47330c575..d9978c5a1777 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -37,23 +37,23 @@ To build a dynamic link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dy ```dart highlight={18} final DynamicLinkParameters parameters = DynamicLinkParameters( - // The Firebase URI domain queried. You can view created URIs on your Firebase console - uriPrefix: 'https://example.page.link', - // The Dynamic Link passed to your application which you can use to affect change - link: Uri.parse('https://www.example.com/view-to-open'), - // Android application details needed for opening correct app on device/Play Store - androidParameters: const AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - // iOS application details needed for opening correct app on device/App Store - iosParameters: const IOSParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await dynamicLinks.buildLink(parameters); + // The Firebase URI domain queried. You can view created URIs on your Firebase console + uriPrefix: 'https://example.page.link', + // The Dynamic Link passed to your application which you can use to affect change + link: Uri.parse('https://www.example.com/view-to-open'), + // Android application details needed for opening correct app on device/Play Store + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + // iOS application details needed for opening correct app on device/App Store + iosParameters: const IOSParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), +); + +final Uri uri = await dynamicLinks.buildLink(parameters); ``` ### Build Short Dynamic Link @@ -64,27 +64,71 @@ request to the Firebase server whilst the above `buildLink()` does not. To buil ```dart highlight={18} final DynamicLinkParameters parameters = DynamicLinkParameters( - // The Firebase URI domain queried. You can view created URIs on your Firebase console - uriPrefix: 'https://example.page.link', - // The Dynamic Link passed to your application which you can use to affect change - link: Uri.parse('https://www.example.com/view-to-open'), - // Android application details needed for opening correct app on device/Play Store - androidParameters: const AndroidParameters( - packageName: androidPackageName, - minimumVersion: 1, - ), - // iOS application details needed for opening correct app on device/App Store - iosParameters: const IOSParameters( - bundleId: iosBundleId, - minimumVersion: '2', - ), - ); - - final Uri uri = await dynamicLinks.buildShortLink(parameters); + // The Firebase URI domain queried. You can view created URIs on your Firebase console + uriPrefix: 'https://example.page.link', + // The Dynamic Link passed to your application which you can use to affect change + link: Uri.parse('https://www.example.com/view-to-open'), + // Android application details needed for opening correct app on device/Play Store + androidParameters: const AndroidParameters( + packageName: androidPackageName, + minimumVersion: 1, + ), + // iOS application details needed for opening correct app on device/App Store + iosParameters: const IOSParameters( + bundleId: iosBundleId, + minimumVersion: '2', + ), +); + +final Uri uri = await FirebaseDynamicLinks.instance.buildShortLink(parameters); ``` +## Get Dynamic Link + +If the application is in a background state/quit, use the [`FirebaseDynamicLinks.getInitialLink`](!firebase_dynamic_links.getInitialLink) +to retrieve the dynamic link that opened the application or brought it to the foreground from a background state. + +```dart highlight={2} +final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getInitialLink(); +final Uri? deepLink = data?.link; + +if (deepLink != null) { + // Example of using the dynamic link to push the user to a different view + Navigator.pushNamed(context, deepLink.path); +} +``` + +Alternatively, if you wish to select an exact dynamic link from your application, you may also pass the pressed URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) +like so: + +```dart highlight={3} +String Link = 'https://dynamic-link-domain/ke2Qa'; +final PendingDynamicLinkData? data = + await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(Link)); +final Uri? deepLink = data?.link; + +if (deepLink != null) { + // Example of using the dynamic link to push the user to a different view + Navigator.pushNamed(context, deepLink.path); +} +``` + + ## Listening for Dynamic Links +Whilst the application is open, you may listen to dynamic links using this stream handler [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) + +```dart highlight={1} +FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { + if (dynamicLinkData != null && dynamicLinkData.link != null) { + Navigator.pushNamed(context, dynamicLinkData.link.path); + } +}).onError((error) { + // Handle errors +}); +``` + + -## Get Dynamic Link From e24509ec59dea53e7fa5ec8c4a80e9ac005a81c4 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Tue, 30 Nov 2021 12:09:19 +0000 Subject: [PATCH 106/125] docs(dynamic_links): update --- docs/dynamic-links/android-integration.mdx | 21 +++++ docs/dynamic-links/apple-integration.mdx | 50 +++++++++++ docs/dynamic-links/overview.mdx | 100 +++++++++++++++++++++ docs/dynamic-links/usage.mdx | 13 +-- docs/sidebars.js | 8 ++ website/plugins.js | 3 +- 6 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 docs/dynamic-links/android-integration.mdx create mode 100644 docs/dynamic-links/apple-integration.mdx create mode 100644 docs/dynamic-links/overview.mdx diff --git a/docs/dynamic-links/android-integration.mdx b/docs/dynamic-links/android-integration.mdx new file mode 100644 index 000000000000..af3cecfdc72a --- /dev/null +++ b/docs/dynamic-links/android-integration.mdx @@ -0,0 +1,21 @@ +--- +title: Android Dynamic Links Setup +sidebar_label: Android Integration +description: Android requires additional configuration steps to be completed before you can receive dynamic links. +--- + +## Configure your App in the Firebase Console + +Create a SHA-256 fingerprint using these [instructions](https://developers.google.com/android/guides/client-auth) for your app, +and add to your app in your Firebase console. + +TODO - image + +Go to the following location in your browser "[your-domain]/.well-known/assetlinks.json". The response will have a target object +containing a "package_name" which ought to have your app's package name. Please do not proceed until you see this, it may take a while to register. + +## AndroidManifest.xml Configuration + +Add your deep link domains to your "android/app/src/main/AndroidManifest.xml" so your app can receive the Dynamic Link data after it is installed/updated +from the Play Store Refer to the official docs to illustrate [setup](https://firebase.google.com/docs/dynamic-links/android/receive#add-an-intent-filter-for-deep-links). + diff --git a/docs/dynamic-links/apple-integration.mdx b/docs/dynamic-links/apple-integration.mdx new file mode 100644 index 000000000000..6e52a44eff49 --- /dev/null +++ b/docs/dynamic-links/apple-integration.mdx @@ -0,0 +1,50 @@ +--- +title: iOS Dynamic Links Setup +sidebar_label: Apple Integration +description: iOS requires additional configuration steps to be completed before you can receive dynamic links. +--- + +## Apple Account + +To setup Dynamic Links on iOS, it is a prerequisite that you have an Apple developer account [setup](https://developer.apple.com/programs/enroll/). + +## Configure your App in the Firebase Console + +Add an "App Store ID" & "Team ID" to your app in your Firebase console. If you do not have an "App Store ID" yet, you can put any number in here for now. +Your "Team ID" can be found in your Apple developer console. + +TODO - image + +Test the domain (e.g. `https://your-dynamic-link-domain`) you have created in your Firebase console. Go to the following location in your browser "[your domain]/apple-app-site-association". +The response will have a details array property containing an object that has the property "appID". That will be your app's app ID (It may take some time for +your domain to register). Please ensure it is registered before proceeding. + +TODO - image + +## Apple Developer Console + +Create a provisioning profile for your app. Please ensure you've enabled the "Associated Domain" capability which you should check before proceeding. + +TODO - image + +## Project Opened on Xcode + +Open your app under the "TARGETS" header. Click the "Signing & Capabilities" tab. You will need to ensure your "Team" is registered, and your "Provisioning Profile" field is completed. +Please add the domain you created in your Firebase console to the "Associated Domains" and prefix with "applinks:" + +TODO - image + +Click the "Info" tab, and add a "URL Type" to your project. The "Identifier" can be called "Bundle Id" or whatever you wish. Add your bundle identifier to the "URL Schemes" property. + + +## Dynamic Links With Custom Domains + +If you have set up a custom domain for your Firebase project, you must add the dynamic link URL prefix into your iOS project's "Info.plist" file by using the "FirebaseDynamicLinksCustomDomains" key. +You can add multiple URLs as well. + +TODO - image + +## Test Dynamic Links + +To test your dynamic link, you will need to use a real device as it will not work on a simulator. You will also have to run the app in release mode (i.e. "flutter run --release") as iOS will block you from opening +the app in debug mode from a dynamic link. diff --git a/docs/dynamic-links/overview.mdx b/docs/dynamic-links/overview.mdx new file mode 100644 index 000000000000..e9dbf5ae5f04 --- /dev/null +++ b/docs/dynamic-links/overview.mdx @@ -0,0 +1,100 @@ +--- +title: Dynamic Links for Firebase +sidebar_label: Overview +--- + +## What does it do? + +Dynamic Links are links that work the way you want, on multiple platforms, and whether or not your app is already installed. +If a user opens a Dynamic Link on iOS or Android, they can be taken directly to the linked content in your native app. +If a user doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts +and can access the link. + + + +## Installation + + + + + + +Ensure you're using the Flutter `stable` channel: + +```bash +$ flutter channel stable +``` + +If your app is mixing legacy and null-safe packages, use the `--no-sound-null-safety` flag: +```bash +$ flutter run --no-sound-null-safety +``` + +For legacy package imports, place the following ignore comment to hide Dart analyzer warnings: + +```dart +// ignore: import_of_legacy_library_into_null_safe +import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; +``` + + + +### 1. Add dependency + + + + +```yaml {5} title="pubspec.yaml" +dependencies: + flutter: + sdk: flutter + firebase_core: "^{{ plugins.firebase_core }}" + firebase_analytics: "^{{ plugins.firebase_dynamic_links }}" +``` + + + + +```yaml {5} title="pubspec.yaml" +dependencies: + flutter: + sdk: flutter + firebase_core: "^{{ plugins.firebase_core }}" + firebase_dynamic_links: "^{{ plugins.firebase_dynamic_links_ns }}" +``` + + + + +### 2. Download dependency + +``` +$ flutter pub get +``` + +### 4. Rebuild your app + +Once complete, rebuild your Flutter application: + +```bash +$ flutter run +``` + +## Next Steps + +Once installed, you ought to follow the platform specific setup for [android](android-integration.mdx) or [iOS](apple-integration.mdx) +before heading over to the [Usage documentation](usage.mdx). diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index d9978c5a1777..f73a7caf04cf 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -37,9 +37,9 @@ To build a dynamic link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dy ```dart highlight={18} final DynamicLinkParameters parameters = DynamicLinkParameters( - // The Firebase URI domain queried. You can view created URIs on your Firebase console + // The Dynamic Link URI domain. You can view created URIs on your Firebase console uriPrefix: 'https://example.page.link', - // The Dynamic Link passed to your application which you can use to affect change + // The deep Link passed to your application which you can use to affect change link: Uri.parse('https://www.example.com/view-to-open'), // Android application details needed for opening correct app on device/Play Store androidParameters: const AndroidParameters( @@ -58,15 +58,15 @@ final Uri uri = await dynamicLinks.buildLink(parameters); ### Build Short Dynamic Link -You can also build a short dynamic link which makes the clickable URL shorter. This does entail an additional native SDK +You can also build a short dynamic link which simply makes the dynamic link URL shorter. This does entail an additional native SDK request to the Firebase server whilst the above `buildLink()` does not. To build a short dynamic link, use the [`FirebaseDynamicLinks.buildShortLink`](!firebase_dynamic_links.buildShortLink) API in your application code like so: ```dart highlight={18} final DynamicLinkParameters parameters = DynamicLinkParameters( - // The Firebase URI domain queried. You can view created URIs on your Firebase console + // The Dynamic Link URI domain. You can view created URIs on your Firebase console uriPrefix: 'https://example.page.link', - // The Dynamic Link passed to your application which you can use to affect change + // The deep Link passed to your application which you can use to affect change link: Uri.parse('https://www.example.com/view-to-open'), // Android application details needed for opening correct app on device/Play Store androidParameters: const AndroidParameters( @@ -99,7 +99,7 @@ if (deepLink != null) { } ``` -Alternatively, if you wish to select an exact dynamic link from your application, you may also pass the pressed URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) +Alternatively, if you wish to select an exact dynamic link from your application, you may also pass the Dynamic Link URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) like so: ```dart highlight={3} @@ -118,6 +118,7 @@ if (deepLink != null) { ## Listening for Dynamic Links Whilst the application is open, you may listen to dynamic links using this stream handler [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) +like so: ```dart highlight={1} FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { diff --git a/docs/sidebars.js b/docs/sidebars.js index 66fa94bd6cd6..f2e0f20a8505 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -87,6 +87,14 @@ module.exports = { toReferenceAPI("firebase_crashlytics"), toGithubExample("firebase_crashlytics"), ], + 'Dynamic Links': [ + "dynamic-links/overview", + "dynamic-links/usage", + "dynamic-links/android-integration", + "dynamic-links/apple-integration", + toReferenceAPI("firebase_dynamic_links"), + toGithubExample("firebase_dynamic_links"), + ], "Realtime Database": [ "database/overview", toReferenceAPI("firebase_database"), diff --git a/website/plugins.js b/website/plugins.js index 39b103160e81..c16184dbddfb 100644 --- a/website/plugins.js +++ b/website/plugins.js @@ -136,8 +136,7 @@ module.exports = [ pub: 'firebase_dynamic_links', firebase: 'dynamic-links', status: 'Beta', - documentation: - 'https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_dynamic_links/README.md', + documentation: 'https://firebase.flutter.dev/docs/database/overview', support: { web: false, mobile: true, From d78be1b62df379d29cfe737b827fea091d346cdd Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 1 Dec 2021 13:52:54 +0000 Subject: [PATCH 107/125] chore(DL): rm dead code --- .../test/firebase_dynamic_links_test.dart | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index b56247dd3016..02558524d95f 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -353,30 +353,6 @@ class MockFirebaseDynamicLinks extends Mock ); } - @override - Future shortenUrl( - Uri uri, [ - DynamicLinkParametersOptions? options, - ]) { - return super.noSuchMethod( - Invocation.method(#shortenUrl, [uri, options]), - returnValue: Future.value( - ShortDynamicLink( - shortUrl: uri, - warnings: ['warning'], - previewLink: Uri.parse('preview'), - ), - ), - returnValueForMissingStub: Future.value( - ShortDynamicLink( - shortUrl: uri, - warnings: ['warning'], - previewLink: Uri.parse('preview'), - ), - ), - ); - } - @override Future buildShortLink(DynamicLinkParameters parameters) { return super.noSuchMethod( From 51aef0c44442c15110eb1b7596c035c6381defab Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 1 Dec 2021 13:53:06 +0000 Subject: [PATCH 108/125] chore(DL): analyse issue --- .../firebase_dynamic_links/example/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index b71b64ef5cfa..cf6c2dbe3ac1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -59,7 +59,7 @@ class _MainScreenState extends State<_MainScreen> { 'details.'; final String DynamicLink = 'https://test-app/helloworld'; - final String Link = "https://reactnativefirebase.page.link/bFkn"; + final String Link = 'https://reactnativefirebase.page.link/bFkn'; @override void initState() { From 55be4b30c329f3d0c0ca9db70e85a9f675a1d7d5 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Wed, 1 Dec 2021 14:02:13 +0000 Subject: [PATCH 109/125] chore(DL): remove dead code & update refactored --- .../dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java | 4 ++-- .../example/test_driver/instance_e2e.dart | 2 +- .../ios/Classes/FLTFirebaseDynamicLinksPlugin.m | 4 ++-- .../method_channel_firebase_dynamic_links_test.dart | 6 ++---- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 98247ec7e909..9cf858666f35 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -127,7 +127,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re switch (call.method) { case "FirebaseDynamicLinks#buildLink": - String url = buildUrl(call.arguments()); + String url = buildLink(call.arguments()); result.success(url); return; case "FirebaseDynamicLinks#buildShortLink": @@ -157,7 +157,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re }); } - private String buildUrl(Map arguments) { + private String buildLink(Map arguments) { DynamicLink.Builder urlBuilder = setupParameters(arguments); return urlBuilder.buildDynamicLink().getUri().toString(); diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index f4b0828a62f8..744e2313a298 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -23,7 +23,7 @@ void runInstanceTests() { }); }); - group('buildUrl', () { + group('buildLink', () { test('build normal dynamic links', () async { FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance; const String androidPackageName = diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 1641c68d83a6..30a5ca7902d1 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -138,7 +138,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } if ([@"FirebaseDynamicLinks#buildLink" isEqualToString:call.method]) { - [self buildUrl:call.arguments withMethodCallResult:methodCallResult]; + [self buildLink:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#buildShortLink" isEqualToString:call.method]) { [self buildShortLink:call.arguments withMethodCallResult:methodCallResult]; } else if ([@"FirebaseDynamicLinks#getInitialLink" isEqualToString:call.method]) { @@ -152,7 +152,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result #pragma mark - Firebase Dynamic Links API -- (void)buildUrl:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { +- (void)buildLink:(id)arguments withMethodCallResult:(FLTFirebaseMethodCallResult *)result { FIRDynamicLinkComponents *components = [self setupParameters:arguments]; result.success([components.url absoluteString]); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index 76ff849d5985..f72f5462aada 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -95,12 +95,10 @@ void main() { 'warnings': ['This is only a test link'], }; switch (call.method) { - case 'FirebaseDynamicLinks#buildUrl': + case 'FirebaseDynamicLinks#buildLink': return 'google.com'; case 'FirebaseDynamicLinks#buildShortLink': return returnUrl; - case 'FirebaseDynamicLinks#shortenUrl': - return returnUrl; case 'FirebaseDynamicLink#onLinkSuccess': const String name = 'FirebaseDynamicLink#onLinkSuccess'; handleEventChannel(name, logger); @@ -242,7 +240,7 @@ void main() { expect(logger, [ isMethodCall( - 'FirebaseDynamicLinks#buildUrl', + 'FirebaseDynamicLinks#buildLink', arguments: { 'appName': '[DEFAULT]', 'uriPrefix': 'https://', From 397b8e30db66b498fe8007d78d45629ee1269de8 Mon Sep 17 00:00:00 2001 From: Russell Wheatley Date: Thu, 2 Dec 2021 09:49:32 +0000 Subject: [PATCH 110/125] consistent capitalisation in usage.mdx --- docs/dynamic-links/usage.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index f73a7caf04cf..eb4555381831 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -33,7 +33,7 @@ FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instanceFor(app: second ### Build Dynamic Link -To build a dynamic link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dynamic_links.buildLink) API in your application code like so: +To build a Dynamic Link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dynamic_links.buildLink) API in your application code like so: ```dart highlight={18} final DynamicLinkParameters parameters = DynamicLinkParameters( @@ -58,8 +58,8 @@ final Uri uri = await dynamicLinks.buildLink(parameters); ### Build Short Dynamic Link -You can also build a short dynamic link which simply makes the dynamic link URL shorter. This does entail an additional native SDK -request to the Firebase server whilst the above `buildLink()` does not. To build a short dynamic link, use the +You can also build a short Dynamic Link which simply makes the Dynamic Link URL shorter. This does entail an additional native SDK +request to the Firebase server whilst the above `buildLink()` does not. To build a short Dynamic Link, use the [`FirebaseDynamicLinks.buildShortLink`](!firebase_dynamic_links.buildShortLink) API in your application code like so: ```dart highlight={18} @@ -86,7 +86,7 @@ final Uri uri = await FirebaseDynamicLinks.instance.buildShortLink(parameters); ## Get Dynamic Link If the application is in a background state/quit, use the [`FirebaseDynamicLinks.getInitialLink`](!firebase_dynamic_links.getInitialLink) -to retrieve the dynamic link that opened the application or brought it to the foreground from a background state. +to retrieve the Dynamic Link that opened the application or brought it to the foreground from a background state. ```dart highlight={2} final PendingDynamicLinkData? data = @@ -99,7 +99,7 @@ if (deepLink != null) { } ``` -Alternatively, if you wish to select an exact dynamic link from your application, you may also pass the Dynamic Link URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) +Alternatively, if you wish to select an exact Dynamic Link from your application, you may also pass the Dynamic Link URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) like so: ```dart highlight={3} @@ -117,7 +117,7 @@ if (deepLink != null) { ## Listening for Dynamic Links -Whilst the application is open, you may listen to dynamic links using this stream handler [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) +Whilst the application is open, you may listen to Dynamic Links using this stream handler [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) like so: ```dart highlight={1} From c7b30598acfb429a7c8c272f5824ae530de54e62 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 2 Dec 2021 10:02:24 +0000 Subject: [PATCH 111/125] docs(DL): update to double quotes to backticks --- docs/dynamic-links/android-integration.mdx | 6 +++--- docs/dynamic-links/apple-integration.mdx | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/dynamic-links/android-integration.mdx b/docs/dynamic-links/android-integration.mdx index af3cecfdc72a..889694da4f7d 100644 --- a/docs/dynamic-links/android-integration.mdx +++ b/docs/dynamic-links/android-integration.mdx @@ -11,11 +11,11 @@ and add to your app in your Firebase console. TODO - image -Go to the following location in your browser "[your-domain]/.well-known/assetlinks.json". The response will have a target object +Go to the following location in your browser `[your-domain]/.well-known/assetlinks.json`. The response will have a target object containing a "package_name" which ought to have your app's package name. Please do not proceed until you see this, it may take a while to register. ## AndroidManifest.xml Configuration -Add your deep link domains to your "android/app/src/main/AndroidManifest.xml" so your app can receive the Dynamic Link data after it is installed/updated -from the Play Store Refer to the official docs to illustrate [setup](https://firebase.google.com/docs/dynamic-links/android/receive#add-an-intent-filter-for-deep-links). +Add your deep link domains to your `android/app/src/main/AndroidManifest.xml` so your app can receive the Dynamic Link data after it is installed/updated +from the Play Store. Refer to the official docs to illustrate [setup](https://firebase.google.com/docs/dynamic-links/android/receive#add-an-intent-filter-for-deep-links). diff --git a/docs/dynamic-links/apple-integration.mdx b/docs/dynamic-links/apple-integration.mdx index 6e52a44eff49..10c8fe67b4c8 100644 --- a/docs/dynamic-links/apple-integration.mdx +++ b/docs/dynamic-links/apple-integration.mdx @@ -10,41 +10,41 @@ To setup Dynamic Links on iOS, it is a prerequisite that you have an Apple devel ## Configure your App in the Firebase Console -Add an "App Store ID" & "Team ID" to your app in your Firebase console. If you do not have an "App Store ID" yet, you can put any number in here for now. -Your "Team ID" can be found in your Apple developer console. +Add an `App Store ID` & `Team ID` to your app in your Firebase console. If you do not have an `App Store ID` yet, you can put any number in here for now. +Your `Team ID` can be found in your Apple developer console. TODO - image -Test the domain (e.g. `https://your-dynamic-link-domain`) you have created in your Firebase console. Go to the following location in your browser "[your domain]/apple-app-site-association". -The response will have a details array property containing an object that has the property "appID". That will be your app's app ID (It may take some time for +Test the domain (e.g. `https://your-dynamic-link-domain`) you have created in your Firebase console. Go to the following location in your browser ``[your domain]/apple-app-site-association`'. +The response will have a details array property containing an object that has the property `appID`'. That will be your app's app ID (It may take some time for your domain to register). Please ensure it is registered before proceeding. TODO - image ## Apple Developer Console -Create a provisioning profile for your app. Please ensure you've enabled the "Associated Domain" capability which you should check before proceeding. +Create a provisioning profile for your app. Please ensure you've enabled the `Associated Domain` capability which you should check before proceeding. TODO - image ## Project Opened on Xcode -Open your app under the "TARGETS" header. Click the "Signing & Capabilities" tab. You will need to ensure your "Team" is registered, and your "Provisioning Profile" field is completed. -Please add the domain you created in your Firebase console to the "Associated Domains" and prefix with "applinks:" +Open your app under the `TARGETS` header. Click the `Signing & Capabilities` tab. You will need to ensure your `Team` is registered, and your `Provisioning Profile` field is completed. +Please add the domain you created in your Firebase console to the `Associated Domains` and prefix with `applinks:` TODO - image -Click the "Info" tab, and add a "URL Type" to your project. The "Identifier" can be called "Bundle Id" or whatever you wish. Add your bundle identifier to the "URL Schemes" property. +Click the `Info` tab, and add a `URL Type` to your project. The `Identifier` can be called `Bundle Id` or whatever you wish. Add your bundle identifier to the `URL Schemes` property. ## Dynamic Links With Custom Domains -If you have set up a custom domain for your Firebase project, you must add the dynamic link URL prefix into your iOS project's "Info.plist" file by using the "FirebaseDynamicLinksCustomDomains" key. +If you have set up a custom domain for your Firebase project, you must add the dynamic link URL prefix into your iOS project's `Info.plist` file by using the `FirebaseDynamicLinksCustomDomains` key. You can add multiple URLs as well. TODO - image ## Test Dynamic Links -To test your dynamic link, you will need to use a real device as it will not work on a simulator. You will also have to run the app in release mode (i.e. "flutter run --release") as iOS will block you from opening +To test your dynamic link, you will need to use a real device as it will not work on a simulator. You will also have to run the app in release mode (i.e. `flutter run --release`) as iOS will block you from opening the app in debug mode from a dynamic link. From 19c9b9b31240c7c9639ffe00142231204703aca1 Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 2 Dec 2021 10:16:45 +0000 Subject: [PATCH 112/125] docs(DL): update dictionary.js --- website/dictionary.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/dictionary.js b/website/dictionary.js index 8ddd556a3baa..9feeff46e1a1 100644 --- a/website/dictionary.js +++ b/website/dictionary.js @@ -14,6 +14,7 @@ module.exports = [ 'acs', 'alloc', 'analytics', + 'applinks', 'apns', 'aps', 'async', @@ -54,6 +55,7 @@ module.exports = [ 'href', 'html', 'http', + 'https', 'img', 'init', 'installable', @@ -86,6 +88,7 @@ module.exports = [ 'untampered', 'untrusted', 'url', + 'uri', 'verifications', 'web.firebase_cdn', 'xml', From 0b1235a4cf2fafa941ea9628f5820734bd04aaba Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 2 Dec 2021 10:28:58 +0000 Subject: [PATCH 113/125] docs(DL): update README.md --- .../firebase_dynamic_links/README.md | 177 +----------------- 1 file changed, 7 insertions(+), 170 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md index e320725e17bf..a08beb5e7ee6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/README.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md @@ -1,182 +1,19 @@ -# Google Dynamic Links for Firebase + +# Firebase Dynamic Links for Flutter [![pub package](https://img.shields.io/pub/v/firebase_dynamic_links.svg)](https://pub.dev/packages/firebase_dynamic_links) -A Flutter plugin to use the [Google Dynamic Links for Firebase API](https://firebase.google.com/docs/dynamic-links/). +A Flutter plugin to use the [Firebase Dynamic Links API](https://firebase.google.com/docs/dynamic-links/). -With Dynamic Links, your users get the best available experience for the platform they open your link on. If a user opens a Dynamic Link on iOS or Android, they can be taken directly to the linked content in your native app. If a user opens the same Dynamic Link in a desktop browser, they can be taken to the equivalent content on your website. +To learn more about Dynamic Links, please visit the [Firebase website](https://firebase.google.com/products/dynamic-links) -In addition, Dynamic Links work across app installs: if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link. +## Getting Started -For Flutter plugins for other Firebase products, see [README.md](https://github.com/FirebaseExtended/flutterfire/blob/master/README.md). +To get started with Dynamic Links for Flutter, please [see the documentation](https://firebase.flutter.dev/docs/dynamic-links/overview). ## Usage -To use this plugin, add `firebase_dynamic_links` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). You must also configure firebase dynamic links for each platform project: Android and iOS (see the example folder for details). - -## Create Dynamic Links - -You create a Dynamic Link either by using the Firebase console, using a REST API, iOS or Android Builder API, Flutter API, or by forming a URL by adding Dynamic Link parameters to a URI prefix specific to your app. These parameters specify the links you want to open, depending on the user's platform and whether your app is installed. - -Below are instructions to create Dynamic Links using Flutter with the Firebase Dynamic Links API. This API accepts either a long Dynamic Link or an object containing Dynamic Link parameters, and returns a URL like the following example: - -``` -https://example.page.link/WXYZ -``` - -You can create a Dynamic Link programmatically by setting the following parameters and using the `DynamicLinkParameters.buildUrl()` method. - -```dart -final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://abc123.app.goo.gl', - link: Uri.parse('https://example.com/'), - androidParameters: AndroidParameters( - packageName: 'com.example.android', - minimumVersion: 125, - ), - iosParameters: IosParameters( - bundleId: 'com.example.ios', - minimumVersion: '1.0.1', - appStoreId: '123456789', - ), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'example-promo', - medium: 'social', - source: 'orkut', - ), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - providerToken: '123456', - campaignToken: 'example-promo', - ), - socialMetaTagParameters: SocialMetaTagParameters( - title: 'Example of a Dynamic Link', - description: 'This link works whether app is installed or not!', - ), -); - -final Uri dynamicUrl = await parameters.buildUrl(); -``` - -To create a short Dynamic Link, build `DynamicLinkParameters` the same way, but use the `DynamicLinkParameters.buildShortLink()` method. - -```dart -final ShortDynamicLink shortDynamicLink = await parameters.buildShortLink(); -final Uri shortUrl = shortDynamicLink.shortUrl; -``` - -To shorten a long Dynamic Link, use the DynamicLinkParameters.shortenUrl method. - -```dart -final ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl( - Uri.parse('https://example.page.link/?link=https://example.com/&apn=com.example.android&ibi=com.example.ios'), - DynamicLinkParametersOptions(ShortDynamicLinkPathLength.unguessable), -); - -final Uri shortUrl = shortenedLink.shortUrl; -``` - -## Handle Received Dynamic Links - -You can receive a Dynamic Link containing a deep link that takes the user to specific content within your app: - -1. In the [Firebase Console](https://console.firebase.google.com), open the Dynamic Links section. - - Accept the terms of service if you are prompted to do so. - - Take note of your project's Dynamic Links URL prefix, which is displayed at the top of the Dynamic Links page. You need your project's Dynamic Links URL prefix to programmatically create Dynamic Links. Unless you are using a custom domain, a Dynamic Links URL prefix looks like `https://YOUR_SUBDOMAIN.page.link`. - -Receiving dynamic links on *iOS* requires a couple more steps than *Android*. If you only want to receive dynamic links on *Android*, skip to step 5. You can also follow a video on the next two steps [here.](https://youtu.be/KLBjAg6HvG0?t=60) - -2. In the **Info** tab of your *iOS* app's Xcode project: - - Create a new **URL Type** to be used for Dynamic Links. - - Set the **Identifier** field to a unique value and the **URL Schemes** field to be your bundle identifier, which is the default URL scheme used by Dynamic Links. - -3. In the **Capabilities** tab of your app's Xcode project, enable **Associated Domains** and add the following to the **Associated Domains** list: - -``` -applinks:YOUR_URL_PREFIX -``` - -Remember not to include `https://` or any slashes or paths in your prefix - -4. **If you are using a custom domain** create an key in your `Info.plist` file called `FirebaseDynamicLinksCustomDomains` and set it to your app's Dynamic Link URL prefixes. For example: - -```xml -FirebaseDynamicLinksCustomDomains - - https://example.com/promos - https://example.com/links/share - -``` -5. If you want to open android app directly without redirecting to Chrome or Any other Browser you can put an `intent-filter` in your `AndroidManifest.xml` file. It will open the system dialogue to open link with your app or other browsers. Users can then directly choose to open the link in your app. - -Note: This step is optional and in case we do not implement this then link will open in chrome at first and then will eventually open your application. -```xml - - - - - - - -``` -6. To receive a dynamic link, call the `getInitialLink()` method from `FirebaseDynamicLinks` which gets the link that opened the app (or null if it was not opened via a dynamic link) -and configure listeners for link callbacks when the application is active or in background calling `onLink`. - -```dart -void main() { - runApp(MaterialApp( - title: 'Dynamic Links Example', - routes: { - '/': (BuildContext context) => MyHomeWidget(), // Default home route - '/helloworld': (BuildContext context) => MyHelloWorldWidget(), - }, - )); -} - -class MyHomeWidgetState extends State { - . - . - . - @override - void initState() { - super.initState(); - this.initDynamicLinks(); - } - - void initDynamicLinks() async { - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData? dynamicLink) async { - final Uri? deepLink = dynamicLink?.link; - - if (deepLink != null) { - Navigator.pushNamed(context, deepLink.path); - } - }, - onError: (OnLinkErrorException e) async { - print('onLinkError'); - print(e.message); - } - ); - - final PendingDynamicLinkData? data = await FirebaseDynamicLinks.instance.getInitialLink(); - final Uri? deepLink = data?.link; - - if (deepLink != null) { - Navigator.pushNamed(context, deepLink.path); - } - } - . - . - . -} -``` - -If your app did not open from a dynamic link, `getInitialLink()` will return `null`. - -## Getting Started - -See the `example` directory for a complete sample app using Google Dynamic Links for Firebase. +To use this plugin, please visit the [Dynamic Links Usage documentation](https://firebase.flutter.dev/docs/dynamic-links/usage) ## Issues and feedback From 1a692951bb2bec35e0c52726666d057145b0c0a9 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Thu, 2 Dec 2021 14:03:42 +0000 Subject: [PATCH 114/125] chore: update docs --- docs/dynamic-links/overview.mdx | 12 +++-- docs/dynamic-links/usage.mdx | 85 +++++++++++++++++++++------------ docs/sidebars.js | 2 +- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/docs/dynamic-links/overview.mdx b/docs/dynamic-links/overview.mdx index e9dbf5ae5f04..40ff7c3d48af 100644 --- a/docs/dynamic-links/overview.mdx +++ b/docs/dynamic-links/overview.mdx @@ -94,7 +94,13 @@ Once complete, rebuild your Flutter application: $ flutter run ``` -## Next Steps +## Platform Integration -Once installed, you ought to follow the platform specific setup for [android](android-integration.mdx) or [iOS](apple-integration.mdx) -before heading over to the [Usage documentation](usage.mdx). +Before using Dynamic Links, ensure you have configured your specific platform: + +- [Android](./android-integration.mdx) +- [Apple](./apple-integration.mdx) + +## Next steps + +Once your platforms have been configured, head over to the [Usage](./usage.mdx) documentation. diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index eb4555381831..3b64a10c173a 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -29,16 +29,29 @@ FirebaseApp secondaryApp = Firebase.app('SecondaryApp'); FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instanceFor(app: secondaryApp); ``` +## Setting up a prefix + +Before using Dynamic Links, ensure you have first created a new link prefix on the +[Firebase Console](https://console.firebase.google.com/project/_/durablelinks). + +For example, the `my-awesome-app.page.link` has been added on this project: + +TODO screenshot + ## Create a Dynamic Link +A dynamic link can be created directly from the Firebase Console, or programatically via the `firebase_dynamic_links` plugin. Once a link has been created, +you can use send them to users (via emails, push notifications, in-app content etc). Upon opening, your application can handle the link however you like, for +example opening a specific screen. + ### Build Dynamic Link To build a Dynamic Link, use the [`FirebaseDynamicLinks.buildLink`](!firebase_dynamic_links.buildLink) API in your application code like so: -```dart highlight={18} +```dart final DynamicLinkParameters parameters = DynamicLinkParameters( // The Dynamic Link URI domain. You can view created URIs on your Firebase console - uriPrefix: 'https://example.page.link', + uriPrefix: 'https://my-awesome-app.page.link', // The deep Link passed to your application which you can use to affect change link: Uri.parse('https://www.example.com/view-to-open'), // Android application details needed for opening correct app on device/Play Store @@ -56,13 +69,16 @@ final DynamicLinkParameters parameters = DynamicLinkParameters( final Uri uri = await dynamicLinks.buildLink(parameters); ``` +The method accepts a `DynamicLinkParameters` instance, which at a minimum requires a `uriPrefix` (defined in the Firebase Console), +along with a `link`, which is passed to your application when a user opens the app via a created link. + ### Build Short Dynamic Link You can also build a short Dynamic Link which simply makes the Dynamic Link URL shorter. This does entail an additional native SDK request to the Firebase server whilst the above `buildLink()` does not. To build a short Dynamic Link, use the [`FirebaseDynamicLinks.buildShortLink`](!firebase_dynamic_links.buildShortLink) API in your application code like so: -```dart highlight={18} +```dart final DynamicLinkParameters parameters = DynamicLinkParameters( // The Dynamic Link URI domain. You can view created URIs on your Firebase console uriPrefix: 'https://example.page.link', @@ -83,44 +99,55 @@ final DynamicLinkParameters parameters = DynamicLinkParameters( final Uri uri = await FirebaseDynamicLinks.instance.buildShortLink(parameters); ``` -## Get Dynamic Link +## Handling Dynamic Links -If the application is in a background state/quit, use the [`FirebaseDynamicLinks.getInitialLink`](!firebase_dynamic_links.getInitialLink) -to retrieve the Dynamic Link that opened the application or brought it to the foreground from a background state. +To handle an Dynamic Link in your application, two scenarios require implementing. -```dart highlight={2} -final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getInitialLink(); -final Uri? deepLink = data?.link; +### Background or Terminated -if (deepLink != null) { - // Example of using the dynamic link to push the user to a different view - Navigator.pushNamed(context, deepLink.path); +If the application is in the background or terminated, the [`FirebaseDynamicLinks.getInitialLink`](!firebase_dynamic_links.getInitialLink) +method allows you to retrieve the Dynamic Link that opened the application or brought it to the foreground. + +This is an asynchronous request, so it make sense to handle a link before rendering application logic, such as +a navigator. For example, you could handle this in the `main` function: + +```dart +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(options: DefaultFirebaseConfig.platformOptions); + + // Get any initial links + final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink(); + + runApp(MyApp(initialLink)); } ``` -Alternatively, if you wish to select an exact Dynamic Link from your application, you may also pass the Dynamic Link URL to [`FirebaseDynamicLinks.getDynamicLink`](!firebase_dynamic_links.getDynamicLink) -like so: +Within your application logic, you can then check whether a link was handled and perform an action, for example: -```dart highlight={3} -String Link = 'https://dynamic-link-domain/ke2Qa'; -final PendingDynamicLinkData? data = - await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(Link)); -final Uri? deepLink = data?.link; - -if (deepLink != null) { - // Example of using the dynamic link to push the user to a different view +```dart +if (initialLink != null) { + final Uri deepLink = initialLink.link; + // Example of using the dynamic link to push the user to a different screen Navigator.pushNamed(context, deepLink.path); } ``` +Alternatively, if you wish to identify if an exact Dynamic Link was used to open the application, pass it to +the `getDynamicLink` method instead: -## Listening for Dynamic Links +```dart +String link = 'https://dynamic-link-domain/ke2Qa'; + +final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(link)); +``` -Whilst the application is open, you may listen to Dynamic Links using this stream handler [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) -like so: +## Realtime handling -```dart highlight={1} +Whilst the application is open, you may listen to Dynamic Links using a stream handler. The [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) +getter returns a `Stream` containing a nullable `PendingDynamicLinkData`: + +```dart FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { if (dynamicLinkData != null && dynamicLinkData.link != null) { Navigator.pushNamed(context, dynamicLinkData.link.path); @@ -129,7 +156,3 @@ FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { // Handle errors }); ``` - - - - diff --git a/docs/sidebars.js b/docs/sidebars.js index f2e0f20a8505..dbf32b8d4657 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -89,9 +89,9 @@ module.exports = { ], 'Dynamic Links': [ "dynamic-links/overview", - "dynamic-links/usage", "dynamic-links/android-integration", "dynamic-links/apple-integration", + "dynamic-links/usage", toReferenceAPI("firebase_dynamic_links"), toGithubExample("firebase_dynamic_links"), ], From cc7a9d9ce26245c1c2c9954c09585e853c8a28e0 Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Thu, 2 Dec 2021 14:06:48 +0000 Subject: [PATCH 115/125] chore: add prefix image example --- docs/_assets/dl-prefix.png | Bin 0 -> 103721 bytes docs/dynamic-links/usage.mdx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/_assets/dl-prefix.png diff --git a/docs/_assets/dl-prefix.png b/docs/_assets/dl-prefix.png new file mode 100644 index 0000000000000000000000000000000000000000..1e84eb9b831c4bb2ea9323dec58a53601b4ee904 GIT binary patch literal 103721 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�bt2<#`INbvn&GqC_vM-1Sfx!iokoq6@cKealkQ~ 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 ## Create a Dynamic Link From 26eec280f79e4214b14c2ba69598e533b40b9b4c Mon Sep 17 00:00:00 2001 From: russellwheatley Date: Thu, 2 Dec 2021 14:23:29 +0000 Subject: [PATCH 116/125] refactore(DL): non nullable stream type --- .../FlutterFirebaseDynamicLinksPlugin.java | 4 +++- .../ios/Classes/FLTFirebaseDynamicLinksPlugin.m | 4 +++- .../test/firebase_dynamic_links_test.dart | 2 +- .../method_channel_firebase_dynamic_links.dart | 13 +++++++++---- .../platform_interface_firebase_dynamic_links.dart | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 9cf858666f35..4671a78ff6ec 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -111,7 +111,9 @@ public boolean onNewIntent(Intent intent) { pendingDynamicLinkData -> { Map dynamicLink = Utils.getMapFromPendingDynamicLinkData(pendingDynamicLinkData); - channel.invokeMethod("FirebaseDynamicLink#onLinkSuccess", dynamicLink); + if (dynamicLink != null) { + channel.invokeMethod("FirebaseDynamicLink#onLinkSuccess", dynamicLink); + } }) .addOnFailureListener( exception -> diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 30a5ca7902d1..1c6b031e7c70 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -286,7 +286,9 @@ - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError * [_channel invokeMethod:@"FirebaseDynamicLink#onLinkError" arguments:flutterError]; } else { NSMutableDictionary *dictionary = getDictionaryFromDynamicLink(dynamicLink); - [_channel invokeMethod:@"FirebaseDynamicLink#onLinkSuccess" arguments:dictionary]; + if (dictionary != nil) { + [_channel invokeMethod:@"FirebaseDynamicLink#onLinkSuccess" arguments:dictionary]; + } } if (_initialLink == nil && dynamicLink.url != nil) { diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 02558524d95f..2a2119a42049 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -375,7 +375,7 @@ class MockFirebaseDynamicLinks extends Mock } @override - Stream get onLink { + Stream get onLink { return super.noSuchMethod( Invocation.getter(#onLink), returnValue: Stream.value(testData), diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index 1cfeacb9178d..c1c7f543b3ae 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -24,7 +24,12 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { case 'FirebaseDynamicLink#onLinkSuccess': Map event = Map.from(call.arguments); - _onLinkController.add(_getPendingDynamicLinkDataFromMap(event)); + PendingDynamicLinkData? data = + _getPendingDynamicLinkDataFromMap(event); + + if (data != null) { + _onLinkController.add(data); + } break; case 'FirebaseDynamicLink#onLinkError': Map error = @@ -50,8 +55,8 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { ); /// The [StreamController] used to update on the latest dynamic link received. - final StreamController _onLinkController = - StreamController.broadcast(); + final StreamController _onLinkController = + StreamController.broadcast(); /// Gets a [FirebaseDynamicLinksPlatform] with specific arguments such as a different /// [FirebaseApp]. @@ -129,7 +134,7 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { } @override - Stream get onLink { + Stream get onLink { return _onLinkController.stream; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 3171a7e50209..38a4447105a7 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -56,7 +56,7 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { } /// Creates a stream for listening whenever a dynamic link becomes available - Stream get onLink { + Stream get onLink { throw UnimplementedError('onLink is not implemented'); } From 92bc1c2db5263202186a5e72717128db1d80dcbf Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Thu, 2 Dec 2021 14:24:46 +0000 Subject: [PATCH 117/125] chore: add docs images --- docs/_assets/dl-apple-configure.jpg | Bin 0 -> 89526 bytes docs/_assets/dl-apple-provision.jpg | Bin 0 -> 208590 bytes docs/_assets/dl-apple-signing.jpg | Bin 0 -> 593662 bytes docs/_assets/dl-apple-urlscheme.jpg | Bin 0 -> 590283 bytes docs/dynamic-links/android-integration.mdx | 16 +++++++-- docs/dynamic-links/apple-integration.mdx | 36 +++++++++++++++------ docs/dynamic-links/usage.mdx | 6 ++-- 7 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 docs/_assets/dl-apple-configure.jpg create mode 100644 docs/_assets/dl-apple-provision.jpg create mode 100644 docs/_assets/dl-apple-signing.jpg create mode 100644 docs/_assets/dl-apple-urlscheme.jpg diff --git a/docs/_assets/dl-apple-configure.jpg b/docs/_assets/dl-apple-configure.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2c747c7ae410ed36e12638dc8a6b1c85ddc43ce7 GIT binary patch literal 89526 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 X)T9NP$|rqMB;X1E|J{HFU;6(Cq_;fc literal 0 HcmV?d00001 diff --git a/docs/_assets/dl-apple-provision.jpg b/docs/_assets/dl-apple-provision.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f14ba82ec97e38aa34cd4c53257b53e9b9dd81eb GIT binary patch literal 208590 zcmeFZdpuO@+c>;L2{DBTF-lU~VajnQj8aJwr3f)e&M`SSLsf-nKcvtQ3-rw)@ywB(P{hs&t{_%d^Z{stwZfo85wXXZRulqW$ zC3-7j0&5Q)usZ;ViHQNH;Xgpc0`m9c0{sBM!2$RM0D#rNN-xN zGT-?t0Ep*{{RvGZ0)YG#f3~GA!)@_D+Y%P=c=#h?$ruMjMxHlEp+X}Jyw76K_!{_N zLr^&H^QfH$J5YcH8h75?C)hVq^Ng>5V5sHh`3A~n&A_vkn_W#Db~v23@eK$(cro19 z`Qnk|J{N<1cAedfw$ik~nd3svhxkT%YvMxAg+`d;EI0oEZVtD^W?>1NN-1GyrXL(V%mm>&#` zh{T4+{9_57eZ&6IIv1$U<*&KZP}6Y7&RyI88WkPj3&Z*^QAfddMtxuPKaoKF zXZ(I#`xg%Rt2@kg-<=~+CNO{wL|JxM@c}X#B{vWojGVPLBtlDgRL-((=o>bc8B-F z?g4DRzdPp>67k)z4+)J7KW4jE^Q4=*rsR7-2G9VcV2j__+b81u9w(>6-(miB`~m;( zA0F+87XS?Ee}`pylr!-8z3I`#;j`Z=i@WCk?)G0dq|d_EF?@*+e+_)jheyIV>A`KS z=*aWm+fHy>F&st;ZlC?$_W!eu``$kDXZz}pKF5#Qz2@muS zh}7J3{`@&#O}kJZ13lOrG~5XQ-)Z-~4*+~Q_5-SzQqw=rVIKm(uRPc(y8h2|XKn#N zT`~Y{p#SsSmOKDJTn2#J*7M%s-haY_f5mtb5q?I7KmHe6g9d<=<08?QZ2%y79RLK^ zMWW>bkw{Pg!yf~H<`~f!VDsGr{6G492l9Ue;QL@vGq7&8goV^)aj|v4igjY*>%>HD z01}?j%0FTMHAS%%;u0%YNv@WXmVrCetOZtxiHon05MQ}cLIUm`2VVyy)~%G^v~$lY zg`?h*o5K_hFI~UCT5IpKmi5Q_!7WB-!V{#Vm6SKAsA_N3*|z-`V-r)eUw4_??Aw39 z_MqJ%=i?__Twy}{ob~nd4+sp3h>W@rjf=UMcsVIKCG|?$jhnY_XJy~HoAaRHVd0~q z$Hh-7tEy{i>z==;Z>6@icXYn$dOa{WG)x|Iy6;p4dOY*E_u~`qSbS*TzU{4MkY5gwqgC zVm}V!-Mzn4P+qnw)8xa;eJlR(*|lNeRc8^V4A2Kue(uD7+ns3f!7+^?$AU=8t*%^` zOv09ND4eL=!d!SUUP?)to7WngqMf~*pQh&9aQ%jMVB^@W1a^QHj#GYEQ{$?fwN+!E zWDB{juDv&PLK>7zASmNyxYD@T$*InYR4a8*nOf#CM>D$-pyb3Do7LFCJD4rWecBgq}QUE;ju}FyczRMSW*HVcYb` zc@K{ub7C86#f)=+)#jVWs;V<}?d^NQIH$Rrs%rKnOsI!%xSy%*xOoRc6H=cn_$MDa{^zKJaz)Q{iB#?@)Q&y9vvT zvV!rh^Ne7lZ%*G%tBL^7!BH7%=pc&ogP-7f+u<|mQ8L&}vQl+}r(@g2^82L>kHCxm zsVmDevsX?Oghg0fjLXq7Df}%oi}%3)q>q#R4haT$9B~!7&T6Hw9j!>%%GcxS_g>~> z?+1AS4!T~IHG>tQAqpp;bXJI#)4|g;y&73ddYt*vC)p8G=Lc9lh43_hi6#1B#wh#y ziL9-lEk^{D;|kid=oWSLu1OYgAg0+6a&A*LvQg|0RLv_YdPeEze9}JnAkOPGE%=Vu z8vWm})?zavpsJTs$0VmBE3GaqJMcYj^s+)8x(-7AZ1oIkkQvWw1NU}aTJL4qYWqN+ z=*OLbWivMemomvAhU48uqqC-2*=7-4A$rwfpS)xRg~C;MYp8^cO=wyT-Oh)|Y|Q1z zdoTUlG}QYCotok_Ivs}fzj~fz1YH|7OH^3+@P<1xvn9(U_befgcjFn-3b#AabSafBObz*$@JID&=Oe@sxo=KQlTeh+Dk~LC7*hbKT+_=g-EL6vqb>_7~J(G@C zCbmQ7^xn=gpA+2dbnWNRFH5}JPmF|S zt#23#JzB0g7}@=6mZ!~$p|iDVAKvR#k9pi9Rnbo!=`UT|y%`8Yub>2BM(26ii6Cw=_q$Eh^4@LfzS(c5ZWy-DFKeec!^Ex{*uTYc8jJe=e)iwC;e^Rr#*>&z)8i zb`eI9RpdF=Rx*~G&CX8ds}u*-mcOB2 z+a(x%Gdc%+B_&am399%2@OE})lM=3bKesc*YKFILDV{__oR+wJ>)%uXMuHvA6x+%HHcI*AHU=;uw6iRh7$r8b2 zSu8qmfm>78PR^iIuZweKQ`%xm^9Cjz>Z^a-kEF_)9jup%V&!VJY{v!`8su=PJQ478 z6k~C0IxN7Hr->{S-_TjKfw$2~k|hG#95c-(v_wEcCIhOZGE>?`z*V8F;6@`N3S6XS zqh%V=J{4{sDT-E`-Q3F}=GJ7yxK_-b6#zNdXrQ{2oej{@s$+c%u!lvZFf3nJKR zS5PJlOM{2@v6d=j?%TBL>RvPeJaT+^5{%j%!USf^HwEBkiq=xJ?`DnveW3dVm zAW?b8VR<*M?=tR{;6B0Z?5{1mxMweGAc}0PH!kv(PH%@t{lV%=M|DqV%!7M-B;|hANcRm9;Lxuh z8B#Utq%(g`o;MJ@<;5QTcLtk3YXjdpc{74M{PyLY#1<`lFz7?gxlMcK%_?(by;~|u z4P|)*_YggX2}ZbRkKrggPL}=U%l3~aER@c7S-#^f`MylbrQLsQe{Q5IK90&=Y^_(G zn_phfKP>{1v{)Ist;$X7Asu#!gZwh}>7EBO7cbz=EX#URJzNu%n}mIpS7k$IkH5I_ z;eCbv$g$gh)RSTXWF=)z0PgMP?S?#<4!SJ_B^q955}lN{k&C!eFcewhc>tq~!F5un zOJ?fJtD<6g_qx+_ZJdWbeIRj^BWfPUb73ST6Tiq)Vz;jxZxu_>MkNk7h3VUs>=p=Xpwc zhFHlSTBZg|rt0|&`6e&!Pdxl$$mQL5P_1r#N1(Np@TYt9@8=$^i$A>wNLbyXvhix9 zu^4xX+B@p(2-z&}gXSldsgw;~5Vi%mKJo%l1FtmrHTWn?-I=ZG*=~%KHy*3Hum$9m z=$Ckn%_^xzCGIJIH~y$FCNkUf<3{n>Z`UWbE9rbL3>eqSR=axc_1;&CV7t^ivDvE% ziPlIx;cIl2=g8bRxQqcmJ)6veNRwDK{2ng0jjVxN!XPS=KX7$Y@vg-+?=l1=!87)% zr*)N8_V(LCk}IMRch`&@)uzz@xCCfIoaLSSxzTLW+$=ZNmU|yWWrzTOhRRIN1i2U? zr;}R1RZeVl^u-oIlP$-Z>2I#)VE9{TrY_SQ8p%kyA9((_3t)foJh1B4D-LwR(^7x>ONR`zf=szI;tLR*+ICxQs;g zzHAN`!}44Oc{+j|Au?FFirldi8eO2I5{$X@nP<3Y;kw(^qz=`RAmS+Uw2(f6|MKY5 z4ngC@J}jCRmpSrj?HbaUBkwE`7B~^y-eyH^KBxe7U}X+l92crvZSzD6*HM%|T5bRQ zCb@n-x##UmPnFVWgQ|d#p5_;V#apLuiO+bb5i8xt#zGB3%JS9tg z@SXMa^UMJ8_lz+!-npB+=YrhEU~m)u3$I%&x6e+wmo1})*rP6QzUZ3$k_MB)@n=GX1mDw(V#J2kcMvNg*r$F)iMt`5TB|l zMrXHt#yJb+(a-@(owl#jDTW9*BLZ6YwpA?Y@SdZmt;O5%5z8CUSBbu`jz(5l5asg+ z{UHCxcq7Wq4%-%IFKRg{CA!wEOddLqtL>Y%J!!gUUrL*5HZS^)hcD0cn%q6!J;Cji zj&a9k0D zdNCZbvbLfG17WG=g-f^+w>v2Qp?Q3IXlwyBZga8C^sJHxZ#|}S2rpPKQKv?X-SFxcwK6`LC=NWjF?MXo zV9SfVof|7XUWrW;t8C|9k%9M6$|ORGzn5lZzz=}hOQ+pC+a1%)o34AadZB~9prGbG zDY?2wr52Ya!0o-+4A|U+}yP zRN!&7(!67fudX%HPS`~RPr@f5jBm8%DhXpkB4G!^ph=sY5qnu=d*e^$SN$fE?#)2o<> zIe+lU;$$>OpDR7aN@*S6?cR^KjAeKCNVa=zuB)S2*o4z^EbmQE$o27UN=3k+W57u;yVrA(#yPS|VKi%3L^>r;5Z}76H}DBEZ}oSVUh!gKiW^o59)6?lEen zNQ!_EMB>tX`aH3+OG*ea*QKjvz=4lD>zM`&Li_71xA*Tm|2 z+8-K@Tuv?jDsXgYO4wbZzPI)BDjZ4=8v;i;-h7&{(|l2zwTpFqGU|+20lc-(&eA`T zSQ%<3xX9EfOSBCrOnk%$cK`IEWMV9^-YUHy&}9Gt1r0Ju8CDy>qSQ}t(8a;IB`1BnJe@6b zT)rl`ATVNOp`eJaxp~&%Mb5CkNvwQM=55ROm!F+_E;(@PU(62VFL(*Ta}jVBODA=Z z6$t9WUUW5ricOy|fy|y5T<7XgC!|MwhOu~)$bpxY?{*y=kae{+yZ$nsE04E_C!8_JndVY>2 zQDLyDx(Y5BPx@p~{^?Wsmb3{voj$S4|M~O0gRJBYf5dEY0yL4gb0qo7%0eku_I##L zT9DJIwtO0A)Ir%m*o>R9gRsn(;w?=GxDug9vdwD8h)D%xTU};AW$UCgt}Moz?DU%9 zs5hFI3Q>vsagUNYQA)KrQrf_>5$`v_Q;MJC+uoKX6p0dq%FvL3^jRo*TxM^p7jn4K zJ0?t-H}aJeAA5<@M8p<5V*RxrU4KNiDtglEUo_Smu|e|1G~pNU(+k%4 z?)IgvRYk#GN;G3Nw8BT>rh!n_P-KV?m7a0yVip;W>D<28R?Vv+lZN+6W=!${1H7L9n4w(J&YZp?Quqrkhy=I#j8C*m{+xjPksxHf!6mD?S zDj&%r{($h#Qr`*^q)Xx}VkL!!$L1}fAZO6%D;g{j0lj#+05M7a`c9#=*$p(S5PN>7 z2rzD7`t2kwYmcMRt?`P)mQzG#0S?W*ksVjh-wr7+A)ylxpJ?$v85uKK(MrBVz7Gdz zF~V48gtaUZbVb3~ZXr_by_i12!06`R#b91+D4K$t#8dvnC{YBcY>&<}hwrNL{jMTl zs!7rqNEAv>!t_$>LV^QzZ#N)6+Y?s#h=3E(kWdjQ_{T*!Fn#q_180Qg*i7kz!^IVy zli%R`u0}J<(csa>>moo_H}(?gTOmVy=T+jU!SuKP+u&Yxf+By70Kta^)E9<$4iEsZ z&6}5CAvcohYu6~vU2tpY79cbob)jCen6I>z-(LOIX zt)T`ruwJU_$J!5nRj@Eu&iH!g!wr2;tCnAHM`pwxv z55$}0Z5m47zrKueQ@y?CH)VORy<$uk3`|sJzQ&g7YFbV27@`#|yD+}j$h3roS&5ef zVJpz2z@f!ncDEPz!u?eZ#e0GZCo^Yw^zET?ez#P%oX%GwvT{X0Xz$X&9dOMB2J#dE z-QN7iE0B;sX{=6oLmtgl7Q*(y1-{90*VK1`o^enuyq&C1cd>H67aZ%rT?J2wh z%$=8T7tMwvkz+Qk#C0a>R@+18_?sqCqhF{R%HW5Z2x+#OzHOV8+|VOhbxBOl;V$jm zs&`Gz-oMD7xF*h^_@PO?+)k?boYm$&KM>oFPSMbAgyOitEmbijInt!QDvjn*{5AH9 z9LI)wu{t`8@lmxh*?vrCRK5L=3*AxMBnQ8Wff&xpoYb6qv)FocclHoS>TX|Lx`oAHzq{7z~m7!O5B#96uA01$@H z1z9lfJQ&gYT)|gl?+!FAj{Ox4%aFtoI~n=6$Fru~(pdcs7H{8J?K@@4T(cm!g=Q9% z9w9OxuSvX$fP4@MMRi!{@t)ZcbQ0i&tjy*so+iF=dIGt2M+gHr8v&qqah6;{#~cM@JEm8VH^glEE8J65_lgFpV?*5CI*1j9T=hOp`Pr zMJR6-u!1SLMPU|*3&WFigqtWWVf;oLYZ(!+rU+gpc$FUJcfoMNKp6ELRp2t5*aeS1 zfJHcBFOhHKn9%tZR^d0|HIbFku=LjvnkEaLiGU5BpffD~uYa*tmYgg64hZ?>)^;>k zRwzSy&sGI6kS`kA)+x|l<;b@oB_jEKeG)pnqu()HM}jWG?7&vVE1`?{TW*N~f}1dY zFBWP!az-|w0Wo=?hsv~W{Vi_a3V)y{e?VstmGmtX*DHiWmZJU4*0!)oB*w|tpI z-m&j+5Z_)alA&aH3Z0+1vH*&22v?x^2yZ09#OiDz2?GMe9Oufu&rlP_Wu?`5SjYO1 z5+D&U6fc5bxKm20?By$-k#e~JL(A1GL$331SXSe!Cr_|#n~!IG7;C%!Ztn|qpYaBr zU&f9*NtW`(;j!GHZZ@xY86_N4MW^Tqx6^Uwpg}wJ`6+)>RK1oclVy zS0_Zg-Ae6t*~p2${c{|P@ZPYMWo5ZH#u@Q(lmF|$f#kP2SnTd624LvfLYW143I~Xg z_Tt?A$=ui$Or>K>g({SCfIFY6&)Gs;ITHewIMojdx8tL^a~H$vh>8Jp^cC$IFr|ek zHy(5hBAy!329t}`X|M!me_pf)gy~JN4yc0bkL^$iR)~RWM_33fVvrU-!5cy_Y)nUm z3a-d)B&sCq-RBUHk-UIegOl7}nHl42dj4b6`l_KbwL4m3N@ff_Y$L3Z*|4sufK0`i zYoVQ!NIFs|RZ)N=F|*rYt#2+@GdWgqiN2M>c2s~|*-=Hwb026GAx-MNY<(XWuInYM ztu4XWxCmBkoWk)2@WTt77B~}NzHfv((-$9?C<0b>5?fp>VwYnHJp>a-WqB{|#$r3B z8a4M!@^a}1F0Cp|kv`InyxgRfe&Q+YIGWrm)`_$A&2R(c>>&*N&M~Z&~(@24W4!k52~Gx?If4jtzV~O;0MU5o8FGemA=iUF-U^ zu&3~S;gB5o&VAgYYa?%D-R}JshFhLhX>He3Y0~04CgYJs>OSpFoBH^uhk9HO(-OA2 zJ9YnH)`##`nTXiO?>s!D9?>U``#H?l)FxIl#gT5%bx;IQ^W-(GxX4TkHI@iik*Zlw zRGlSk?>DBbPPZ?pq)p@PV`Jsg`aBPHsaI#js`fN0YS$J3K73PX7)+d0zf8|=#iTLT zG;MctFZKJp$f_gZcTSebxL&KgWHO&zqrP`Tf3CXL4QJ$?SJa@&+ki%{wTkW)@W?TPc|oNh|HytmLqm0-OvxIsuOf7pFMnx4g7C3*od}RhNfH4pqc>>QIw50#!rCeVu0`{jh)0v)%d)P#rcfj2I2pce9l*e-du;fFEBUajn7` zS{}#U*5lm1_U=?y;TES9XRU3TeUgRa6Yg(4dZS}uf4r<(;nX`%&qGen^M+l zu;|EB9`01uJ;b_G!8cBwiaB=YjQxs%m}4PtI+`V$`XoQY9)+YKyy*`KErp#JDY%S0 zmhrZMm;Drqn4Fi#yFn=|Y-%lGH8F)?HvGrHSE8JCZEem3iLH)kH=HJp(%-q7{@&$N z^iKQhO?N?IVbTSFxDQ!5)zP~Ke;nEgIv>TR3gx*ZQll+MWG!B4bPj%mE28G)H7(H! zm;#w&BlD=pvaOuF71>Mamh?R#8%-gLcXwDG<@FW%X za;sgHmBMjmCm|}hc$j-O`a%M-hE7Sr;`hjv)+sgNH?tLjKiGU||M1JV^lONi%!BVU zw66>te7OI{F0IqtF17eqA7>8Ln_qkV`rzq35{cFbxEOBNydtiywP|&Kd86&5qx?sW zb>KqQU~D-=b{ni#R~@`?K~Us8Y!Gsesh>Rd;c!FkZ;|t2Xy)FQg#ef=P7i#&r|Y+@LswM@GyeSQ zd%5gNBy4sZr<_5{^H*}GGAQ1?2&j{Z>0rR+A|71gWxg`14Y`4D4TW)~zZ`rTJjjxD zM_*B;q~je}JvPn>^bg%s_YXJOvHHq(!`QZoO#@N-D4|9C?s>=rEtEFl8u1zgS%huE zH)vJ7eHm_+jhag*GRx3ZDrf zu;1EB$leJg7h2CBiDk|gs)xaY&a@!k3W?(DddMiJInZchJ^AT$x2Ns!RYnI0p(M}Le)SoOYqTs zuK1y3YPa%@8Lu_9!wYxERyimE*c>7(DSyN;6%V zvmVrP;}*8})I79WH_)^LZ#mTHY}qqe?NZAVst@vQqDt*8zO2mLmXuRX-gWrS>uU)7 z8iWYIaHqei0+VN;45kVnw!>C?)@AUK5tFi?JK=vyHMaIY;%>{LPq07FnDrGj#5t(a z2k61Yi5{!$asIb&>FFJm47A>uTsH~VI^)hP9~rc8oJ2_DBAka`%j!6c;P)2>swNkG zP};w|GOI8wFyewc?vEsiou<5u6gg=C(anHhhmx3wcP=yp z#Y(X6wzL-iI?F0bu+Rp3SyPv+)Nw1`sH2v>7H-(tk#=7QJ{vE^=ua(eC@E#l6 zO1W~)CJJ0;yHY7?IPuO40~18Qdt?cylRDC*!9DSOSV39!WVYRq&RDTWy}kGO+QlII zy-%8vzfnLtGPIR6=L@e69g5{*sK`oXQWPw)*5aMG7c$E6*4*s0#xN#%V{igS?&ORq zK@n{5gb>sT<^H+Ic{%#bQd?Hmmq0D2y!jJD6$YVazucG@5?^=_Zz1j?D53byBcMlE zaVUj%4U)`<24vFH-SC@A`DdWGLg>lvbkmdN%zM=OlvMp1Tv6?vJ0Gr;F52GdKHXJg zZTWe-PtLC&lJ{k)9Mw)cnR_<#;2%z1TS6a}6cn$?d|0wwLS7a)gCn(DsepvvqDV?m ziVfIwt*ZSTy&^R#SXTLn$KCGL`aPct!a~k%y%!vF^sZSGjV?DBzb4L~ZA%paa=3%I z*4=#g>_6_hi>l=+idyY+ATl!3?l8eeOZLg@ zBI zX!#?dcy(3@MmFH0*E63&uV9|bF*SU2B~p9tIXEE zztN5j$3q~Z8;!oczd8fk=I(N{IOtLAoze%YQOWlsLSpcr84l`K*U`s*|Ki!DDE+|A z^s%HRS7#F2LP@+pi-sQ$(&HOJZvKyD5{t(1w%n;Cyle;|#DY{^mfM?V;`z(O`+PH( z2i}Th@8cdRZ0+By1k5&~*bEtH%r+7BZMixre7Ahh>h!>JoR9lpjX>jL+t^v9rMzs* zp5J;@ny>rZ<;ja}jW<^XJ~L9uYC>7Qrbl3tKHeSj0c&XsXHB!w>l))&M2Ytcu4!~8nZWEtO(mEC2w)VnBXA|ykKEBK#m^!YL1w_)2PbO0q?C=EiYI+vTaK}2d6`ZQRVQthBksftWT*UDOAvHLp;!eV01 zi*YD*6u#>9N2Tv2MOQrb3f%uJmQ5>IUcNthbl1Wx-5aVQ8n?06=P;kRL z(i;8CK7zByJkn)kV{JxCIbYSf2V)~11S_STJ1!1eCy7VU%m)lb5fDhcgjRy{BycK8 zYuLh{-8&kDlA0l|X~eK)(&325x^ccH*Ox{q^uXz!9FE$3cfs-)IyvXVWx7|QRsOTy zBAmZ_f1?o~>;Z*&isDOD4J&XD*OtEt3EshBgbIfzh3k+U0SXS5f0HBzPc0)j7`kB8Rt@?4Gc8vwdeo7r!7Pp%RYSd@rgotE)gMC(mx^cV@4d79R(DyPhY?D@gk?BQ zkcnnKq{s@Da7Mg(?);S|WjfxJ`@3*6sGMPeoSc`0WW4NO`dONfv=KI@O?8?}rdgmL z(}Q_Ae%VuFUH5xqL!!LBqXNTL+p%8&%O%ZdISUyumUjWfwxW|jTV*OKiLufcozetc zo{@QS4#Xt#*ZZ>=(uq%OFBN~I8{GB#9CXTL`NQ0`fm#4AGlmSW?HD97A2t+ZqMB+;SUyJhU8u};hSb^^)wazQa=3x*pY(mfWC}N; zSrwgDP+z?>{hlBAsi0zPX4bMUSDCIAydQ^u8;zP@3B*1Ow>1vyR=lEj>_L~}v&zQs z12ZaHGKOwPMs2!%>$b0E!k&D||B$u&m(1Y*AFDEmauo2Sitjz4vU%-yDCj^gSA680YvQV8!IxN?RksUyX)VaR@Q13ch-H$U%hAdy_;j-oFraJ{<>>=OrsjeyhuO~ z#OvNZZS>$g{(Bm4mIuT#R+-@^3Z2b3w7 z&Zz8_N@@G}VWmw>DrJ?`W_wlg9iNc49o?^XeQurnEgtd7Fdl754BXhgd>-C;X#EXY zm;Mku3Z*OWx>QsRc|X!qs6P3vC@FO7N$qzQg*o0e{N7vQUw`?lE<<7C%~{gGj|z-! z|M77f@h^kCP(5<(JYP|6*yEhjxUeU@Q{MZu{3*QN%h>d!RPoy2V#VqKrQO4utP8r{ zF_HHp#lEF1@3a_z5!r`kKI+->7=9pkS)+Z`A0Jk~hiuu~wXMV3Z%@gZ?oifNtoSt4 zCprE8??mn2yeclHmfHIWE!G2A#j9LXsp8E3aR2_9`V;>=&wH2?0Oz0>;9<=6*7Q3f z;9R6_jWJPR11|>Rat&Hq zgOGAU8UArD=Vtb2egjz&QuZ9lze(saoy&WzSC_RM(ct3~2ncr&ncZ**lkPiS$Ki0h zkJZF7lzX1w6(N70a?f3PY=&JPqqAuzH>x^X?(pZXvRPZInfujj`QOimD7Ce}7lKbE z7uDEA`Hxm>Kt`$shMntiq|ag}%TvJxe%@wb+>6IJG7#w?x%VmAnPw8_?9^~W&0f~* z@E|7?g{=tnO`D+6rMBK3UY82+1!(Xj0@D7TSfawYuCrpD0%c0dJK}r)C4!=u56>Bb zAK#Z~gzj;5F$0t{6-Z$_tc9QHBw`zF*y)(jH}foAy!CU?H@WKm=!|(*?Zm2tF_%X0 zohq#)-zLi7fe07{gQDI2^KRIMNoI*baO6dD3%u4xn$Y}BTuC^0wUshw&(;s7BCAt4 zr-ewX?Obf)e8C_->>;$9EqS#NHhboqg%Y$eA1JtutYG20sw5v*X)&CZZ+IXWxLvES0jV>>(7vp1-1@iQRyU z?Z{bm9hJ&I!75n}Zm56`%)_>dCH(x%4cTaFo@{^PI-f|fFRuLc_k>cilf95;XanfV z`v%)(7YY4vTwlLYld(>}QL5AvH{#Ma!d8yAaE^H}W6rxB3nT#!NUCGPS1kRe zP_9tWKrkpuwKBlLFNNSMr0_y%`e&-am`a4 z$**0F5iAsfe~?>|6s67WnM%$N9xb)dVppt!kj>`3@m8BX-OA?jRB4-^H}sV+v<*fE zm%uI{W+IqpjeLj(L&*H~TAd776pz}r=ZQn#N+_x50OBZNxphK~o074ha&D4F(1B#y z>4d^CaIv#~ysRI{qu!SW+v zBRBLWdwbL?3*XK;@tSLF@b z@-hU4UlEz6Ia_*Jj_dIbBUUOS!gfryBc2u5mPkzSE zHEVS>uca{OmH1Y}HRFfh1u55~6Zkd-AG57CcpjK_YV4oG+sEAZ@NBwN7+~rGAg^J- zh!nnjEH6xuGzI#@&kYx}ivU#%hsj?0JTD$%RPgQlt+qg<=B25`$n>5_PyRtlN=ueG zf=ZSNrYVI~;4+uSPmeU(vJIC`o!=9o-QM5uvK|oLr7%eh&;~uK#Z#dXl!c>kxT!IA z*(R8{p0JhBW2G`!!$Gno(}fyA!j;uE(7lH^vkujnKvmZi;d-2hXPv2gUPdssz+~zQ zR@n2XD=ZL)TI}4SiOfZV=h2+yWhZ=yph5_j3n)-dV-zMJGqz*WCg~$mAaguhET08P# z7o}a4UWjH>)fv zpD)FgD=PO4QngLsA1#3n!tZ|ZdBR5znfOFJ322gpYVr%9;A7C)${xvN!ls#}bM=R_ z%y>eS>MO~`@9&}_N-m-K3JOALZ5aNDpiXFncYrxNr)Sxg@QP8XOpQD22x6JPFL{GQ zU!Z7@Aro~Ys+R(EG#~01a|UVI6*eqS`4AuWNV~eNHLXS_mmmV{o>upV!pXc2)S7sI zV#`t3d7>kdkxx74D3ciYu~8Yp14;l;Hc`Ok zP9g%Y3y!r}NpXqE4`M9b){HpMnko~$UnVp|F~TlAO=N#Gf2|sC63SSHZ`oo>P~v+* z?Gb`vZbVDoX0BrkIhC+gsrW43w-l$aY&dDhjcTtBdS?4%wrTB1qggb2m$y$y4BMxa zL2viPMk(d`i7ng0@oWlTJwzuPwgoP8xg8PQDrP(qay}KC1}xnZ%Cce2m0(PuB6*rP zIGpK4t|n+;yy%UNYiH&N`=t5Bq&Nm2cR<*@FtKNvsZl_<2n5qZ#f{; z5q7|Dm}oSc>`hg2&$t{OWbQe2nZGiO?QlpRV~63CY3c^4Zi_oKF|i#$Kc0uSD)ZIq zKyjheUGCT+!J|f_Wox`2MB&~*N1H$B-Ny3?Jh1W&xxY;NwOCCijKTAK^c+xf(RaG!1Ywx#IwC=W@Kr!uVbQl zQ7Ye(ThV52(!&n4+6I@f9Pe-1!9NIHuGgpCeTUfhX??K0Y9tzA*FFQ+v-$J z8_F4hQ=YN&(m-4>8y2iYp89jh$10nNq1*Fv`-FznM~9ZMBn$gka1aBoY0?hZbnw%H zWAYLfju9ee=I`4W>(O$2v)k0-j=a&mdwXGwcHCI(4+gkL1dP@3iUnEdP~sI>8SEpC zO|{dfGELy%+l-Y?e-nT!@}l{3S1u--V8uTwPwY- zDW0O?cdkszyt4lC#po;gdS7=SRN;V3JbzayvBebLK+iBwDg5=s=8NZ+h?ko-&E_GH z$_A0pYerDcRBNCyX$9WCU+4Mp8*1ALn!-0tTK$ds-Yef?I8xP)>l`JrkKMf=FTPyS zSMyT0jlPw{wp=BIQ|xf5uOscNr%S8v^Jl}xxh`+i1iOz`=AN%|_oAP&2@BZ<*sV!r z0&nvXENL~k=!#iE1|xZ}_V6XHBlN=Y%dtC!c^^)sP1=$V3+|X4udJ)|NG%LOAFt&) za(vjkupH){cb%n>qSq_E_qETI<$>5DzQ(0ZBxcc^Zqhh84Xr|1Pz5EQFXSU;)Q&>W ziT(^o=bQ*YIv>#3oXt#`^F+5lu2$Ic6s|i$Q!6f&O-l5;1lTyp1Puf{d#iWt;Z5Btfyq1&L&?^e5q7>8=o90=nUHj>GDjk}N;1UX!> zaW_R48nodaxDDrVXR={Vy~o}X=RO4C#FrR?`}m_zpjn~RdoHyjPYcYeVp9Y@sadDWO(Zw)J?CBhf&1(Boqbt#_t5qY0J2Aiuaawg zOxTU7#bjx#!8H)8SA9{&Vp2?>cUIVtk8Bga21}<;!U=RuHphNBnh$496SfeVH4K_S zgBo^2h15re2H*EVP(;Au(uboxL&05G`SbN5f3Ua!O5*NmL~prBzB2iu z2^1Fknx%PmAtC#57;7Q!0yP+b~@rJ zA6;nAc3hA1cdBiuhg0#PUpfezht4h7X^vQ!F~^ZDN@mtbSTwY_Q<&G$YthVvoO!s! zaBNB_^#$fsOf6W&KlBWWc!Ghb$NL^YNlb*oOubhX+ta`j;|{uHuw)UP6d4Pj0?6O3 z-@=X+XWv4jy{7x+K7`_-YzMAsqjn>~NHG52UB0HYxBe28EkHniDFs6#_=+ zy@^)4ic-IpczR6?um{+2=AO2PYm~2#jk~|I3)N26y@RI(!4XCliLW~QfI#z7c>!An z%qN%{TaFG_lJ`5*6^u-8jDcn8V7r%izXb{$SU%}iUdop|ZE+M{jZQSZm^tefV*IeC z&oRY9=8<+4j!1P^r@^mgT5A6&`5xIylElN~6T{KW8nOi1uSa20;{{iow_i}qcK~UY z2RhwekPpG2(uFE`SMKdaYA{w2*Go063R2yl-9Dc%u{GuBkX{YPK;5#YN7pu$JQpY4 z;ksm+BPPfuwqS_ZJ80%T;!`ZVW9jZ4uSZ;O}B~)T6q{K{XNt#Mo##EA3Om1Pym`h}p zq_rZ3gd}8Lj2UArDz{|Kh*`MHI@eUjm09$j{kHG8823c!s*0N^P5tW*~Q(+>U`{gn2J zr~NHZzH5SeI~$f9foX4Z*dmPtGxgM`Pr4B>0{<;<0u)^Q zfs|kSjHZb4nQ5)xs3ITHa1>z=6x5Dv)R-Ctffqq^guGk7QF_)Pf+EwIBOR6Y;Qlis zuNdzoEC+h>yy2$N4l0K4v4D>+coE?C<%gTg`w(?H{z;bm(2mmLA=h!IYReT-kP!jC z2+lNd4R3;8l`@?wjKqKK<7ArYtwL-Bb?1d2PFIOYiE)($Am2~karebl`o)@3c&LeY zW7;RP{|qPmYLV53PZ{`wZ%~Mjd}(E*$g&PG#vq=i61NTD{V+nvYK%2t-sSK$tSy=;ggtS9gbc$K*65U{(z4vWqP!EoUvS(04eQ)-MT z!y~7=soO+@O=%ZWdmm{J7w`vnFc8)VHX&8p=4(cwKWzyTa=D9Y3HLSp2vxl=q$h~s zp@1$s!vet^T#xS4E|F?gN|qAg-VxglmLHk>s73g*ck6cQ!Ja(CwTQAY;M25msAa<- z88w!cM7iqT{{4zFG11BDmfz(uxnZjRas@sXK0qG~0UI#}XeIS_fl;oN4`o{RSV!i$ zOlUKcV05!~Z%MfDAUL-P6*J0bz~$IX7tmKu-axL))j%B(ury#80}q#mghU8PtIr_N z-q)``rF-_6mnrmu)76EAkIW2wrmjGMYGskb{U(;y1zFZwCZfc@E>II0MfVA?;(e2P zdWi4+yjUa7d&b$&Z8@JSC1=i1CcX~LTATzqN_nphe(SOsWGzd&+!=V4B};5*4G`=Y z=_S;d*7p;ElE{*v+1GH*=N4X*180&~Qq7S{us8N}`E;1lFvFC;Dc6Ku4c89L=RRbm zWUjxqD#m0_mte%vNGNJ*-KzNY(+&L2nrtdkf}K`=I&Y9Az& z&akt)B)mn`ts#9?zKXv%lx)Xwf2>_uGXNrubHDH2# z$+%=8l5`4YH50gt35z+RkY>*{z3v>V3HnW|&o$&IxyAtH*{6;Yl}rVZU#;9U3Vo9V@>D8&&1VgR-9 zxE%QsaPuzmA|m=N)6Syplfv++5mAIwmpS%&8ndYIjK_E;R)oGSe4Ea1zfIFS_`-UQ zrU4X*yIWVlBh4h`^%)g)IxT&i6CK}-=yqu%O;On4BoMeavvUYiLz-!t$%v!+p^s&ZqXhnm{UjB{3OH$OW#Sy6rJ~X6kD|U9O(#T zx+jy4mv@N3WvJt3>3?Oiyy)b-00u*)5BFp)lFOq<;e3lBIM7f<-8#dh-0F$Sm_o3mZxVp>`=s{w03zPwa<3#F;Pe z7rq2B;=PCwKbPS(eVd~Q`@ny$MpY<)-K8PNQ8f6ZsL+%|(u&GW<|WF$K1A)Ui(JNYH>&Pqj>UTCBXF>?+5#GqwL|0gtV3fX`rC+s_Q)y`$nEJ ze!ZWSb4Jhld%qaFHt*5A@WlIcEPD8|>xw8mw}WbzMM<~o3Y}JT>Y6RWxOYv>+8CYg zED4;|-F>oaMyR14UKJkpm&2mAqQ+(S*dfcx_HVxbr8e*qiu`ZRcgbO0q8sYW?I)w1 z|H1GPtbqaBqL%44Fen9lsl0V6vR%4)`nb=ed_fdp|3<~{lVaCp5dRr)+2o}^qc!t` z!FEq-9NMTj`=>Gc-?Sj+Blac_K8@?=@KYO8R#Vr5y_GB_<{^V@ZuGdD{D}`Aqv2oG z8{QreNIRQyqO8lH;?4Tu@5ARiKJc~_#=KjtFeLv7Xw8&?5OKb!xCox%vyx`p0-Cf9 zV{wTVIwtmP`T9@K91N9PcWV{v*Yv!a=0D7N+ih|>CwZX$e%R2nC_G5jcV%H7N;M>> zLEt1+jDoaufaK6YJs20(5b3JW+CM-fw;@Vo1u&N|4 zebVqm=tZ1~o_mP-qEAN(^tZ=(^ncu_`02%eB3h+P*-Nza5~#bWksD;MffzC7+9DJ! z>)(s|-%$6L32Iafrg0_?yMn26=CeU=Nh4MPVX-wVPwwke3Pj)hsVrOS9)JBpV&38N ztgG5;_jcS-Nm{?^4GL0b!G5@=T4P3kugx6#{)H$m1u^8 z(XhRWiv?)7Q4@rbI;h2V^$)iScv@rOOx@m*^4dLLdqqD7C9##YOQr+2xt_K=`CReW zms)VKpJwszR5|?^@}M}5I22V@n4M|2>1$E(U$VCPx^k=a54#HmtGD5{gUuB1V+WWc zAmCxYfK;ek2>h4WYF;BY=JLcnDH_&bLkR%XvQ~WIAMWU1?oJ74p@S}HnU5f_D)&`8 z$`6O5D#KM@dY-JaRLVQkwr1x|f7A~gvSsc%$^Fg|!gE|z_Fp9o)F$$0WQx6W45!2M^P!U$((}dy1i^pVl zncFF?g53jq`O_gzJ#u|t=WF=%#UCOYt0@y;5l%RLWwvO|OJ zdp7;0Fc0V@w4dn=vLP@3Ph#~SOynMjf1}r_7YiR|^;;?LTw7HQU9a)(zqy3L_)MCt znf;a>ylr?muuYs391ewSRQh_x^OpcE#3Pc#XTe>CE!${!%NqpZM@(+%|j zD|U8^7yM&0a+`!0u%^-KQH>XpJxQ^IRr+0rwX_tE2OPb1>*=yvU!w>QQ$QB^ug063 z$S8~f2Ink(8nA6FVPgkU>T8^vS{=|rQZ#Ly&JzZ)5NY7C({#VYCp3awR)J>vD^2&~ zlWXEMcguuJ91l1Dvf?xOz#8IDE_#^3;)CX$UyHT$H9Zd8`CAo3C{55@ zI6wMED+>ckpy(ywCs+MO1_6efNcve!t><18yboP~W%()gPs(i)ArjwOhB z9KFBrbJDHufg>e(HosOY$i|MNzbi>DL+rnxAi^zrb$$|opN55PNzs`qqPZqk9QRwD z0L+A@b%dW+!NFWgO1;~S8d9Sm&yQ))bA^be>}K;+t!=ddeI=sb_U;Xo5``D!P4J^f zK|Zhq0a6s%Ef#;8kkGq)7%7o2^_Cb@ciBH~wSVsCW)yE;KlNNj$Qo zr7>JXf2UtMaGlTK!G3xfLS0MwQZ%?2)ITvu#h|0YQ5d*ez~GV-s3%s>7^EhIN}yY1 zu9MuhXYtV_+{qpjQ`74a_N47Y(-)#%?z+7eQ%vCh#Qw4*^*<0}HRZ-DBNV^|`x|xS zpLtbZ#rbC0z2B&R`asJ9OJWH{L-Qq9tblsZ2Fq0x_)N!$Ah~Ls>^W6Yq9^r(arIbk zjgkdl<7u~Ze9-s#tOPUD!WUAV+v0}igK*pDvu*3r+z+Q@ zXriYlA+|M(KdE^63k14(%blzr+p1UR(0BYZiiO{4NnYjbM2#qB*Q28;WVy<3Foftv z9@F(zal)_m0lKEm-zI_sm(A&%S5{&C-G3Y-%wYq! z5CURSB2}9K8rLQj9l6pf_`V>uo;bi0WERMtgp0_+=5+p`?EJ!>Z@4e;*MgD2h!&?| z6S$FP*k>N0>~U5~08lSaZNgKtyn6%PrF%Ag)0Lu=$5m~`-(|NU{udKt@pf50HA3P6 z4u&0AqLS5AC3uG2t_jFTrY55Oq4iid!;4?*usN)cs_!LxBH1i8>+mG4aMS1`ahB7Q<ru8Os!<(|2GkXj0i7zOS>)UFaZgKh9Gj%BF z4A4BUqV7ai!6OaWCA8&;B?nw5G%ZB&aQq(FC&n6=-<0Q@wm2oIeY2a};6ZtrYmnia z+B)VNKl1GE$@C0c$G42`pyCoElw8;RDHgGLbli5hJ2aTSj}F@_zmJ#S%)-pzqX^Li z#KJ1j3X5zaN>}%Cnuuq4>N*^&&(Dv#_&el}^K@snFhWh9M@zP=sehWT%(diZlqeSA>XX*YUIT4-B;8Ji!kaCu&;I7HOIT zmk_(j)?T@;Ybkkez`FTCBMy4)$8OuYPkT-tajL9&v~hhFCJxXNB>40YjzfZjG7BUp z5jv^7o4JnGNMAzrhK)|UXY`5AP!AwipO0U|OwHzb+HjO+){Bl^AHhb4X;g<8{N3l4 znO*2za`85Kiy{ENVh*z|wAt1}rPWQmLHm|~h;RUDwjvK{S3G=91U#8ll50whyQO=x z+$MVGs;6byYnX;e(o5;y8pb`BoK(lM4(aX}pY6lsjt3Neu%vp?3dknOQXl!vlxC9b z5CgRJ{6R^um@(#NS*mi5gOXJ4J7$4TfWv{p77U zWAho@$MUsEz6(sNsoBSvD-hU8_va%aO_?a9GXAVrz6j(+(LCUYV(reyEdxV716EoWD-3TSuAV$ep<$BnTAfrQkbY?d+~>OM z?wcSfA#(!5!k5xzz0w0U?rksJDEdxtUtHyGPzlc6o;eOrmks%^KtV28ZKf%L6-R;J zaGC0h48bj@1IYqjQ%QfVFuswnFu-JCFS&r?)r?(a(H3&3_EF~-ueW7ycBGc(_GEmp z4Gy?`kF#ALw-(!$BGtNci(b|@o&IK&P+=J(dPn$iEU-?gh2)R=S4` z602Luz;6bY@s+z^$1|Tb)4l@HwaWxop={5Mx^d)$VW}h;iL`1x@!-SDqh}Q*!&w-9 z1W*h~OnB1Ozfp3fly3}YdNUr)nLRHJ z{u)He*deXQ4tt}ZMSz^RQXm>pekT{|y8e2iR z)+PP~2lslZItJxfvPrj3jFlLphELbJ1CJ&yLvrE!H`5}=R%rKT1qs-13o~lqx>4yW zeYuhhcjH2w!zRcJ8ffS}r<}Si;2OChMS0xQFnYWyEAZH0W0iJO-YfQ@>0`sw3Gd&d z1Q5UCJH;P|7+|N7;Vlu~ozG>Dlf}bD?Zn7kGO^Eu`h)Yn)%tJ}`f` zjJSRK{^RJ88L1Y?6*jgaqo8CR64`?~)N-l~991}NqoHe#pDV1l?VMl1*Fhy=N5O5#q$&j;TAqdAPJg9pWt2rWo@Otk|P z)54|#6>q8L@LF(OmoPI7o~9L!x0}ol*hXwcPgt_s5i_Fr3PAR5odX=GqQske2I+dH z{G`MJr$R9ne2jquX9v#YnB)}+!MW0+I`zh-Zc5Z=rW{GN?=`62Zb~oqb6%EuA__Xg zTSQw*HI`-I)e$p(J{zYvMo`6TQ1PA42jP?$hNXWm_hRZrpS152PJS0MXO4HzIvkmp zbMBojI`Z|0b6;q>MCRqfWcJ{KX25;2mS)=cC-eTuSXnDhiX;hg-;IP#(_f#udMqbs zDkc4?*S9p3{O3kRWIgz)OQWS_;CSAy`ieDSw*>xT`A`f;Kvrvnc)wE zF`)2XNt#TiEX}_84|RK8=M%3*Kh7CEV8_8xigSu`)pQ6aU(zO$&bFs86>+1Y@CN2c zXOvB!T%{Xec3Wv2lGuoP6eJ5XqGM5nbu9i5(l2xD09O9dxREqpR0*<&$Iu1n*H+>{ zy8LemzeQd^R0jR9HXz!bg5Cim0Fbqu!wlel$-BB0V9V)Ncu<^=6o7c^C_MqArwT=m zY}O)zUxrVU=gK*=RoPCpOU}xBc~w4B4@LJ|u;nwLHof*Rj%h(mNV83N1{*b$+;o&4P1@Hr z^%FZ#*pPNm#_zFEahoKjpT1}KXkzC5+wQC?V<6=E-1L7Gqzf*xMYOX7el{Iz8;s)+ zWG7iF$tapnrXBt#3drQq-^kMCa2ApxIkCVFsH+%z86k6r>hiz6o885yol^K^52uJ9 zB3-agvlZ?ZO$~GjrNomfl7-zyKczg^p6kDjHl(+wdH|!5i>L*rn4fU-C`DYjh)N(HNJOI6@q>tgrEo%U^w2GYh{iU9NV+4PRKW zVgGdMz80crh?yR8P4wB*^kMe+>vzq@SH9Qpnn@Z432*dK+Izx^v$AxinRFwPErMFy z7SnTGsV9)S=akmwd9}Rw690LN+xb_hy9K(+P1<1@A$l1B!Q{Wh3Z|YPcR%PFVTkl9 zb?09!F1ZfzL0)Cc!3<7vpmL~j3@0~~YRj^jngO0W5GCOfsjW~~U1IB=jF*r)&-GM# z82+%+&Yi7GiKU)6=U;v9r|g(=2Ksp2Yddo6jk9{TAa+j55`m|YJ($qLE})^;daee` z_V8(-D+#MWzif%`@y}8>P1PI0xMLEk&bj@+$Dqk!rkPMjKIV)Z5xabq;tne(hs)qh)TS)#iTe3iE(7{xZo|O=y!Xv!S&4H&f$RF?sbr3)jfAUW*c%Je9}mynS3cRTi(oE)<^!yTR>rg zDw-0}WL3z_DHuQu80%h8s?XSS6x|tfT>r88kI5IhEFQS!PFJR;?|5plKCm92+D8Ql z{le@r*|ROIizKwv3ds;)HGTCgx}*x;l6_D^q|heB7Q4bcu%TGg6IqWl#Z z^l|h+PiXS0gB?Mx7t`jB#vgg@654th1G*uic|yWqy5nh0C0J5Ffg*5ZcQv)}sY2-xSd@gN+SBhtag6!RK^l0j|M$0rvPrwJ- z+`v{E$zM)u{At$N0WfkYNV%e4#*zCWVNJd%H-+;lXXksua;e$vh>+V6p;@Xa;IgbD zPkFL1l@T70u!VzB>$el6XIRZ~v@hm7rxc#(n=Za0F0biY2Y<;Q+|bRP+Ex{D_3XV* z)*Z4UVGQ+!!VfZ_2aTH`VBE8+-Co2?mRh{>2(YBB>jgenar3bczoaIt>=L3Azmy{p zf{Y_tz1(lT0kwm?>4@qF?64Y}_ZJSni7ZwaKsb%0YNPrYRI6yD`8R4cUY)wXOS+qk zNo204YIZQROcQpeZ9XPI%DBn11OysviJ!a;h#RyhkcSAz!QSSEx73}S6wJje^IXAz z&Gi-|*#)@_PtDZhx7&~RRN67L$Tr=5R;_K}g_9cdXRPi-2QC(NezZBGSkTKfqV+=M zCC%jPRRncVePM*G23E4%suT$iSHH`*W2hB^9z5Fmq>H>@Ct7`8p|dUwlE9QNpm{o7grCt8_80iY$erH?O!zJyfrI z7k_5p_29X9Ya5kr^&gY>uWp@iRPhBDOGQWIz0>Z-`Ii?1K%o$vS%GB>q#|#pR~#!B zKnagnYUa2V{=6mfO$doI$)7BkB`@K&1Q#PdO|&(U$G$hTIonfkQ^i-Fm@YIsyAtvWF`dwfbg!3hR9F8l z%iL*Et6ccCnj)y)-gL2Ty)pG})Ky$GD}bfWrJBfIf{s|y8ry&Z=_c5@Q8%K2wUBD* zwV0mMRy^*h@rbwgb#HsZ7u7y1D1||M>FS>QrEie8U%i?f7!bbDK8U}DS^EkE#61ih zxZ#I5s+YN5YS?R9VWJA@An9UC6>>E=&@T@;S-+$1rEiVT?d+aP!fJod?PZ??wPn%o z0pIEnW`4U_a^m(*X1~I`G7JgBo`@m@&~=)TpL(CuHR!grQ8wk}AhB)<4rmMtmlS`b zU+V~p8ty;xy?+?oKih(Xrga!Zoj2$gfY!!llFI2)y3w?p_p=qyzBG-Acpxnp3q;Y* z%3Jm2JFpoe)s>~fA)t4hjwP7WiRo{@>XD<#TuMDg_NQb^mxr~ z?bl5zQbAb|Yk^t)e)YUlB02P>&F8R%@BLOb*_0mo{_b(2W|=|lKZ>*Y;viWC6GiLt zH0-0A!Pl)1SvV*j@PJMRMzF!-o!ROuJ#6#y@9)T8xIiHN^~p}{P2|h{?~bc&QGj_I zdNRElH{B#c3vF*h7uyq=Cwa(UC^M~r z)0)|JGR;H##}RcgcPKgbR@&da;c0hJ0>arLNN9VL#eV@+8@?4ea;`bwpsgE}S|Ab6 zk(|99GX~6#R44djGM}zw_j1g6<+lu}jnMm3k@R$S(yYfZU7UMm71Pf!p%gV&GEgY& zo3;VZxN6FB&vgQZ6l$QalCBa-8uieyQIZ92fv;5+J%{4HSNmYw*C(d2f#>qr1+Aga z?Ot#XMqa57uPWJAO>70Xc(4L?FY29e&Xx;xnoMxai8(}?> zoP#Eweo{fvGXG!6wABhyZ?J&@;=)e?p2pu|B}ah>6F$vC4DL^ck#v8mL=Z*QjqR}{ zl_^kI#U=)el#j)I76#pAlO`O^_5~wjkj?D@*ZZeZ@?E#@-x%-fR!|)1Yf8H{%?|ai& zQQy89Ja``&aCOAv{O;o-bEh4Lg^N+YLd4*-MgIT;-UkL;dQI=GL>*$AvAq7pdr2)s ztGS@v(l(J{`RWWZBXr6ZBuBKD)pk^tX!_OYrGWj*Cq`9b41j7y6G=MR^G)#f)0f&Z zz0IAk=qF0M>j?z_7a5hVtm4R(JS2t$0DrFXuW`N!nrm)y>r#{D1WN7Rd*8{b_&P5? ziy2;e~st|A=Mva!dG7g*A|_0tIiq6az~HUs&KC51i?jj64GG4O8^( zDn2p7co-9^aW2KZk-536XuSqEcP>r}y+R0$tYtdK-`@Qe#Mm9~C0zGhiyimvu=nlW zeg%3Nt_h16Z2NyhhW&W1&=%y_Z{!Hs51o>!)r8;1&7@o1PR51Zlqm$ zfyBNI5;_YIq@1P88Q;MA9+I<-G~4TKmdyS}y{M|(g9W?=dq6QU zCyXh6<00!8-_H*q!L}*=M7y4%wcS_h0D94NWytneZK6>bvy{o|T~||CQ+3DOkz;Nk zxVKB~Va~k+XHUP&!u<0^Y9v1yN+ z!p#CeX0bb^t0j$=Q~+)bP-Srg!$$X2cQa1p8^z-d$HVb!ca*+LYrIwxy$8=jz?Mc+ zC=hVXyKy_$)!)tXI#c&EGU|b(Mx47M zVm{0=&(tdK31U>&GSpuaeJ(4^gWGfAI@vt}KZ{h}USFao-2-Onw!8zY4XEc}q~|3P zexgIJL3KffMsT-+smtL*F@Z1b^7{(|(&R+~8M=AcxVv&_-(*uSxYQ)X@~#Tv(s34d zo4?aFX8J`1WSuDVCYXs)<|3U_-+Gyv%O387{%J_h-t3}xEgF*zK>K}Bgpc_`=S0Z2 z1hF)eD_cnR$@`dAh=!1S3p{+*H*H@?b&V&A@>11?lJm;pA0x!ZKn-Ex7)?)9K7Oq^ z{yESLxC%2g94dOG#zL)Es~W4+&8`~fjpMh#qc@9C1gBXnvNL^zEL|PfCD%%oD=A3y zsKLY(((>t73__8VhV+~hB;n$KJdYSJJqU`$0;yZ?SvaU@WXSLdsc9ViI?>LJ~SN5Z4-fHT27`j|%hPfT4Y9@8}vVKV1KA zK}w2T6*2NaVqehO37V$Xt|KfAg=EL-mG1Y3yBg(~o}U>ZO^@6zK2hnBO{c_FP7@l+ zCkq1oHofi$DhZXmfAuqC)ybL!#phsfpd%&>ykLFhjMPLHS4oKWG=nvo+hbVer(-DP zEe=JLkW&a*NJ1Q|m`h;Y>5sSXs+cuiJ2;a-a<1-6<#6Lt)>AIGhUPGfURJ(gJyrY) zW)yH7xe^zID1L!}ZM-N2{F=XfGuMiYT1sw+=P^N+c!+ z+0LlyPha=jPl5{q z%DDIvszN8k-innk1z};)Az7UX@VTH@7$wQAX)QnzX&d`()kzSC%zYsZps(0pPf&B* z+gVaEql8==6iiOk985{Ew)8Hv3k3bcST$=$frtJckvQ)j;>?-%9)4_LvzyJw_Rpdy z;lRp0l;E2(z!6`U(VzFG#NQvuuLl}&ESluu;wGp#g*@Rqgs_RPk|CtrI9uX#HUFXl4 zl`a8c%r%|XIuS1sb4s0*ARs1TRiy5DW1ed14fFEYktF5F9quMa4#vqN{lzLv6u;32 zfopTP#0g>tKo@XaFE+3A&x?{qAg8*4$4FNq)j--!m*wFt2gc}wq}5kuqV<+D09g-3 zkuXJ9-0O%9Tv{RM7e*Xyt3?^bu_M^k6V+C#IhwtuRDxj8#+}1jUQgHy@jvl?9ZbE& zn)=4v1WlA7279pGl_+Qj&~5Of&oC`4u{&_qo3IB69~cb7OK#pL!9*ZNEnq#&2#t4T z8x_TIpaKM4XS`n?$*d`ZLTK`3=n<4$^gsQGNq+Cp;IIG>L_asDT9sXzP6OyUSj`>0)3; zSO(O+RM_7f&YCbnoH-rHNmfuH_|n6G{QvKdCoy#7ldC+IUu!4YD|se za@(*?nYz)VEkK7FUjAWybtw{?N*6G9+G9M=q!%*5xumNhV1d?J{v_W9)CnI^TS+{Tl8LjtV>wwQ4?Ke)Ha>+<^z zC-t}6>BQNsxLNja!*TSlo#54XG~|aJAb^K4L88M?q@#-r$#HZb>Q06A&mh5qu|cPM zgPyQ#dgdmMw!ly1k=xebG459UP-NRcg6YG}^xnbHr8K<3q4O;RzBhf8jn^Ohry$2%FedBv&4OiDC(2lg~ zu-6}0zFSa)JJ|kwxpJ`NELaJxN+=O3!%5Y5^XI0$M9~pMT}n)2<|3rM2zmBHh;G#U z*;zxoAMp$!HqzCk2lL0Un)sD~d%VCdL2!*}=teqWUrmq2G+sVDPF`323AK}iY|59a z*@KM?Una-lb!cold@QAZWF)9C2S~S;QjdvzQkd&qC_%c;$GR(Q^c&qwlLATx{;Yd^ zG;{G2{Aiwf*LyK|_b5iu3(lgp0qR3n_?xGfQIDR+68HV=Bw* zNh_?;uaJAgyY6+J5$R>XUX4bL*NSe0n5S+XPjwraST*ic9+Wxg@QAzk>IU0-G{0J^ z^+1yb8on-G7@~7^!1~pXU`0WJ5Ho51!tsSX*z-@GG93sk7C$2AK+wzpJ2!;ld`gts z)E?hQ!}KsMK+C+F$!}C5!zDBY<(DW3G;VpsT-3S#zB3ZTXRV~}x;-eEX~Hf=B6IrA zcbLDMJ-o0ctgvXpa}DatPYhyR%m4Tg7ER*~X&?>O0YqjB7f%;Q`mk$^Zc*1WQK_D> znH{lxH!X}^7(Rj|_gcY1$3YM2j-H^3h{UgzcX+meDnl^(F~r_Z@WKs(Hv&4qKrOlm z{8D-~kCWlUA7zu`(g1dF5LOn9CSI8)?SYp2;}?g7z&;!T<_c!j!N6B-a96!sTt4XC zYfoST1w>1p^nhrpT1oJR{4JEQvQ=;y)0KkkcKqW&0sY&6;!k}L%ln?d>(`gRQw5iH zzK4GlUJ+!*pDTp zr~He4Wv4mIi`q3lEr8e^^zRRW-AK6Xnv?*D$A?`T6(tRTt>ws7A8LYC$b;Bh6n>-V zSVd@Ze+wY-e57it#G3GobhVGz0O^oyp0tY1yk10UwXN!v>mbFm25Ey0bT#XB;d(5- zhui!T6SAq{r=U=G!W2PczaQB|D#!F%NFsNglm|p4pa@Cy{s8bShvX8(R{R;!-cJxq zWq0xG5SD-xGdr`~4$gNAJUQA>J*-p4=$_Rn0w$~UTa_49e_-Rlfy+L$MKp?~V{fN(g)KA_ZM?4~9viLPnSxd`7gdo|8q=@n0TZPivNlWk>cC|i{??<`>x5N??Oe!4guKY%=p`ca}~-Ys1MG#|16a*DZv>KuiAHyExjhbZ?)+Bq3Iw!PA$ z!&va7%@yPdIYG=cfr+s(l%&%LQFQV{Cj>f7%DSe_DCm}w(83AJ8f`bqN&6@actkm4!K~l{eI<0xnp(ocO~tO0>nFS zLi<737nNfAu3&%E46?4}4_nQa}lupp}h z%w_6}jAFmS%k+%z*UQ&l4F!>ED-sS5Jp(9v^6o~@i>#839Sqk1YbQNy=j@CoiuM3v zcVoZDky2RVoIC(J<6_CxHitna>rG6Fao z39MOn|851@Hrl%p`BsehB4O5tx0o<{ghG<4pdft~>}@LrJv`6p;^lv|ZuDuJJy>w- zvl~EEJxb)JI3qt`d-+lT|1SL1#W+|j{{)rK=EtWCZDXh!x&4!wyShziYy53b0b@+M z66L(Gmy8fgezw{V&L~sn*fZo}5+$Y~tY%See0-&eA+Pb%PV`->4LH9oats9$Gy)n| zL!vIFd?NVbRQ=xPARJES;$DU_?s~DcbM9Wa3DI4Adv( z6u(n`_XDnt3|19T6mr4%#za`D8c4f9m9=OQoG)FiFN{yZThhST;bZOb+Tw==6dd0u zR&GK)2}9BH?QRrL`}b4>K>)PGZ3sEmDlEQVLV0Fy;v=kXoLNaZ!fTLk@673zD(4(9 z9}~jz8w#>4fX)3ka^}_l3CQ{1;a|`)I_$C)5(q%IH{36q;g}8pQ~phGXB1(_zck>4 zD+K-x@m~{=I^-8=waLqFmN+nZva{&cs~1I~FOXEbs%q>uMUyQzx9(b-xw8#*j$$ic z@H3+BonC&x;z`8-dFp-Vtd9NrC>uxdTM!X1NRP>0vwQ>hi{oXP z*7hL7X(BA5?fg8>G)-*@*IQfKnaV!#nG#`F(L+qQ5-|BLG<`tGsLCXjxwyWE&Mkz; z(;g;g48=BHQTPf>AE({>F5DIji+7-(ut#`tSEwT3JUH-72f(6=P}3u+#mxhKLQV=)PS6q_U6+-GvER&qq% zp+T?Q)>|=fy0e$Vu0h9)R$cGjQd;+@NGLn$K>J(iv_a;Mw+=I3Tb3^de!QzA8fm~^ zRI-NZfTY6T=G&)9@bMX4>T=Pgt>Z^DPIpPyWg!|3ZsHteYucr`lkbI*JLC?BY)YRy zA|EG)7CPfL1SyEZZw9Ra0YQbjFv%PUhAd1*65hA|vVTd*4i7X68{*6;RNJUt%~Gb9 z-T01^uEdC^RJQDGPoyqb=NQ#i?FpA3RGBv0i)0!U-f zlS=4fsEJlJq-ECTB0hgCNP?0IJUu6{L6tqBnrjavR=RGeXFP!1S<)tmEe)7=_1swF~){ih!x{sn?o;!-YmoO??-cd#w=QXj_R z4LV-l1+ZIe3{Vg8kS+NQI33E&aStQ*N-Cfa&4g`%YCh2%BIwiredWLgqIUC9*4fg& z;)>eBkp=HJ?6~~-L*kaw4Q5ePo(Q;oB#nU6)pf19nWcfu2&$4Ln>?wu)yQMe=KGDh z_iUdtZ7HL-$QpQ$PU^1Lc^{gwzp)y3*}Tq>`=K|&M7QG{$083EPIom+E8ZG-v_5zx9@x7ujugSU+ ziT<9oC<_CU1!Qw{IjxbU_VB{N`+%jy{JrZ7QGd+6 zM%kX0h(YjGP{M%w#ac}i!CpDWTS)^i39N!YUKi93P`w3esg7M0g{?)nW99cE0{!>Q z2WuqTJj|VK%PX-q!#`QRR&SH&n#4)QV4W@6-88%kp7j5d^$T@1JVoK0Cweo)+H}wt zV%<+A^Jgm(zx1qq+w;@r(02)^>g0+SLoO5ZyAN70vqM%_)$1+e0u`F!+};Xku@oaB zq|i3;_L2iN*d{s${}9f~OKrmZ&Q-8FaM`z~D_ZTY3_jUlKiF?!-)42HqBhcW^n|az zT@?N~&_hlVm8mDdECx_W_Mb-JxVr*Y!b;z?@YwW|_gw=Qw;X{F7CpCG?_ce_s_kWl z;lTL{jp;3&o?8Np-|Lt26{}=#43tDZV$CgkFcSN*69qwvhvz*6OLl369lxBjWzVGr z3Rz2`YH21ZfpG5cr)XIfO{w_?td$n&^2*C7b+_GVEu)1|!F$%Qk{RB9lJ)Wd!V38| z>fx@?cQh4XYqtbG_QbN$#Mq&GRzg^eNCZQ7It3lp4nDc#ea>zM%p$=rZTYaQhhOvN zPLlbX75-&@QCjmpDHW_ioVXgnj*xED94jcI>dMmeMZ?uXTw+>mTp^Ip1O1xyxo7*c z$K)FD5VIuTb$Fu8@7^Hf>#vc7?$=uQI1O9w`o174gis|e5tarj#-foNWi``djRENLIwfJ4x52p{cPKL(0R&9CJ z`O5vnVbF)?B@P9@CPCgxuOuf|LUAlKW3RBtwsAf@?i)aD{R$~Kw@>RF412$|9?SGC zHq9Qiem3G*>A2c>!^^UnwVM`3(Jsl~6Dry{JjC!|ej{r@N1W9ub>ycPX$TkB3R$tk zrdSPjz+F;ms*iMoI!({YGHRM?U|8xMbYyHkE=OP- zY3$DG2nrh>51(&pN*1Q4hi75_e7jQz`tZuKLVY{^VOFJcW9s6K7xp+yEbSd`j4X=T ze#<9&;f1H4&^IBr9?hKME(njEA)Lo0RLR%F&@>tZtOW23m5bEm6#|{Q-F3QCzw6cP z?xe>S?@SCkO}K+oeTQ}i&8%}r&S_YksqT0e9YwhIU;6NBWd&@|#daHF<3L{X2naR^ z_d!(XgFgwo)_mT>`~WAj z@w6&>{zOe6H(|zHcJhPDzUGNF(ITSXUnL7a)L(h1yO+JOzX`SfnXk4+Tm^C^Mb)>4 z82>Z!P_P{aOPnM-^=rp#r?}OWVh6XTjSaX6HJ7) zYMM(nl8d8Fn*MPLEA=>98n?u-=Jx8hk4@+5ANeRooJF;))jp-rJVC-(D;EZAMed(~ zeQuDY2Lt0P`^Zwu=brxJ?=KWKI2?0#q%DZbIsZ9p-JW;#YZc4D?^udri_o!BOJS|c zC2OKUrra2|{ER_&n4A2r*DG#Ih$jAYqtpBiGtO$!{RfW^d0bt3>S>h9V-tR5-0le9 z^VQL6N~@P2y2H^{OQ{HHKmABlH{j zo+nbvkN;U180P!#?8!(som0#wTmN40e%n&5C_(c7HPQd7nik`01=GrnTxyMTLWKjC z)OGPU$~`|I%{#LszjgfU0O_CwBWK`VlvWlcfWuVl8tG(g%ks_C=>oyWId4q+^zD@V zmOhzBCVf#|O(-F3Tlf5@#Y2C#2HNN{x{$f zaW%U{!(VR=Y@7J=J=H$jpX*s_83S6Ig}8VIQJ^_3g>qd<$hJ@$(h3k%So=Er4BLt-dJy0srR+X0`3^F zN}{PFj`nb9)%{SfMN`2P=O)huu((K&qJdoY>pNCDG}tD@t&F+~0MJ^wsv+Q1LIF&x zF{Jwe_4C|@|*2yw$e_HssKz>EHNCHV*_NBY8p(ne$OS`@wR0Gg@DGEwTGmOd8V z=XN_?Fm?rt8TNO(vBH0q{KqkrJek0c$HGLQuY%aXBZp7Ns>l~n4@M9Wcjl%(hMg#N zL?w?-O?&t#abyNtd6T}B4Jo$yMBri=`p*#ihHJUv^x%+Of2(iFh5p(OJs+O{zw)){ z$$zcZe-zQTX0ue?FbgR=20hc8)a5JTI##05-Zjj1F`W5RZa)j+RMv1C+>(BItxH(a zb#?*gPCrWb-%sO$RbN*C+QfFeeK8ndH4|g4|7vo_t#(LaQ@jYU2QfZYImh+0sQD8;=fVxhqb5) zgyS_CEbRCmwa@piY60l^o%KH#!vBHhUnrj3{m8hYB`7Cou}L<%tN3Fi`rFhrt~jfz+d4avtkTw2SIMvbu@D<@bJ*oz`#qzl z`@cR~k$8cN3R|XdI@fj|^XzdHf5EB0c502c3$M1DD`Xz%{5b$KuMFYwCgW>o2@?N_s3JSyt* znx|@KuZg`EMsEBc?7e$9RQumQJd%(!q$pxKQim6=&RpT5`ccRj!Rxvu+u?(6qF_xJwY z`}T)_7;Dzyv)-Tg;dPkSlv@bpMh|T7vemVh`7NzbX!JJSDKGO^h|^zQcUB}_zpS_r z4PE2@g*#OIf%nJ$wT@|9zGu9`7 zUWF~Y{)!$t@TU^YAnR5?DdeSp-25q;A^NywziHB0?asjEI_|H7E`!DW*Q_f~#V5!! zaR=q|_pMPt24V;Sui_qVEe8hd+_wPK$^I$7WYMa?&F*uP zZ3!O(tdv zJDDZCbSdw_-3RA0D{z_{va}3eHyw@cYU@6F!|ZV5^i4i92WZjLK8HO|H%VA}vid`d zM(m|+*B@;Aa_|0fsP~tb$`!a(4>um!<$Y(-9MXkxsl^cFD`Rnr8lbKK7LNBw_ zq*uHWmbztFh6nGe(8b8RhOpaI|VH~u|{(P?pk&-QmK!$ z|9-KdeUbF++!dPStE0cv;k*^|*lAx?*L&Wk(ymj@$!q07M+bVIm3=;T7`bsJ_pH@F zx^gTA_Lc#}%s+r+>@0pO?+D0X{(Qa%`$KKg)P?XT`w6HA>iIlz-d_`xcV9tvkmM%y z#i<=8uJWEGs)+*VOI^&lwW<(~tK32!ASGx`tJYy~{ zf8oi2#$*HMQ>z}ao~qm6L`xQZ@-o)esy>k&ZMuePa!DCH?O*y%lh;5YOn?Z3#Hq@! zpRjk#KwLREKkaX$tgG>$O;0pEu<*mQ)M{$Cf!te_9w$() z7maqqM&eM>gGYD5;dF`7ITB&m_}XquddCDoCpgXjQ{KvG`|sQ@?_ay$coVhmhzlw4 zUp&QsAyDyu=Pv*CExP}m7ef98GwA*}$@k{1J=EV9`C#{8>Gm7cV!6S+2IjjCl!?6e%Yl-2tB z^`c)$JEj3!f(<`w-;&sJ>^=GMEXDp`P2_21v_B8cy)`0XT?Kaa?1^vq1^XBGDC&IP zmw$IWj8o0}H`frpnb`eGhXn>i+=-f4WUHvyMthxZi%l7ORwU#2K_B&Sr#WKJ1zsN? zUNvp{Byl0T2CIKHk^AEb;C!)}$5M4ZI>|*vA8rks#5B)^w464j&dCB}mitekW%qm8 z*Q&qQoW-}N{V#eo|N3%O|1u!Y{R-@4z;-abY7OVl)<#8OWB39`V_`3*%V0Uu*cV?n zpO|I&qIy<$*z>KL!?ypke)_jkg{i;&=iDViA{E{PBuMIu6$eB67ND=-sM<7(i!4h< z_*N1DF-wtZ<#`et9Htvh8}PiY>$|{?7OLQYx36T_}RL644d)v&lgm<_h#K%<8MdsQ|8=e<`dJ$Qi9h0IAY>$|)`}5z1$&$kpz-|Z7L1Q;U)mvh)<^v~F&~oZ@3O1gIgOm<< zY$ovsZp*|E+-(nW>JOY#B5uq7`0$#O3TNokE_5jh45PP>XUz=6v;nL^W8r%dk`l;O zc2ds$z;ToZ*aI$xZpt}2*v$0+x>4_Z`X85Q25=&u?w#JLaS#Lm@WI$C$LVN8Q4bdK z69p&0tbu-vT>wVO-?)2wz(Ij)G@$HR^&iYu979Du&;(V&w9I(8;oyW8x zaG0kZrIb``7X$8_p&RZ30%wwVMwuj60WYtIz4_v@@G;fxb7+e? zB)Q8w4q#iao&8cKpN++d8WqH)rn7_9L~tvW>rF;D;2GBbg&uMPfQs%v3CTEn%-B*s z+^o#*d#_vFjkmQQC*|Eqn;8UPI8?t?y>aZnbRMd_TJ9QsuenWg@Z3k2ru zF$ASMxFgDftm)(uZ&|wt(;huJrl2T^>f`MixYgiplIg&GuFm|%9acTd2&Ly!U2Stx zlaw^%8{fxniS7c-e+Efbe6hAvJh zQs#`v`iY5DeI*6z|EYJf=1`5*?z*%NuLTcFE*;sN*1&gIeNsnPeY@31KfmbW>d?HL z?&1sT!^Sw&QXU5whN%>^Ae+_Bd-92!<*VFL1S`$-fZcR+{ha25V$S6%d~wy4$r{VT zLmlq+@fFmp^WkO*4{a;!N?%=n-S=HK`tbA8O59f(IfR0)_^`{y0@F^-dlR^)sTL|D z*UZnpeQ9ypFXkqbF z6JTRA!Ajox5+ri9uTcP@c%uSyc@TVHuja`un^Q4!@9HruXb?2|f8wlSuRv|084fgjsY=g5;t|SS=t8jyFc&Nwwb{5Z(WV~p}8POEwiuw zzVs4TE$x@_#ZG^IkR{p;+OPY(05{I-1`iisr)W+}YnHhxc8#zWK1VrGk|@}o&xvPg z(>^;Hz@gPf-uj?bdn@hc=%EpRgnH?7)_DcpM{~4q`|p0;6}Q^?x@R@}_WZZ%L;c;8 z%lQreuP$x>dP4v2tn2<)HOr}k{hQ_5)a{wNJyUPh3U$Z5Z4V<07L@dEBb4|Yn18t? zy4ba%+9pb$VAr?x=%yR4Cb8G8Pl-PO`*@yYAG#Df3!nn${iDDHxdaE*6vA#QHPG{z zQ9cIx-oYTZi1QPtOsaD+-AEDU`!lnd$*m@gYtn&11W#EC5|w%MSn}X(5o#-dzK4Rm zW0hz+)MCnmLm&OXedz)@&)zBk^38ID!~%Z+*DeG}OaT)>f?Ys~S^enw4_u=!$V;Y9 zW$La>t(B=aXezEuMcb)8Xlgs0N)o10r>TT;D$SlMKBh{tsp@d5W}fOKO!Zg(kL)_> znp(aHnAb|b(@`Q@)6>@zo%w7158U3TUzCG~xqn;&GVF^FwKOf6)_VO;!u($rsTWQ4 zX{Y+M{|zyUQ?smpVNN$SubPU3Q*m%A4*t9Fzf%ikYN7ncEEIJ! zhaFuszk(_9bYp<4;ws%#xq8?eUYSwCqY3gA($e-)9-u$4Elj~?>MBfGb;X1GppxbW%1q_D4khLI@o~cJS2QWb5Pgj`Eq`{d zbgh^@Z7{$BIpDjrIn=hWtkV3dO;Y+`UeT2?S@5-OYVTQ1-GlpxL1Hz0H9+b`!ljL2UV-YVW#&pqG{#L~NVx$S<(Xz)5WjBrzNv{}Imvh_t z8*wn%2wdBKNSp~+pQ2W1q?b7G;1ePgR5l|^PV_DOc zIS=?dCk(U}zWIGPEk17iOpx1SzofO1_iF`Zhfe620orM70XVF)(gb#`7M1MdDRwa( zxIq0xwnecOzV#g70<{f`3rBp*ZpzgQY5S^htr1qP(iNQ%ww)2F0-J8-a@|jfX;nAO z3w43(LDGBNndJ&6ter3o3K@%k%-pTYtTJcNrK#tRRy}LW>8fzH5|YvjgsXSG4;Fs9 z_CQE0AB!)&ANI(Kc(`?=}%%!>^WmBJ?3Fm zK68PDeJO2ktzG#*d`Xjf17;7Dlz;#H+tw0O#RpD5!Pr`ua@i)7pvR!r1rVyv?`pM`8ST12IdXp}RsI%! z-$T)#{V2Kq)MM{iS?UFUyJSTD6^q35d5r49_Wc(1s@?A8g7LBQz|(mVb7y7Cv7-uS zIhQ6TXb)qS&)SX+D4a#t!tZaq_bPO*v~A=i&1tN7hhFUq!rP$HXfXv{$yLrHi%Z$E z^aoJ&jtQun>VXU-F@I+nGxdP&V8JFJ880>^*03x(oR$U}B^`!L293%Q_U@KQzfM5C zOQctLg+q4^1PhbpJl#&&+uKLgCW#6|tc_gCt|7z%8Js;3yjPb} zR-x#HXdyPg@N>}-e65bNdX0Q{Q)tXV((QSjLr>to_|=m}mzcj0ndHES??&#OWfp@V zQ~_3$kV#e*U>3k6ZZq;6xL3r`7m8RdKwab65 zCvNLb^p^g0Jz?UE2mkBqrGJo8j(X3*v2Oj;=z(|B-|d#$B3l4ZS?DNFgj4wb!Uk#330z(|1F@nJ&c~U?`dh8M$!0kgR6kt2Sh8K#WwLbo1zr0J?gk4leL zI{BvcjWf`kKVM#Jc`^e>kmsN}1lb(+lW?W$V}MY;aHHByx{7J%X;GVUAF452o=A`h zIt80a3$83))_Oif_>RZdG)!OjLcJQIQPEYzQGLZ?w25TOYJp1PFEDlci^GDV$rlQ3 zQWl^CwZ>tklizPW2~G3n^JX#1zVWfh=bNLAM;;H=jUKn6d)uY1c_SuJn6uGuaH#wi z8kw#1MRgGZAYjd{G7T-X@r4qdR^HcXq?Gn(HT9+6_j`F&G&otA)}$UVD6Gu6QgGDb zLa$HF^2<*(AGQ1^aV-C9e68Bo6j{;_oOzN0z}UN=Do_0MQ7?1N^)Z<12Tve(LwkjZ7N5Xk1nxKdI4`A?3C& zecDog{~E2!Y<+hyRK~4I z6F;qw7su)Z+^8_;kM9LWIMV^8oawLl2{6y?0Y2A&=^pW)F^wYW%CjICrkwdEmW z7b7SJJws-5D-m+iSY)N+w#S{L$4eAs)ZP4gFLR5$>naevsLmUba~F%_vQNz7piAhZ zr3x}x2Dlv>=h`F57cw;v!)tK7yby7#7R3oI5}nrGMN`~>W$&vBI&!*w7m$D+mj%>( z7E#K&#$}p(-yJ2bch0zOgZq*Wu2eXe6#SxrN6p`Jsl|Eq9P}3+pREy*ofFKPp>&7( zITs-OxQC@*nEfVXd2YJGYq-mpaxrYRBvwFauj`AKs4U#t78eH>9veMY=+)AlOtG^;p&KmZ@QLWMhH7??CfNE-BSi_moH{~^NS_=+y>QwnnPfej)ZeT>m{yvS z96`K{- zx$TF$BCVo!bvC6P=nYtfV|D)R0*M-5>0XIO=Aj04z`(eaphctVrt-^60yglF3G7-9 zYDbvaD=f_{aq@&Xp7iXV;Beo!zjY9H-(Fpjzv->Zku3bcZorg@UB!4V0XoHNK*G8V zM2maWIZzNV%w+UY(d{<$cn^*{0*Q%<1J4%i_otn%isKxh`PQF57&h(QU|MP-coN=w zlPK#qhd<~$7Ijq}D5{{#-DGUwtK3SmQ9Xjd)9!f=w23SBBF%Eou83rvI?{SLH~mPY zcr4*G{t_{=z&rjxyY9_f=j`s_irP8Hh^v9_dt+D-U)UQjPrWeiPxa{V+ll-B71Poe zr)a&B^3avX3!)@codY4P1*!@q6eg+McgASPGamf$4{zh*%|Unj8jlNn_ZF7FJX8|< zdcWa{$A8^j(xUN)Dhr##NCkNS2kg1AOkkGF23Elm33+~>)X)TbnD4Z~Fub>Sc) z&lJABnUBV7>>^p)C$COUe%xj~?l(f!q4mu%TgGj@Tk5}l7hISZ7a7`uUknbn$Y+EN z_fcVQ{Kd>QsI7z?n`X`{U|I{5RE1Np*`ijEdywIy&mROZ28UUuEfa;r?T_L5!n@9# zOOZM;>HZemlD3sz3?A2ENY8I7OVq=AgQG5HXjZRdb@E^zlcW?)Mu;C<6BCi_+LXkT zC$k2N-6f5d#01C~YYvsXn*CRC@Tr}be$)5uZu(gJTSEWJMNuba-@vqaYm+b?cMwt1 z;ygT73!v%8?$q(Vi9gvJa(C`1gC76FeZD{Mt8OJf zq%k5acPH-32fqV7@8|zs3plW^_ebaKRDTmm@8)4MH9+b&sRCT7V{DqOI;z*B3Nip}&;tU?F2pbwU-a-IK-3|>W$4{u#74}=(l*>ssA|-x>crWK2AKh3u(n9K zgbJUB!k`*Dvb0X52axGCYr*gBFO!R*VzOi<_Oe;I43wf_3e6sbCg&9Sona$3yn{*18 z-7(?leCjn=nC?awm>X5RheJ^gbsb2^>ApMBF7pYdJn6d|j=HRv(w{ns^9yu>CD9ys;&C5xSjTj1vSBW>eN=hD-8NOlbyU8*T#UAvd>MU~(W*CcI??f-Mucwt^rCrL8kBBVOdHW0eWlpS>f;eUSFLhG<_P2x zr1>KAV7NGxgEK!*hd+z>-$1v3Zqbt4W$hFw4TVg4hKrc4q3#1W_!1P*ZX>aVGP(^Dj|bABPkH=nT0p`=u6C~9#jj(w zR@(-=I_WP+yuV)`;|dxtCd_2+feDwf1?ZT2JQb$Y5_CfQW+JTklgn$@gp!PqEveym zM<(|a`+Cx&riB>$%R2L)mS&oyhp))&+dq(KzY|~0)&h+FAGqU`?mUlj)L$_NJU(xy z7?9I4D!L*=lMN*7TFSYqS!m%yrfus)5{FCO&v2|Omp`seFZe!YyCAH@)LtUHJ{%qp z(zj>w5huUzspcSFX)uCmH^2jOZTMTQqXM|6757IqP?GzWK!(aws0z_5LZWKVoFqoZ z^g5Gjgcl#!oFVK;_3yIq@R{(Wdw1CC?vj7=7EH|Q-grpus{q6~blJD$AGo8G9*WdW zW(BLuUm?(0Y^E{{&B$l&LYowpy~H|}2X0}N1FKd9?`$?@z091a%4Pb2 zR;`V4EhRQ{I$D%_0L{ck_H~q=39O#vCQit#+iRMl?}wK2-!*E+4|J8d7TBCBA1^a> zIK>WD`^iR?X5BEdNOLN@%W15YIo}fo{dIM{#mON{l z@S|u^N6HsEe98$l%ZWKi?!Kyym)`?f&35Hhge!}FhylV=QJyTPpYpDuKd+XkO$*RQ z%Z{|iZ* zlMX5)ZR0OQnCO~`Tw(S_k})k{*0aYg!1+h!Kt#84j`s}@|2DJA2Anf648&%lJxGw0 zGYT{fGzjQ<#d?(5-;kJxq}I~o%xqCdu}Da$5mFOMEqf|mcXwh7c_|b37sFv`y?qBL zdBJwZzUkp>i`jn9T4gp(t6r#&;NKa@)#0d73kf0NL=V#yf$G^wJX0s=4C30KTF*1v z7#JiaUkX@XnI=E-6np!a*55W>up!cU*Kk`+zgHK1%bkMZZ&41V%{_B0PvENt|1NpR z6lh@zv@nI#_}e8FQ{n0VsCl|N(Mw?Cza-2-w6}A-a^0Cja%X$@^IjcRt8+VTwNHM0 zM{7OMWFQK7b?r&lI}gW!kFNDDw*R<-HB5>WnvGiW%LkGw{2v8l^I^_Kn=@{;q~!?l zQlyE$2_GZCSaRrcthg}Lw@G<*Xfoh-&Jf&uCMM>LlVO*<#lxnpVbC?T1JM=dxZcDf*+{Zo~0RYe+1P1C6L z_BIlMjx>`Zp(bQ5fFIsUShm)`_Z56Y(%Yb1dL&4}VoTBEHrXHDqVucQXpV1GtYfud zvs8DXBkT*jQjHueJ)7Yn)vQUjklHX3uH5*A4I6(5O|rp!l=_v~yN>*sbXt}3edBKb0LX8q=l>m#0}xFFep zf-yoi;)!o&u2*G4hnm$H3Mu&7!-B2yFRIEo1n}MEsvCa zVO;rv+Yf)P1f!t6Z&SsgjRoEJ+CEmaM*20`{lIPSc=W=ScZ4lmDz&dAqszyVnVt$i z)=RV1kI^H*OK&b5lyI4+U$qJ)OD$P~D!sOX65@-L?siQ3`~#FMKLy2;i<@Oh4;h+bQJl96 zVtTOqomyuEDs3+xNt+34bvIL!_OtRk{$`ss69wj3TcUd-{#yNw+9D?%A32b zj>&9BMjD?9wpHkSAhV*l;xbjw>nHUH~-rg4tPiOIYI_Hz}P&c z8(Q6;#CyzeltAZ{yTN?Jp!cJz>s^M&mWr+k!iu%uKQAjQzU~Q}GPmNw)zOTaHemkyKbxpYeX_iEdrh?iz9MscW(Yw%W zH>6)Is!2&C8<2EqR2@l|bp;s=fkh>5HNAddjC~4AfXRHSbik$00;1J+#^eY67ij5%1zf}Fn^po)BGQ59<^J+NVit2zl=-qF|r5X2F z8b}_Wt=&CD*6XRGpXkcZSx|b0xJyvc`1Dvmn^INQX{B4whUjZ>UkSn#>DcHu1#tKS z*tcVZL?9{N;d?v>*pO0jB*)%C-EY8HE05m=;-SuL zf!qc4L`)>}I@2C^9IINbTm#F%&Zd=i;OojzlMMRaw$vJ~5ppypj9BZCwB`E8#aGp1 zRhgJ04Q!P39;#d)!Pt>Aa^MlUqw2;(h}N74@7JDvEllCBWVmAlnwdt&!y@DA2TW2* z4a*YAy)d#mKky`d^*Z15XbbnVPJIoMZ?csSq3UB~@m(_wSW{L>96i|&C6d%tf3X%R zZEg+7S?ET@AG1^1fzuA9&JIa~;zZJ>Cmwkl;huf_N;l$P*zP$nB45di!xl47f(3J%#sj{-Zt$4=6he-VB%d!66?1Evyp-ZKnH0#yY z6&}%Wx!lp8;NIpGnNOSi{1>*Q=vfEn(bzGWEYl>kXYmTn&z1i<+Oz+en&JO7@GSqt zv{&;wGZHm{o8>qDkrTyI=a1{K=PK7DA9Ir9lb9PqrR2G&*F?H0*}HwBF=l0Cv&IO^ z6j@$aFzn!;9^jf6YUjGM#C^P{|731ofbRiZ6lo5edtOYP#fYlToY$V!s$46vQvVgW zI@`qTwG6vANHS{=8&6)ky>!-_eO(Qdk}_`W`s;}oZiT(aMX$%+ur*BNmrGR-1=WR` zGPN-HHT68be}rnlc-zvav`Ihk6j{%p?tv@wF3FTe5BX-ibs_u8FBVHGUH3hS3Elc| zOnmWmos|p83e5P*7PLzG9*J5qd76-kw5lP)quxqC4Ya^N)a3dtPx;G0w$XV(JK*Rd_mP*=4#;8jlWo>g}TBGo9Vg$f)p+( zB-W5-wV3SbisX&b@xf({v|JiUwfYu!M23a$H0*kL?M&XDjW8;nS^o@S0z_n8-W zDmP02;(MPTmwO$FAR95r`&&v!{QUB*td2fyKU~T7xHa6>CHJ#>WkLp*`1DXm&;X6W_9_u=5YUjQ`zYcIyA8cIv6D;h$`;G8MC?V%F3a zIkojnZ9P+4&wu#Vqj?c)uQC@X=PB%2Ede%gZoXZTG(`)LXG*1z?r<04=V^D7Gf0{y znD95*bJ6nYajSc5N=KO0=R;RMEhxNqxclVvm#5C+Kk+c_Z*U_vvtJR;dPUWRLS!b` z%pPeC0UItR!>z^ZfSRTqL6WP=55siYt8^mb=V$!)AU5UCEU#D4@$A_tz=4}-t zW#_^SzYMPpb1{arc;d%U5tPU~d_k4t1R9++sTS3fn*1|(sbZ+g1hn0<(U^X>%gUv8 zcZ|*!9(oE_%HETOr?DidDVg$=Yg`#u(EaAP?E+kK4o;Z_DtdipI82qTMZ7RO=4sV) z7D>5D^_1zIuk`J>r@G0h@R#;bVgpRj$m3=ExW*Z&XOFhfD+trN>mnxmV$}M?|;0w(BT0>gJh3j6GKI1;WE(l;#GIbo&J)X5W#ymBBL3$3;8|W7xeUgDM z^At=-sc`HkUNGug*x}?&>le)mNRHZ^?%LY_{7k@*-*%7NZ-jpPd;O@iR|dmnT)Dva zOw(oiTg98Q2!x*qt1xh8QSbArk3LrARxG~XsBjHE)ki=#9z1vl{iN_g{8eLD=$Nrj zlSTZfa^*=58tzt(bluEnoYIBrP9KfG>**Z#an%0H(7sfA_-qtgpC`UYF0!cckLtI- zNLqrm1n9w6cnXq-#1TqL3n)DzO`<7@k^Sk>))f{9gI`I$A4HB8JnV6`ePc{Me;Aoj zFt4(7lxukMOyb8t+=p>8y6T(KprMwn#&lC`rx8l+`S~ne)Z;)A+;B|4n0jx zmyIk`$?;hWO;b2CS_IW)&P9n5A#)%ki>JeycH0hCxJqt5b4ZaJ z$**1->?#bl#$Nk=*kqlDQx%||QT@Qqo-_KYpKT1_tuD~9LbrYuaO|bo$~^jS6~ebh zYObMfHK)hTj9^i`(^7IAi_p+-`RZ60(`}yW^+@|)wt|G;o;=e!=vR=1&t_5--mGSp zjw(Y27-Bzg^O(Egw>K1|_oz2NbKQAq@R?2DHa=@%`dFujNk-CF92@^0ne=MHuQ#Bk zrhP}eheLklQ@;%l7ni$dT~g0L@UkMsTGW+K#xV~{If-@wX7HHIodcRzWHnn|KYrDE zz~6{VDnOq-ge3FI+GWR`Z0E_Zrzw4NQ^WK67}t9?w|^|HP163Y$hN9 zPVYsi^(OSQeI}}hRSUs+8gMFH4@x|A?SzE6>{%hKr5&FGiyyZ}q$C9KdGN!?CljAi6+0LK zBa+P9u(ZF{i;u7y)-?vsW{a&(+UQ#B_SDR0$&H~W-PnBZ)T;|@#ZAwqGqJsxPL>sG43%WExH()&aTASwq z>CnDVt8q zZ;A|!(S59WS*Zus^fRd1ffwAIP{y87rN?UTn}b-?R_>5Jw4uxj$uvdJiBBQscbaeH zF{s|?IpF3#NLt=O+`2N)XYh26s{YQRFQeHRMOX0;e&B)$LaLZNS|IiznS+xwP+Gxx zFIsz-UpPIMFt+`WV%N3p*J!6nH-k+3o^e91yWHqaCcC!Vn%p0iS%3bN=*U=h6~~~C zmV#HpQU#F1VPw7GsyV9L;K+dL>5c>>JM@dp1@ql?Zhm683ZY(j+{_DWc-&vKsIpl z50`ELVakKDaFCl2l*Pyl3v~6Ol$3jth{PRE6$~oau$|wS-V_IrRYCXG@brX_8XYEA#m=%qz=d}2)`vbQE zw6DF^mlIoJy1v>We8~7w0>c~$D89cxc=rO^WTNMlu1Q*H)0RfplwD6Rt2crmz?rM` zLgPWKsYb9=F@!GR#gc=XyAAo0Q@5qOc=CK^m|~-HRg#o?zG8zsLuW5MR$FK7wippQD)>xLq&RMQKa^Q(XenhUl1zE3?9WVFh?c$IKB3f6W-Xoc zH{iQ^D=g%H$)kkH$t7$3+-+KQl?_*?p9KLErc+11!xmEfs7^T2*pN8`Cf9K;lg+AD zF#Re~L4V362eaG#qPZi&I8KtS?kZ;kYNwM|Sbno}W#7$toJ*xTcGFCEdm*Nu3RtQ3 zQP;P*IIYLDvuSjgThD{3)NV-9ArQgMycrdgehV~EB9fUrXXBY9Fww|XMzn&Ep*5)2 z>+w7FWf|DzN<2p5Gl+|++TE^@dCu=m(epKnq3UPkC)`n#2UDPUo=GV&&P)TL)Uiz& z15yonA%G|tGN^8dQNrj!*t=FYh;L@n9-+H?e@O+KUw%A;5Fgliu&BjvM=91_{;YFZ z+?bzimRddbl02Pc$lMF!C`jb1cPTd`menLPq_dgdj8|GehtI?(*(5vG8e1nnWW?75 zXgqn2%qzQA;OGA?Mc{7!` zuh{&l^p;M4yp_~vtcRzlu2(HY?Zpksg(nrq72v*(jGsJJW;t*gyRi?*g?9s)O{DgpN{A17B_{$Qc01aWag1 zX`I~sk}qSg~)YPrs|wal!5_VR-)O8q|AhNA8o#bEMXL)qyz&0{mTVA3i86 z777io9I$S|X90e93Are0^bWvPEa%kwader+s2|)nBDTNCwBRULAjFGIVh$QZ1?a^* zw3uIRmXSB)@b)%6?0z3P@x~td?BP@8IlUhoK6d5n%I~K7)|JMo?rYW%xWvoKK*T`q z11ycAolYV~3SZ!%nz;%E>C#Bml8#8fo1L~+)O|ptMyySD+L#|=q`&N&L&~L|*`oZP|7dtO*paQDDSl~FrXG9H6Iickf-XaYC1=}1%*{g)ZwB{q=^l1!EA zsw-9MOf%F+(rYP+s;BoXt+q3BMnlD^aB~e&Q@N?KEn;~o%mY*1IU!}I%E1eoPMr6) zEUvWacVVchegz>r)O${~=0zDOt}Ik#fG!4jV=D-+!MDWDAe9*O+POR%8bIq@-ts?Fsx^)JoyYoR6@T zbB)9nab!9XHE&1&9MGOzKizOQR2w-?)~n{ACiU$h4#%J6gp`|dlAZA6_=pq(w}(C< zzHd{4j>H5ZMqAs7wi_ZERZ$d7Sau6lpY)jGEc_dJ?$?ydRKTN_98)eq^I(pGs!+!a zgZL>6nPjX_p(*FcEtKZ01)WYCR2)^Ryw_ggp#VQJ_HS70V@1#nIaDV6p2_@;064|f zPQ1Wo^fzAjdP&15aP!hJ!VI}eOObk??uy*@V#iZgmNhWbTz$+wY}=q zcD&iPGEMJFfzw)Pif$jxL3bdLv`CnqG7C+qIlWhTab(}EcK=;Fya0 zQ1x6M=)WcKia!@9h^$ruyeB0=G`C7SxJo~@hBwnm{ho4uOND-Ru(yNttu#76!%uqU zPB!BQ4l^KLHYT1k=eC!o6V*ZktlMpp3d1+I5v^_QF1CibXb#T41I|!-b%j!>S`MBp>0O3s{e8Ac1mz7mvo9Ns%PsL99tXfVyX+(?-N& zu_XXkGE5?*@QWyc{gk=GEW6VEk0JymH+(xsMcYf-ti}tS!$#k0xj2x)`#5UH{>h(@ z+N4T%tF1;N2CG&hsfqYx%~+m|AFBDq$)}%Up>T{oFQfK6Q5BfcyJf{6 zTQmo%3c!^fLWf{#J$3G9NSr~1chXI;I!KGPo{{*i7F&gyhQb_A^d=C~81XGxQ~h9A zG&@q)yWV)O;G+4L-(q#`OmsY~cGbMq@pQoJKT6M|-8!|1aDw%U0DF?-$VCIAe8f#` zbe8G)h>=v!HW_c8?}5bhbCQ7I8^TUu21$Dj_O?P2^RCtPS@(t}=bnBzmd!XBnOyWe zRbb>>`nLFC$YkfB<{5CJgR0A#qZ*2p3MuM7gYEzpdIsi)a9KZ zjW7QBFG|}}>EdKEHZM=Pi2aTYpMz>la%sL%8Q_npN^@VHayeN@?aqt>C{-;^JgH&e zd(7vG!Y?>?0Cv|P=mJM}a*03&!nh7q5zK0ZbTEPv;N;^xz~_l_x^l4yjvZv{Mw|qI zp=fZ>eD?+9=)X(6Lu@&hOT_KsW%6_F+D z;kWscW*IcfD;wg0#|M6nfnb^(-{ZtCR+S0feC@|6r=di!%69%Fh6K?sVxW%{KvlP4YP?_bwy zQ6G2Z6N-4Uq#RZ~bv`&CVIEZdtJ7vszJLclH3t_UV-s9GQ_J^+?9owK5uaRJ4vUcM@geU+)KZeT!OTW`P)BS~;*u9njAJ zSN)iKp6Pd=xdG9v_NV-c02wTy#WwhxkQsVUdAN*c%uZx27t!{aEo~u|8X|EW-$tUc zpqjvtw6F(^-}@T(lHp6iyIj;@Z>7<0$?<$Cem2-V7PDq5qY%&3x+Y33RLYHIEoAOS z%5F<~QsR^PQQH*M)rlxg4(Q>Rv6dk^jBSvC50w&r-*>2dqGKPo-P7)db*9E$pR+OC zT0FXh*ucATIwh90;3vf$-VG%~CQx7sj=|fC7-qogekgQju+LgBPRAG9otHE(VEVNx zJ#_^Mk0J(B-en^sjwGgO%Y1TMNm7{6-YceC*5IF$!vJ?@Mv`J*wZd?S1sv%EVKV=x zmRZVl&t2|^2>Pi zb=)JhX9z{EPEUYfFM!ue$7X7RRTWmUQQ@GpLK^tH0pwk8cRn6G%bFn2Z*L`+@g&aR zReQ_F^v6bggz`GJ@R;^)Bc*`5jk6mW?RLj1=Hjom1I9%K0o~ zZWfD-2b1&=3LhfS^a3_Z#ulQ!wC3w+nST;Ft3S(vW(d4nCUpHamv_&&`*n-j_hcjG z920pJnxlDvw2&pB!h1QFMJBu;!t_wzQ};;oP@)8i$M6h}bh@z(gsdt-rlaOYbt4>Mpd?;)L=nLfvKFhJu*{WO?GrKdb5&-=sI55V9D6p&EQGYA z=sMpIQD@Mr1;S+RrP6|%3aj__jb=%!hK*V2q+DUiY0^1*_E}c_-=~nBf{*-vfRAWe zNy+Lcv3~tvDiHUJk5hVuOENY`rp!LTNa0WJcy>~vI%pSt`cb@H9xY;WM-JguI{nyo zqos!qc|G2#x%=<4_x;m0*{Ls@LcINtkfnA`%AO1Q5~PKKii1*Fs5>l(V-mANGM4~S z_k?U)qg%_kuIA<<_O8y-jG(<8L1jhl5tR=0!q9>d#WN|lgqu8&(SL5)HQWl+s3B7q z&5#iBs6sN3P(m?gEUio1`{MLp{0gyZ9w9*9ZxB;nFwe0-T@cF5_G3?>h|Vt7QpQ+ym0GLlP0s^VP&;W6SJL%`$#V>oKRXk6 ztj{~cC_RCa`l*3uB3NW1w0?FMy|KNdOX>KK25=bnf3?on@T#ASlpA z&RzR?m($B55ib|nZN#bX`}?YN{9+X)&Epev7)jgVlmu)kLx-QavP%vfVubo5De>be z`k}K1aI`e@J5bpF#ol{HHI==6!(mWS5h9`>AjF2KGz-O{Bq|CbA}S*Y2(eKDLPS7< zganZ)LaZ>rKv1euBGQzS2%(HJbO;cHG!-d<6NPXzW!^pO{qnr`ddgbwdOpql_bbbj zlbvhteU)D+M$TD^&zp>y34Y%0=Yu)B1?${{UMUszDN#8@H`u?JP&dMp7l@GW zZj&hsJc&J(8)Mgj)~y!ZdbVog53$b{>KX4qJ}Or!NB0gkD=e)w*7ld!1Hy=A?d5Yr zHPOyqry7PALj&2BnZe{>bWySXqH@?ZcG~@$=G~7b5A%auLpNUGZ`hgq`j1%EXg;cq z0tQX1rKob^Q5c|+l!?}mK~npj5#m*WbJ%H!lUPF$I-l-34w{U$6`uSNmujoTD!?=I zevlV#>6x%p^vAY&lkI8m%x%u{dzA@0?B9wE?n|9`3#;K2shEJL=VKJX}zov*X&^dq(&k$CUvHk!6b1mdii}O`3>q)fd73t@KU(=3ok*)0Qoq z)AmW=EvSCAI2h>3dRq}#PuY|X#2Y*#nwEbiEPaB;Jw3cWdOL5oTTz*>#iH9n=Rx21 zI%)d_xSpwrRu~Rfv23?;PkW3V#PBu@5v|KFFkj-Vg!ReCnYc#*?DU)nf3ojOha2KZ zH}^9aTXsG?asQn%mw_Va@X@KrWI2k^+e)&6WF0nXkuCHc12$(1oc|Df7+Umd?E3ZK z-DN*p=Gqpfbs9^7XmkZO-{!VUb}w&m7M3Mf^GY$D>1T zTYrfT%84E)m>L@-&J4_Kt_%*TC`ylx&WRFuT+Unb-2YyHUmEK~Q5yT#9lqgL%2g09 z|H&l&Yhs|MB>8Q2QW>hB>y;cOl<-aO%mFGH5>SoNd*QMUtZMCvio(IBNFH8=fbwF2 zXjhu36;=ofZ@`b8s@@LxI0{YN^c!&PHFC%Mv827E;lB}ePp4WK@J`y?L$YKeLA#4< zkixj0vv3DU(1Nm>vKHr_LgK8hK<~rVdlt1%QcAtHAC2hNbgpR{G?Sg%B_F=q=GmS1 zHfUY;6B8&l#vG!^SG$5bUj&&l4arJUC)lz?-iKNrk-FzIoCP%L-CpqDleQC&irii_ z1e4pC=c+{~8lk(KiMs3MHoum7flu{3zQHlNH1H;NR+Foz2p;x%h!_fbe4t^9!f>C+ zw~OlU6Uopa;@(|v1mbR!7DeR*<#&-J18-CtXDxq7-&B8+QZx~?Mm61dBK*@E zC@I-|x6$I*(s<79So8r|o*8+xS`6k|aq;rWIuvx?IILBBO1PhkWuw}tNIHUOAS(c( z$e`{+>&kM?##6_nt3X33TuAzE50#{NwONdW&b%o3Gi1rSdFyoE!RnfWFy#XMEkbrr z_Jqv+BU@<>Cvk!~e22Ma!E}?3L|=LVT8&kce{j7BQ+%MxyP`X_(a}{Re_jvm1>xQ| z+h44Ozp!mL2##Aso?tC6r{GH+iacQa$-Z|O*V6w@Q~Uou8sh&dwBmpNFg|^!Cjs=8 zc+2U*Xe~}a1GcSxv<_j9|G81jf(jNDKyZD-I zG`9N%R&BSFKrdH>=i5J^8&TUml~O7rQm)lKZfRh>GMhkmKdqsuj|Zr^@EdJ?1a2eL zvxs>NH=Cgi0BbJnYWW%`Fat;8^3VgI>&=$%s^DRX>8SLAsJW*kG$=@fY*ARGt&|=S zZR#6raw(nBuFK@5MKZ10zZ8UCrgc@$vQ%CMy47Dj(^Q|2v=K3+YK>xL*h%t>)PX9F zhi;{oNw4&y*Ab|E%MJ{?_cvCP!wce>MtI~Zud8=GoXIbKD2Q>J=U`*x;2O)@40R8k zB?pe{sGvLtmV)j1vwtBLQDduS3aZ)qNxoKZQt+-BKOS5%72+% z@Gv?OY;7-6FIq?Tl))`$KxgrBc^V?qbRs^8w{VAConBiGPx0N8=ZWV9G#x@`hv%+L z0aA-l-`3FH(_0fr+A1<>d@QFZHy@Kh0FCR514Ocr8JJ$;vE_7hxFnVrNo!Hl%Qgtv~XqDuk;+8epO(bQ}LMP+?q)xran3gIf z`<8qhFOp8`4&Wnf_bNMTIPH7`b=MeCuhK=j8Lt)4_0Z#YWXNd&-s?XXT_W$+zRpo0 z`;+0_=PB(j35?C8)nA>79Ar)JJ(O~dil!$FXus>eR{Pl2CGc(iT}38Y`Q9-UzZ^WT z5woF2!_lN7!Ym(EK!(nt*xxV6p3>Lg*x1$z3zQ~lh*P7K%!T($45cccROi3d_H59_fWz4ngc4PSI@9ol}@_77e! zPBi?pruKE?u=bQ|b0fV0A=3dr_@6=Am2bfeBU*e7s`yyvV z9h|@?09&Tp&27;;F=G~(b;LdVuS*_d+Pk+k-fw6$3q7Hr^bah1#V4w`TvkF~*(u6i zXl(#+`EfBBHn7O$VaKw&yhXlG@=Rc9gv(qos%`R6-(vTHPP-u+MIJfv;Vvrg_no5n zpHI`P@%rW27ulvM5#t_*(Yu;pWvEfSAH3#(yqyEakeAceq7r|)bW-9`TOyF-JGe=) zOU@?;c@tD%5TP38jAd)b`yTFj=vI{EtHZCMpd-KLK6A<-WYE zg;eOp7`nW5NpP=HAxS997>>coFgs^oip)N zQar7&>Mhk}q)DIe*c4qtQ2%Y{(@^kYu=^>|aXO_u&@-euq))~;)pTzw5_lNV6sI|_ z{G}QwCgxS=T#hKHbMlZZOTG5Zn>#r>wX)Mnl@`1It>wlF*Itzx^@|_7wrGe&j%MFa zwrsz*`C(y(qi*u~69TtLzpZ=Y9Nz&q3JD)|ujx1d9Y2LjDu~+9s<$r)0H{ia@Ey3z zqE3EKrf~1gFPGZaRW*HbB|>KlV}sDfnkU=U#`Zc| z_tP}?%j^Ed@$)H)$;K7jo2>?jW!l(PF%3QHe*kU~t9phBaISD6E$m}mp|4!_&! zOq!9+wkR-2ZwV49I*(Lt{OeVa&!&;Z3jY(si=U0nJky?JymOhfWXJGb+8Yj(GpeSIud0^R-o_ zPB*ec`%R1^4$bGa0#7@{_i3I;Q>szVPtP@MB*nYWJ3r9V14Z%f~)RGHc zUcg5uCauQemQ_r`AA5pvSFhqi9<~Je2d%(uYHm8QBXQr3`+N7kj3w#HyG)Q$O(*%< zL<<25!SG$RFeqP-TuZLy&_3Titk(!>7`lK`2Xe!Vs|!NEhY&3#+lX6WcZs$X)8O4* z)GKh=(%jjxkXC;y@JjNLGMMDWP$byPmQVYo?7T1$oT2f%A{c!8jW=V&B(Qo@ex8ZQDGe7k>F>P1!4gvTXU0y!X4Nt2tM8EWMK*pnSEOix5?ZT|zugCnpDtT;HTyo{x*a?=U z8k%Afw6VXI6HmTO8LRH()R;8cRD~5;c97XRpps5F&s9-BbMScwI}i8|D7VW^`gW=P z5O1URuTS~3E?;k15-A_AL%lAECmQoG2*PpFe)%wG3%;^ROJXVS6=&WUpUE>5**qxl zfm7QCbdtS}0JL2rZU>7PM4NEA8np6}gYT}QBIOsg-e!uAz&DE_wM8l_Xp5-*I?ajCydIiz**p z=FwE(i;6+=wI2aeWJQmxK1t@)*@ndbNT@~JPLitsIVD~pOFHy7BF9FSt?KQ!%}1Z zgx>eVBGn9YW4#5JVSr@7X(xOx8Lw%S7~2o_e4ncnR$je#4Kan*mg>NfP%6(Q9=(R3 z$h^gNVWNJ4kB+>fZ-D?Sj>Zr2!YX@=si0N#=Kn^tXXiCm%v$)3?7x^Bc7BLv>iWyP z_=?u=ir;nG8PE|byvrq(=u%EdqpzCH)2tEceyq>i4!OtDjeu`~15+5{_(xOKN5Fid zn^q0X1+VcxHn_O4fAQ;;?T3QZSN^WJ*vTz<*Bg(m&SXxg^BmqSB+)hDtI!nl;pRp1 zT7rwSH@a2p+K`&)VX8SNxCqjgSxKC>!pK^;>NsfZz0QMGi#LkL}8F_{!r8Ll9}w+ z(=3+fHP3j@n6#pr!+Kp3LwPHZoU5NZUjQdL$g<^X0aPUNzDe+c4VGpuZsb$62+yN0 zh`lP`3b2}i4O92purNu;6C(al9~FkHg9)yN=@^eiNh@|NhX=z!(DDUQ;tRp}0+QV7E}&^?HMv(zvn?LK3`}x^ z@A9b{LHlD$Tp&3m#3;CSwb>}C!!NPNIyL7-F#-nitdJcIApY((kzc^ymbvGb5-J&d zW$Y$GCa?022*o$}2mC>4(+Df-u6y>9cwm6&gyY?K*t^k1mUY?xYQdjXKMqXy;?4hZ zMUWDS$6+Oi!Y^r|s)4-pASkyYp|EzeDjpFyxpKh7+;lB2sTJj0_d4n5U}e*enEaWa zx@i?fxfMmv1FSMK#C5NZO+y*;LRAa+09nO&t%50v`D^`FWocN9j5Kp$Gth@GggU zs1$|*+27btASh1t2Y@jOM-R9l<79>OL(>{oJ(+y#AS6oaDPon7SKhZ0rcn5#v7jR!@o zF{w=~Hvp(!7>`PlItjA2XLkBvL>i5Jmo3txqR_-IPNl(1_{}iWofT0uz|F(y-#u2< zP}47XGj{8`kI09A2Kl;FvDFMSR>EZ@(rw{cF}07lg@w{3?SxH_0fMN-0fMUON>Q;@G5TrMPAEo{`GM z6qDofyokbk@Q0SdEBa;NKy8N%RWz z^!{9v^EV<&Jys(Ya}20v?twHrO%o?AfNiaV9bTPi1E=zuU0Z=w-M5(rRuVW!CITla zB8(5sOzIAW=Z2k@95edO2WOR=Ahivif3E*pp#T!_mgDIgq_z;Mm4U!H90j!jW)%U; zTaF7q7*jfvWDjNDHFH9#67VOj@~R?B1AnFrE(TkC=;H)tjx?l=B?&c0A}tR%9gMvd z{-4gqf9Y)e_gj$Fh=2ZFQh0|5N8I`a1nU3a1nxio@87$0o4<8XNyl84C)|HLJglXi zlpOADvg_@TdCc~Xfqh@1bA+b{y0^dkARSSCxJ5d~F^ayiPsboYi84d3Rhs)=&}HPA z)X|&3`Zlg6PQ4}SOk{sE`lQ0z^TL+fvt~u>!MpeSl+uI#nO%%dF{_R1N<<}xaXo^1 z=K<;23WxZ;I-1(2??mINzXz*q*PIHu(T0f1D*=s{i!zEC@8A&ucKxiL#|I#mEW23q z)*v~(Fgs9os$%n^nZgHeaC%?D_TjJ9>g2v}Ix9+Yg^h zI$pOpj|r>R0sl+#Sjzs-1Q&tXrzJ&Z9ujc_xmncZ&oM|JZ-`w%kt^?)?B9pR$J6(Z zFSd|X2xqHDsF|JUrgi@G!<}2TZ~W7u#`s2A`t|ZJ9y!s;wlOYVbt5b{&m~1)F=Q37 z1vRM?dHI#XIF9iTm|=AA++G6_IVC)8v{zhmHv&KL>5m1g8$+7u$ocGZN2XSsQ7Q_+ zLT72CBiPJ2F-kl9gg!R`C_Jlu74fROoL_zwpGi-;vB6^U;P6d_+1sWX1<2KXzRhK`7k&VU+t~>-Y303gwSF4L&|Z$yjdkV||KW|E=TM|8-sZpJOd{x6jNi zE8;nqs7PG!#{EsN--kuwgSMP?s3*Se3Iz%LhLBYb{yO%DLf)Z(p`nZcv}IfpoOj+{ zXs01(E%#@wAB9a^1=hv6w}S7Ila4RNpVMvo(*&RY?eMC@in{rzb%b%b@?Rh_Ue2=>I=;MX%8ykPjUf+mEeCJ7A$t`C| z7Tb?N4DKJKU+NkTm>1Jb@0uE|sO!9x_&I`_Y&D+&ewDoBg>yY?QR@_mOawWaKyA;ulZw`y%<$Lkd1#_3+LgpA<(I8L)oRTxf}r51E-G zyK*9yIg@83Qkx|7W@iV>vo_{b^>yqcO`o~2PwCk-7*%mb1;-9o5m!U^%XY1(n%Qxl zbtTj9R%WXE5dM5zhQZYLLzo9j`D}S7_4RP+Ri$^>1j6-@?>6eZAN2X#QS9iaGhy{w zf?u~@QgkHya>iaCIFJ5?xYhc$Kd=67ub_w0`(r78Wv19i_Qxl#bR~R9=@gBLUA;;% z?|yiBI^!gw=Z)+U*)QmMG5!uix#J`E2$!ttxz6GswHo(OW4hzpxZ{-^CyT>2%V)qc zkma48T)!MHHesX5`5o0USf_O3v5C)}B{OdK?j&oi{}I*c^E-mOz~E+LtLQ}=ThLm) z1>O4;3I~Yi`PVMI>*1K#+Wj_k<>-OP_3`K%ytqXmQ zCwATvVvmmqGL_aMAC?@i$9KQk$5wEWYuU-yK7@)!&ce}>qvX~wv2UnG-Xvxu;@E=+ zj7H~!oj?`@|poy|f%?eSW134vz=t(s?0%(c6GmzLd4!Tu$*oYJ6BSXB%={1T^) z7gCcl#hzQv9lCVvb-T^s9ghPAq<5;{TTtN2SzR921?p(pW`gI8HKppKOa8|r6|YaO z`72Yy^CjVySH#(x-VGPMKXx_~-^?EvKa8G-BPG%D4*=&E@0d^YfaY_>}3n*LQDu z*rj~Hs>v6%_k>Q>;Y^grJHZ%JI|HvOT>7@l*@-EyNh(+tc zV5GYeDa$0SJrad~Ne~aVPwuFRdX7~lta5VM7)Xj~ZmX+45)p=vQcWxV=rv(yGXzU5pMH@F_XcL1PRQZ(5sWP^nfqrW@fD zd;9+XWcO_D^+X^PWB1uAfr?X6@6e~s;qIF||H>D^_YmJPTfmgcL!>?G34ed5rz-Mp zXxn~-MhJ5p-j$#kuQAB+?B2QZpych2?E#F>Pg1fGa1b9Q-H<7E6=mi`@FsMCue15V zFMn3U4i_JJdHCI$OtVc&zQQ_th4Ms#&a!wyQyYKly`At5Z3`}>z=y1Y7)DG3&3@Lmj0f2c1_I)ixI`j<}A_B(omY8Lf=s4c zWV=Ael<2tD+adh&6Ce-2@!8!g4sT~qDs?vZz#_{hlh zPC><|%o%HOBR{Y4$A#OCHT2QjMDal-6SCI>Qy23D_Kl6{E9-~0etVwXr#SC&hYC4S z#u&U6b+>6LMhkL7xK2Oaami(Ks-xNN`Tnq-EV@RzQuV%%PAS?W9&bmEHpK2?pWLVP zHSyuIfSJfguhdK_9-$O+FpJjtLd-mLYHp|ky?bG}mcY883O1UMbIFMz*ewr}1A&s(W_~|EC z&yR=C<`Bb<%^aB?*^2suyoJooU{q(eGitH$xt{MlRO;rYz92o7xDU2#`NAhZZej_Z z0U5)W>y6Uu*ef|nmd@Jy|7i1>c!$<|3=)~Mm{AM+H<0~XOb6#KJBFDtxTzMkX9@%Sv+qCAabzyiJrm?WvT00hlt^ ze&6iY)$abPKFMU_#=~Z6%B>?S-@dtN;ZVU25G97E>y#Du9L6|b&eKUA2+&UtC_EpY zVc@YN{PJ6G?=^02u1_zW*zq9r@P_}%S^VFm=SRQ`4Il}>q#YBNcL+kYVD8srs~6g2 zq;W?|D?@Wmy8p7kkh-eZm#?zJbtq&zG+7dL`Ra>YcZaH>a1D=np4a(dXXtzOsMl!) zX{~(J3NPJM4-ivD|EK|s^?-fXdtVxDDWr+ieIS+kRPYn}|BXl@>D0p^;VO7uaT>ZT zqM$pb983nz`D4@y-XytD+#rA^NICYPb`r1QbOt#>PK1b8!JQNoK(c@V@_i*}x5s7r zNTXp)g+UTgi$@bO#^&*BJqV}{?F89yn`e1FN`=z_h7&;=Zr^eG3yWReCX@d4j^?Z9 zO)7+yv6yp2FHsP0l(_ITJ?~q8Bd{*7 z>>@*>@On9#?Co(qT9uV|S66Jyn=Yt-pg8p&!_CLM-iclfD~PsZ?>C&%TP=G*^a|$U zV{gkiNzx!+B(Q0joHbywZl9*&B6+{ps_4%zJ*cZ2q3hT5o4pkf<^}YiUpGV|zG43% z!}~C}IeEq~GZ@ljl4~=WXF)DV(l~kOFX%;8NSOyt(_+AZPE~R+uX|2qYss2 ztTxD1dw#zPA=CKRUBU{gH$q3Y_>a`nzL_a}w-j!YoRb>KvYQMnlcnU!Jwu+8d}o8! z23NK>oa6Z>`Q!_g#2n-9;;zW-gNiee)nn5l>yGDq$7?74RN_%PP-)aU7hxmU^q!tI z)blU~>Jmr55j?yW+<2jua&9=h+q6yFG=4G0^}VzAx)@j04IF(#*4#@YlpM?Bh~zeEvFCWL)quxoMz`sF{glpnuQ z6dodTD*%A)^sjQWaZ)c%azSd2zgK^I2KH3ZcS!MKo+CV&Q7Oz_L)u9J!0Of-t4wje zx0T^lK5ysppqFQBh52y9Nd=LCbc?bG!^gIA;>cA!MG%wkkWSK`$(|C9K!D!f@r;Yr z2+G^gz*;n9C==vCY092&`tXah6|P6~W+n%|O*v+BJwIL?^K{&eKCwbkYycuh2=HWL z4>+up=poCe>l1=_c&5-|X0jE#p77{PsJQ#I(D%`ZL%&%rdQx&xr1v%q9~>2de;%M6 zQuMML=No-1!;jT76L8qZQ0xVk>4Cf*Q&&u@gz@5Q@Dh)j;w%+h1`x_4 z2J?f}kBN3R_*6-(%h4O*EH0m|``5@%=gMYdS@9h~vr=!(>yhkvT{Dj$wFz$o`P8C< z^s{`JTFVgTNG{1aRzSE%-44j=3z{)p(?k*=LxNw)LE@^bJ=g}!Uwyu)pydLlT(zcY z*P)#QzQbmeb&kO$&LuFljecM#!rGVBWXvP4nQdr?l=6tz`apBD5?EF4CZa@grnpE% zk#1}hhg6A9r-5Zm12Nwe1ic5u2yJI-a%KMDGZ7|UYFFY-v=`l|4nFzWm`kr28Fzx_ zpS{5CpOLQ?nWW==2i{?#Nn7Q^3GfwQHiB2zmgC%O{#DsXq5(e)Cx0*_PeAl;-XUMqV=^fzGA z#yH~p5QAcKyDoDCB3LckiRxpU9AAv#8nI^@`f4aCdYhqyh2&?|b*AJS;hQ6NIa^K6 z02#&F+Po9*Y+d*$Az(sC^kz*L=_c$0Wlq?*FV3%z&sI>14C&t#8? zXUTl8W(&+(rs7P3*=)?AS$~g4dNzAt@O0jndG?-I8-W-gQR1>mOjMoe{UvM?wVEPS z;bD_Wmi^@>wLvsx$3j9^3tRZ*sozYdCpBsDZ-g%F&pZHAU205d(UCksDbrU`zrD*r zu{>U}4};^3r;1%=_iKW6yky04GuWN?8+xbY2sD{h>QFID-z{2qD>!)5Qb!7RVePaw zCpE&_S|_zDz|^#S(WAVa%}3ULJnVNof0euo0OBxnSrY$gc2AMyfHVZ6wjbg32TX1q zG#jn0P;P7368Y8VgTM`mMKC_LUKQ^P&!b#TfgK}f zSgR;OMw435=|`sKI?mgz8FN2`HIBaZ2%saEfe8j|059=qpVWbGIz|>4B+(6V^7U^A z=cMO>mM`Hk6A<8%42IL6n-x?N+&er`NjAGNugGP(p zE)sjo#+tsuev@4krd;n8#i8+F4Qu&aEGZNuVETYxo+`jg)l=nb{i7vz01T~BLs1^q!A*^ zB%2W55uvGBTjI$1fg0?(&T>ayt_kzP&|<0C#HwEV*GcE->BIBa5I^n2CqX>M0SQqs zRk>oS>+LM+U>=8ac)epjgJ)zfm$30a-BWGMD~PLDz}0@FO@;66-}-&VO_R_04XWr# zvgF8VrT1 z<~tlNb8ovuz7)egsO^{;-ky$c#>l|4x(=AUDMj=oU)+Z#@EpXfq81x@KsXv#Kd?D zJ|dVu9c-fibc0rI`tDyAgq@N-@{Z-d5h_v-Q4X;Gwb>7?MXh6Zmj_|BcD(7g+3&C0 zMzb8-CfZb9*UyHto$ckKOK~h+y5Z0iu%A6nmmKS}JB*5FykCwO%Y z85K8Fy*Vq%n!GS|Z#}Z;zwgu(ld}MP=%s~&^3{MS;jbwITf~(%mJy4&{5Jv*&}1$$ z+CTI-0NSsvU8=3<9s!CPp4}x0*>lG~jS-LZJ2O&9x`8*fKD2EeBnB4*L}p%kulPP_ z<16FgS5Lp3L4Fo=kn5Dv0hN*iZ!4KglWd2r_%LYzTcgy;SOxqSnvN7+G+l(Hp)Ek0@zXMs9phfF_P3)67>kK55z1{R8n+N3J{qsRQDqd>y%EH^yJb z`VNni;G+RA0e2R|mpi+PC%)z>4=$2d5v;zS^FF%C(#;Yx>SR%5`$==H>)D#PsN>8x z*ANnvT-iaQA%8!q1-7pz(Z2!Ww9pbbD)V$jf`6+gNZs%o;H#}{Y*OvQ>L4p}s*UwC z98252y4Y(x(ETRirLA+5^$X9L$jlqFnVyA~?0eop8Z1p#KIqaw=Qt@CZL}e&l?okQ zP=p(qo}F!fVgfkp<-P3QcB)bkNa1;F?g}iyMSzeVqO?vTMI{u|rbffnq`l63VVKWQ z1Z};S4-SCLo&)i*Y#i8E#-^75QFXjT3=VOSn~joJNs(OSN^;8%5`ZIO)adFkgXv=o zTZ;;K3}G;&Z{q~@kX0{saK}k*1rd_j6_2(31 z=Lr^5ZIO8!pyrYLM%xC6UZK1RRq`gB+sOJ!FI?Wv9H-h$??EBWI7^5(o~yNdTbKA{ z_*4DU?MU_4YO$&r|1M z#IMi}UP#$qn`fOgwCnrUw*xi1cWP?xbJ7)pTeiZ)tiLpt*eS6fw_u2oqA+ZxI8Ih) z?(OuCb4iMxE%pQ)S=M_SzdkErq6}_2bf?_NI6l!Dv*JQbmf7ezouI7ptBy712-#NI zi<%h2!?ODfT(0TSfyId(rv?E92A`(kNy;f2Z7G=+yJe7-rN@JUgK)kfWh-l&*4sZk zzHaZs?X*Adt;t7z@t3bzDOp2eqW}c-5+)v{Mpq-ZoFg3|b>}Iu%qjOW8vI*b)=3Tf zr0&lNw_^hY z5RfQ*E4d`az+IAKgiLX=EAa^J zWY63S8;g2&?lj%qEnRGl`@<^!`2Wj1ZXvZ}UOOa$MlnY3S)Y6z(F8)kT9Ckb1g$>% zQz?GYSre#w*FFo()=zxwUqndk=`r@3nQgbX<8^yU?Bz39wfB{d78Uwm3XMa!2q}ox zxHJOL{a;V!J_0xkjF!~7ao9w9l_rgpJur=^aP@4^&ZwYGBID@?>(ILyLm^kZQYADE z&v7;(&+F~s=%nGl;$Lm;Qvzzf?zPy|JRp-A*DY`1tZu?ctOBUD_(Uo4AB{^5sUoD< z$=J|j3o+hN*ORt7#fZ+@951`bfr~rOLtmbSaf5Zp#Gl*I#{PjiZDhGb5@u9{bONQ@AZQ6m}(+xF4MT4V?FQMK$L>0+t@W@V7 z%~T?|%_yqVKDGm7Khzku#cJdoN&)U+sYD+cEM}Qe?k;;yr5f8{h|9Op&sn!K+W-u} z$Af7bFLwLcnQUxMer?B(Sv`4FVG3Loy|Lt#B(NX-Fx&_7L%>VHRGDDd&d?;8Is;`& z1A8bv6UUQb&b@&m)8r_MDxvpGf6ZwAtH<6f9&0IA<8Q=8jebs`cvAb7*VvSHa6`V* z68CyXUIm7*J4xIbvLo)KK&$y_4@kLGQRAb%31f@}Ucyi-ccLI`DYgp+Tch z4N*&mK^#@03mjGcJ~V{dSXCbvnX0jC+JxU{Zf8(=lsU)iJ?VWO zghnRG&@1OqZE}d2VelrRL(FxBAKN6?;1cmYs`xwjigwb&aJ58%Xd$~Rb&Ql;As|~C zb^*(PbkrKU0ilfVpAdmbrmi(}Cbyz@*1@4XZ^RLB-gSA#P4@i!>3ovaI?}FPQTuvK z=Y7!)WFe?v8Fx`@<%h^E?=cEZiXyyyzw|us5ZTw(pmPnEw*I*zZ$S&lM!bP5_}+>q zSY{Jx!Id7<+G+7V`(iX*;})ETIuo^ZPqO&^C26r%G}su^ib?>9RA*-|tUm?XHR>(e zO0jZ`mwc4I3ewL7{bqDmO9Q11ujJzs@IEqs)-6x3uDX82_|o^S&?!GTYgXHmLaVWk ze=~^J7)IERh~L4p5;RS^G5R#5`Hlk{7Km_6zcSCA7|z3`j*UIiI(!J!^pwh-&Jbs@0Yu~h}QjNRYVne03BzE(F|sj8K6%b z@^Wc}lO)Cj1Mxu-rQLLNs@(xl0hEafBJ~zv^c3E^9@jUcdAlg-o;hs;LFsg#S#r~n z@)^CgeI>);HB|{ksmBK+QlFXkRGGCY7J%O=j0B8B&?e-TAO^PrZ4Og;E^7!=ZH%=f z{q|^RfjMb1a6KZ|s$-!Yy+>pNN^W6z5ExiYM>H!*bnFMOn@`VGnl7G@IuOjJgFg=y z`y&>~dPGaebZ!_Z4e5~nWO1tN6M-U!2WgO8?b6n4Cs>FjZhQdanb}=9Jzcmerif5| zrZ1eQ`Z%!uHfUxXEDzKWjU5jn(_lB10A?sZ?Uc{O*xLZ%u)bbuyDV4s_=d*tEMfES z!Pmn@>8iH`RkqQ7v1q_4jJphWV3H{~83MoEFC+lr@wF;U!(Uva2TBs&AY#K7yAhFS zZAhL9hAb@=+CD`uzBT}U#8+~4WcqxKQ&;za0rB_ajhTYHnrlr1Qw_D*F;>&z>+1~DDy$gNp0cBeCLDhdO$iJ#k9qApjQpp81reH2w`W3!-G#x{RZ7Cc|P;n zF)SvgAkf`4P}{9BEZBJNCp}MrM?WZgLDF*)MT!GpJUAUeX%pwr0x5dD7Ri%%)Vrt} z)419g>kjg&@V^mSAAP3FipIJlxyrw*pMn_U*XJrLn+#(Fl$3qPOU80NC3ev|ULCQD z^BlH|7$NFx)dlH!0BW@C%&_!VJ`#D+XZAKNwx;WS5yLC;J3hh`KJIqxjeNK&Z}(V8 z6ROl9TKu*6P4!^=Qd8Ze-Wg;u`3i0PI}=+IM{aErJ+YWnh1&}br-T+e@AdQ`R2W}X zo4K8oWIUDURSROpGRL+5^LO96^lObZZ?fA>HJuPL6BLzE@qZpa|0`Wx6@D~Ju7Hh( zrT~(bGpUtaa|y1qQ2>o#SCLMe9tOnUA$T2JCfC4<=Nq9ePi+^V$_{10Ve<7HKwxWq zD={5sRN0)L0&Qg=+kQ1kg84v4NSJ)3Hq;8@UdTTgXoj5-olfCW6$vgbG45@2Ly@jj z+b8MSbX9}>a>G+u*G>)A?9PWB*B(BNw7UQOFzP)Qv6%ST*7_5ysr1*V?DPN-{@gjP?f&RHo zLs0NuhjtpNCqvm8qU_wMAeMMA|d*{H^AO@!7L8 zvz0-b7GbB%7B)<0cIy?aR$4gTT%+-zJvdm~4!;7oZeNE*=f<;@qk=T0wJ-A#O4n6m z5el~ds$He2A{ou~lXVR)@XW#=1mwTdqAoW6gXdr zxz2*FSNAwvll{c?<0%tkvz!Suq}YMEL>t}py>+Bt-p{DH0;HMw%gL2kpT3&rs7d+v z)(+W~28z#!_7C4|tjTutiW)qIqT87#6ys#0C>uGQF%Vua2PwzV@nnCgRWVoabMZPE4Mn zhf;*SF(MUFQow-L0qS?r4DB441_%m3QJbD6u$ zrH%n~JNWoR=^|MY5dJe}eT<<< zE;9sQ5kwUp1Ky#;3(BVPG1n$y&7a>-aL#fl)VOAmML=Z7A)CvKTdU zZ%g}H5&nL~h#kv(GttRdUTqt1u})#JR|tCjE7G9_VT8n5&IE|2RQmp|B7(d4=#X54 zky7dY&b{7W;E)6mV<<<+q@MRB=_E|y<=XM4MTxm3E(YSFyjp(BBC>u{eVm-nQvQJW zLE{7AJ(PgfG2W{J0;n4V_aS&%WGY4hmBjFWiu_w6Qq3Y-+7ekcK)rLH0fW-> z{*nA`gh7wC+)>T>1ibru)AJ~B!TvRA&k^wp6RpeugRSZ8yT;4|bt}g`C zF00);P>IwH(*3wXDMs(Wpoxtw)XCKDO$f&(u}Of$u!edU*p*#ZcOEu={(6`+UPku! zntmT*R>rXIPF4&Pi@`4z4!-mdK0yx+O|>I6NIk%8y8fMU=u&SSrv`K9I-@QEEV3~R zQ?sZW#vIY^NJFLqb;<+B!&wJswS$*x=g!6CxKd6H6OR`KT|%Ly>fo6^#F#g*1nLwg z%Nj5s#Yw@`t*VF4;mq;zplcuAo20iH)`iNL^gW@!wDZAqIJ(s{S4!GHWR#YhAS<}& z`E>+Yj?4C)uZS!gXB*!^Ok+Y8VEqUV@Q3W=Q30mGhSZ<8O9nEhKu#h%hLdy+t_F%X z$NA%UErR_Q_WTE3%{Dm-obaiweG}fe49(@A-WdfE5v88q0n5Qfvp+5B@wmcVGsSm{ zK!4CZHG<5x7GILlfM&=?v^6jbI|i)JsbB@C+K^gsFE2eW+rN#xZd&uUF6Rz?GrWUo zWstsDf#gml+Uzi|PsI~w4KZ5I<$-d`p@owAnz)Xh)>ur;SH*8i;vZl|oZ%pGC0qeC zHOsiPj^0hA_vAVh({Oi<3?)dq8{WpcE_KSk&=S3}I7Prvsig51gga{oYgHWVD4w;$ z!IcJ}`+)v`*n7{YCeyH8G>D3b7z6CzG)lu-tQlpsM!!A1$ZQ3$W5%zkF?^L^|5*xy-at@CH^z0O}2 zi-h-m%6(t=RT8AJSYwzra{R3ffw|HTuH4&nOL`dI0tR#n$j5s`3AhvBuAODX%waaa zrHAs7@XBrpwoUEpSK+htQ8DE?S$}Hp9pX+>?$@D{b+u4uc4>3X-wHXL>*T3?XL|z! zW{B~(=&gHqa!F(ZpzC0ZQ5l#W>PK8qP7fCa4b-r1(M?rbB~w_Fu8`1D3=32IWJ+Vy zC~*GSzGPKYfuBcF^1K>jeZcl!r8ZAOQ$( zsrn5TDIKUJ$hX6Ia9$J-vgBrOqE!}RzR?#;Yhd!B4M&UV<`lqESQ!pn6~Dv-BZBYK zs=%_z(k!#u?A4a2c)b_MbWkfXhdE%D4Lkx8oVP<#ax!Kw>??J#R;=l3iiW17EMDWV z9ovk$7l^shCh!~Jc)9IuzF|kmbGPuX@81y}ZHrecVgwBOGr|+1Zh0{GhW0En9$;&t z6bF3GR-Q;$q?lFLszQ`xxJVpPHrv8leu=vR98Zas29S5M>|;$szbZKPX&A>Agqy{d z3}4z?EBsiK!8)J6W9mmxV)0}{QjMBPxO~InvkXXo7MIIsnRKEPbA+ilpnjpkDJ^Kd zL7N~829KMPSqrv_vyD8sRb-%Y$;W*$al}npn#)bf^4<*xj(~{UUfKMrXC1)g?1cBq zFGl_oF2BXt9HyE2+mqNtP)bs>}G)Gb3)eYq>u4LXJ&0W&+2 z6e)|{M?B1acp_^ApuqQ>Ezy^NQY=)?2TC8X?yTUo;Lt3zl+NC--!;`SEmHv_65pT7{E1VV4oWc&^E+_QXV;zwa&QeJdNK7pu7g)g#0>t686T&Fj9Q zLm6?_Zf~n8QC?B==a84xncQ=}>TE9YAH+zoqLiGLK7LwVVb5Jk+|;7e!h$lG43JBc zemU+>%2SPzOC+UH=}JURaV6`Zu3-#c^ZfH0H4vZD{syd@qh0D8ZZI9hq94Ut@^8~6 z6=1&!bpr6oD5wNjw*oRqVmQrFwWA-iHtr$CM`L1D2M&=dAhYQ=feL^b9?ocW{ik$? z*L}|1x|ceo)J@>2UWMISv5;4sgGRRzkoHy<0AOPZB%R_{*v}?6U>WBjOhqw{!p6%@ zlS%WV*1QEr(QR3Epy&Q(fz0Yf>Steptf-;yLe_-k*e9GF;wybvN26OIZ&X|Y&WDb) zZp(e@+NjwK?(!xxO~gn~VXXh?#k8U2Q1Q2i6i$f1Go%jG+%SBmlQr!k51$^18w zIS2kh9H<2g{1%B+T^!j>I(}A$aM>hAsf^GPCJ$IZu1o{(>^4|NP8A`VM9;tsQN`1nX{n&2`c)(to5VW9l z{lMK0D*nq|a5O==3+Q}(vA3&eUBbv~j>cRb8c8*TavAbd=|sPSr!?SQiv z@jRiBM<_U;U!EuV7OGp#Y%?HinM*+cAogEBWI&}vz_ZF-)Gg{iRoZfQDRX+BuEYdT zyidU>IZpDa`8xWxvrP$%J>uwczbj>Uwt7NECO(hP;wC?-AB-&X{zYz4kioUA3Vk-R zHU#ngOt(hYLFuX@!0AvlSe?)b6uiwn6|_7o1{XnFKY=%F(uU{ZE(X&mnauNx$Gv z&gQ;pi@%@AN8hK>4RDXYme%Zh{9tuW%|Pk2jVt!(v;V_o1Ka+K|8He*CruZ;W3t{< z&@#Yk_11?!x8`oDB005VR>_kR3*hXwAM**X)|Ca9eK8v>o5_4W?0jdF2O*B=(v)}@ z9??b^tMvW_KDjHL_l1f<32(UqV%?x_EwU>sf`dV@MW6F_$&}F^orl7(2IGQ^N0<6u zj&2>6T{!de_rpsN9#Zc`l&zhK@RO@8(Eco5)_W&vPVj-u zQ#JK*TYpKr@I6|wR4-rH7-D`15%qtdZHLwe`Z^jK#*2O1SZh?Ll7(xbC2^&OG^74&`i*CPj{hZk#?|5tQrgBvZyi1=mezbq4*u)@o%7ularSSj=!C*oA)mr% zyXsaYYSxrr-g>V)eG8@O-OZHVUY!^Je`wABQA$u92})(0&=oV=&P*090^A#> zE@oubcnXBll(tmu5cU*L#guYPp+8NHIyslE!-mW{{+9Dm_i88KOdfG-C2vH~+ClqE zeyZ9EUlEHKmTOP0OaTYrN`jej)-7HiD;-p#!#K+cx;wmj4=; zy!NE4%Zc9*bN|)S|9@w-pxvX{p>lr9v8Fo7={&a4lb$D(I@duv;-CA;S2i043LE@H z?)vY2gw1arMP3-NS^VO!_!*(jhIr$1$Sy3r#WzFc0rg8Ay0F9MT|UnKj9d1kP<*e= z*sm0ud3~KtjPa_P)#^Pf%hANbZ?FnKUZ*o;sQ{D1rQ|HX~8=znR3 zOT6@x-jRabPhli+(%R6h*c6jB8&VBc-1V}1n7Zxl@z2pA%OBUR--TEgfLcv63*=jr z6#+auFu=31JAR}i7nKz{Qs=aRd6JN?QkM@`Abwg zvOpwr3 zo8!$7jL3p9hW#>?KJn}Qz!G&yoUvl%?2hkgGt^B8r0B$m$2j-cTnEDQU)yIbuua#} z3HSsSB8r*Rfb8%#rnlKY1IBc#bJs$rYIB~A;l?I^3Yaj-JS7V98}TCM6BN;AiaQo> z@`^o4q*cwyv+FUvNXq|x2Xx9!05Z62fid4hS33C!uoZUc?q@Ww-jX=OrI%R4f(YQi z6G}J}JFYxa5c@%$^?D@c`oiu*mLErd*J`06;R=GBCy7p^ZF>iMcW9Q?$d8%bs(?eg zV*JB2R{a?{CHM(Ld)e)1(`~g2cPD1!3f`B#Z0;++%%;8s9=|*tfTUk&uBkU10Yr_7g>9gT=ZVwshzgVlsnvz@xor;{rK0p zvlt$FyPD#p~0I4)CnU~dV(z0sPr zwtH1BN{5nmbV!AgIz1fs+nhaZ7M)UEWKD4_=F|USG&GrfD?m^~?s{?cNmDK%mmqAf_(}6-SJ;`iBb&1H7GW82% zdG{4lMm6PgR^QmgZ@EI!sX&ZVM{UDi(r>jxHp`Zpwu(lcDroSCvz|<_ua4noe=+c4dl;idBXF=CKQ}!|A44{)rqC4met{D|o1ULY|S-zUR26j6g;D6~y zK-JQWkH$gc-UFq!k820);!eHYe6zf|?9^DlPtCV`vNOMtZ~vwB<&S@>m~}&GU@4Lj zln5U=Jv~Zo-KH^pdm&@ocWA!*ot@0uD~Xs)+HiM9@o_wUmHlW(b7@d8`;nczv;J4a zjqu?y|4EbD1%ZRX=5g9ivM9UuX7J@ z?eRDMMY<#lt%0GZUM6&b>H3_=V3LFEzfe)1JErJw`w{o4xU{)v`iMYbrRTKv!>xcy z^Sc=@lD_5(wWjR;N9{#H-^3Egw@`+h9je2ywRqMr$6JbS`^#{=#e|17%#`6`G5O&0moQv&;L z7w@j$i4GXEieBekrEuLEGLMLYX3)7Y_7>9mRDQj8)xqtM-;X2zk@6k4D0GSnVSEz{N++nsm%qX4&tRS5hE=uLl7lk)~nJs%Qtp`GLzmoMlAH(!h z_b;z2s48cRze_y>V?^yg*lDg939JU&e52eU5#u~1sxqBUQ*Nias_QUzDwnr_z(ft{ zZ!#U{E>)qSt!?IkS4U^&Z1g&~hR#>3!hV83`&OOiRzeAzO|K3g@e5D?SR=dtY^kV) z1#dUGFCUTk%Clg+K z6s6YS^l>L@o5)MXVA{A(zcV@SlJL(}BRnUHdqD4e+3wksCbf40%I=PqHR(CrTch&| z185KN6{@WQ`gt68WL!$-iA+^HVPY9&q{C7l1|!jEl9ZdwHMg}JjZwB~R@6Zl#*zoA zl^`++)A)4iw=heK>jm-r|MewtgO3B)+6ou=wd)+G6K2jY)P`Zh7L>`L=|QshTH>j|BT+(5zFYHC}zB01rF_NS%#EJ_Y==vNN>~sO} z#Qs}kz$I~o*n`k$=55R-kcs^{Rb?;6>QJ}z+A}JcJf3uGJAXAVE-%bXl)SVcB(`Y6 z$lsXZk?Z1qit_@OwynIy=^w1b3FZ-$2i*{4B9UR46;dqi?`ofnmJ{Un;g?zI3c7)5EuL-9Sa}1{I!Gy z1PY;1NTIbvkS%4s%T!pxYNa=&%kAyO0gfYO?L2!qb!!c5S}L4$Ov=6@wjp*}?g(@{ zE-z{a+O=$1Ffj7IIc**NH`w z*M1~rU(|xe>8-&W>q#1tqkcj)1}EBpx}YgUY4}df^<^qjYvsN-tC?$vcw}|`$BYFj zgMkfI`<;_#6pMX`vxEZ4#Ha<)eIn-UNP)VHbLWncUQxiWjHS48X8OJk`1Cf`^K zW>S;iIREC4$V}QU5MWWGi=Ok_a<5%jmQ;sQ-09z0?c&+~+o8O`8PjsD^99j3nxWcSNa42sU?ewPCz6%>_!5vYe^efxr*pg1 zE`96S%=U#OZ$=U@sr172JZL+etgWb0T!)ze_%GrGVmr8NIE$z7Rm_a?DE(8y1qrQr zoT;NaIAEvL^DJZ>8>CCNK_DQ9F(Vd`hGZxAFOHAJXRRIhy*VqH$2JUV6mVY%+@En_#O zfwrPH$3H({bMhvcYr>k^9&67b6)y1j)-LjJm87mceSdg?-1-Z+C#5~(fERF|mEpW= zXM<@<*=*U73>+~#{XlEYp`;_7BVI=bZ{4%LUaAG+`Iu>_TC(h>*dlbi2&nY5C8oS1 zvKqD#ngJTe6q*?Uvo}j9Ixt|>R~@)X%E*Ya2 z2afZ=yqDvTk5y3>IOyv)KezbC1|HDWz{Oyh!z6 zA5z~~itX@D$5$ge03`vhe#rgRi^xN*kitF^?g~oLIKC5Q3ddkggU$v}q-&y(x)f|{ zkYWA#V5_1lPi)4D==5?oyPXFGQX6aKrZ<9?wNUW5yG#$_DH#3q5T@{+AH;9Z<|otE z37Y&M-*MktDi>tJNc&Ts!PqEV(#Elca!T|uUB3O1z&w)_@w8R{F0Q?7r|{-rp5`^; zGg-4;Gr+CpcB0dAb<|lZ;Pr5mrH4Vl&*==!W;w8GP;D<#xykYEsFavskF6<@ahncu zUYZ@hBN44^7Zxu(CM(jPQ+A`YFuDW`pP2a5Um) zQ9R3x8zxFcyLQH!1V#s%W37yA9AP5hY4>M(sCDm&cc*@T4|4>_U4H`)hMK-I z+oK3!)(R5hhc8&80El2AfL0|!a)wnJhBw0!W-}~z4XE_Qv&MKh9HmXch`Q?=hU~d( zDG6;2L1iVcmS&3Cy6=aD&4roQV_nqK2KXcKy5)9XwLV&ImoLcDl^do|NN1w_vy>ap z4I?LDcFP$IjwR(C0i{1p)so_qVv1736U!OWvdv$<+2l4p_M41%0MXlvnYF=}zj*Xc^v!DcD17G?kMc>A3rgXOH1H~;J0^MkNvujOOBNR!mK`4%t}U8c=O0YWJiz@+?*%U z3}crx`ANKQbJjplD5j?~ruNHiY96p9Xj2N>t9~G|-Zs39>Q0E0G<)thIdJ9a)QO;X z+#HhqL!Fss1T9##^dH0@k7%QKg*P}s=xW!w9SAU|U*ZVcgWPq+HMve_;PN-318_IA zq1rnch2*TCxL|_~>?`P1xjpfGHjy5Ar@2FxIF^;U``x>qo$>vCHT`ItTXzpC7F^9y zrgS1U+03*RHB7@ZEKU2I_sd0!7yV6oMHIuKQ!jsleO))d2e=q{)dm z?~qb1==O9_U@nZdX-R+ZJJ=(9F|!M=OM7FvULMLrr3<@c`uUgosVMkfocN3Lk|J2g z7wYCzjHj`TC}h_^u*r5@efX65=qa1s=Cw_OXj{9B%(IE~>dV`-d!4t--4vzpTBR>_ zJ!~%jCPl?_>?o!R##`!DjjlWwh)1!En4v^xPq835cf+u6AJcAKlhoXyXR*wbuzzqIH!^^o$A zY9%Z(O=5GbXm5mF44WvdDSULay3D9UgOUsGJ)g=o8R$Q7=R@3%DdnD{1gi{(BlEM6bh2Q2pk|Hfwt6Q29TI4@*9lKVrh} z{~)64URi&l!lG}zI_`4!b}n=x&|I>&KzWi9EA?(8Bf~grp?vP@DD?2_1<4Ol8&!vp zk4`4f<-|&lebc{yUppaO?Q7bQA7cS5YXU9-szP;DbA0=|BR4FDx@JebaR48iUQpTt z-X`Akmh+xc+JOHoFUQD3j&08_wxuqCp7XncP#WQ26w`Rp#PD5LY=q=@{`u8bp18H; zq*;5Xdp3oStnNQUT%&2d{Rcq;C(}_V81!JiJigFJ{P{M@2V)~BrGiH17H2&i&J9T- zq5XP|jtcBSS3rp1Z~nc9V7JhaJ$%Tn`?t!6?{376fNG0&l-~N&oR^c7Dgu1hC~5NH zV!4yFsMFh&;?EDr`Md86c4gCUJMU?4or&;k+16f;SJaOp$ZGmzO%x zAa%N5VF2@y#J7mJu*k!1dq82Vwo}dkaTDc7X_>`?JxfXCpG}Jle38za@y8aZ-RGT9? z)p-TF+|B~aTc-Glm^GAKla@3f9;CVhRw%)Y&WJKU)Q=9Y33I-&(gA>pfGyQ1bzpLK z(q0X5b^})uW-5I#*{;XEQ&fF9NH;J>pll1;*&jJdY*An=;NR{MeptgrK{d^pC!08& zp9p&!?CbmQ9d>-b_2i%b)>{|(87#AWI9quDkfN*0%OqSQ(BTCHA>~#%a(AA;8OZmR zGvb@@l5ZtBZm0Un#5Mh;v(@P%>UtFdSy7S&=rXU?NJGZ*8y_U??s`P!x)Ir(A9|r zX*}WuMRK%9S*bJb%Jrz?R>SAJy-X^K!WR5j=8?9aotbMsrRc4!o}AQL*xELmgwcoh ziLonG4$x92IS=+}i#g4?U*PAO_G$OQAdgve=yG;!@g;|=?=P9<%(d`ipN$5N{@w9; zJ%ZB3^Bx|O@TUiXgqpj$X>G|RAm`|6|HSAVvxR#|dS2wbM2Pd{NY!d5pa7fW3f*{ILyaM9xlChD5E)jp;`^!2nC+~N z7z;+C%>Dr&n!g{~8|@gH;_S27H>RgHO(L^CR^1;mFx}*Iy$le~LPsZWY4fp{*(s=1 zpe-Q7R-YcphuU({Z>ic68)8dCP`w=AV)SM2k14oNy3j>4=p)&Uns(HgX3_E_v8a_( z4QHCpH!wXKGyUUdHfN1#6JOql^Of+ESqAhFhHWg6F zEkB}p!*f%fYP8#1JM_{({KzH$_hzLF4WCN#g&tDRmwhu%hwGb}M;ev;YJS)Li|XZ| zTAkU#(gR?Ic>r7irTI5OibQlf+CE4OGVHQ~an1)sT0{a!XOT5lUDw+k= zBD1i}hC7hHAkQ&?mp2*h_^11U0eh08;K%3Vjn&s}&Zf(cYR#jkl@hGb)0Msk6o2j= ze9%!h$hE_EQ^-8aWzbGb!(NW1XQ&$BMY>DUbDw?nD5E?XIpYxHFg$DjcYuHSUD>h@ zRkhY!I)ZjlMcxN?P!6pfukgZPnB8su@Z%K)aEJ0N)kh7~c$etIB1v?r%1F#bQuj2$ z!O=z3Lvr-3dmW~h`fpWU;zSPTZ6td|hZTz~#Tvi~XB*9Oau$;3uM`rpq8U-1rz>C9 z589|6ubfqo;C}gM5A{>pR@y6WHKsB3FgR!Zo8MjKP=y$nyR)u0As z_OmNTeyXe-xIAy+<5^dO(<4&)h@{h@cco*VdQY?zqx^RABER>1Li9LZ$8Qwpka>j| zD^1@h_@vwE*d{Nt&@OOq=`Q%~#v5E&MJLiQLKe?aLx`8#N8bd>VAjq5lj;N>{((@;Z z44Y1u!Lh*kK1${QnqjA7wYkN#tb46&f0YYa2>>i`> zIzXEa^&b9#Psv5(3SF-9J9Ag`<(g;Xh_khXEDqa(^ORsw@ZQt_xI(>#bp5TuRy;Yl zg0kLn!}t{FX0S;r{b!n90cRiVbWv!Pc4fRQLJ^2rqNK41l57i%%W)-7CbzHAk*_S1 z%CJY0&KCo4^ZkUG*QcuBYgyYL2$bIO?}3}oE+q+O@qic4v_$DaHSN#8i%mnBXiNyc zn$-Ae1GYU z9A?jk4xneHFTPIqeAw&Q&>rdHsy$aE5oOqsQ*swUq3!sU-$n0$FC&|wI{!qEwJoqb zQ|e;X?^~HMzy2;|V{?*Tb<)>m;kJh6x9;xRBkMuXA~k{^wRiF~B0O|l?TH_(mgya- zt5X+XhDs)ft|`o-o&xJs@0wauhs>)y5~9BTWvb9%ym5}+dIGZvaJKo= zBhOV%eN=Y|G8wftN@PsgflL52?Q0bUaAwyv%}*d%5FLH}iGNsTw14iS^&r5Y)F|+$ zy7({0v!Wk{m&;bQxQu}7d@W`h?4YPnr)zY&pZj|~R-J_D^27fiq~W8sz%|al3wMGbC!&N7UFl1XV3ZkB7=U$~3|t zCy-UW{8Et4+qomOl@y=Ola$QPtWEfdAgw)91f67++m`a2)iIfA_GQ0$7s9b_z2R(9 zsm%ZDf^U{@UB%0k8;)4OJ~risc_#s`JP7)wFQPmJ#g8F4B-m-SoGq+h;3_E|NiZ`_ zbhZZ-mfriCu4F1HPGYg^X$3KP?z>^X*ITjQ@58ekK3Utw}P4Gl4G+Bj>CBNH1Ea7!!YCRO=35#~-Q#pC0{j%TBJ_01XP zgz)f?+OQ|_u=eL!x8^$fdgd&6Z)OzxN!ngeBscbw9i z_7>zRhIX8F_JP{GQ$;IiJ17xtzf(}B2m1Q`Gd%^)E@g1Er+!}7mIim1!57t8pQK{~ zbI-JN&l6^qZiP3l1^wKMB_oqrtEeQv&cL?glSEZ)9%?1%M=)8lZD!aGk%7wV^tY_I z(DwM*Q`I$4#_wPANya&eP5uqSpw=bb{D=z+J~twOcuM9gNBYB|%40opw(Hw@R4S_S zLDjg;o=zL__9C;b%xd}y3i*WGB#{kY6G&`_yqe@LoJSFt>^}bSIPA%w+3Qv|x9S(| z4vi_LABa)Z5W`#j6th~>i(OPhRG&h^N9<;Yzfc|e!&TOyiFXe{*kp`VZ5=@>bLcRU z?gRu7)o|Jaee|2KCqLxCbODtRL?%nt7lYfBU~qsJ~%)%Cy7ORz#c~7Ny43| zduh4uC2@+3={{j;EZ;#$`ZRRRG3^G$dpZ%ir>K>0l??#^#}~#yLz?AUQA#V-u{5B4 zL3ZHy3~%LLpi^N>k;!yjYE(7=1hFp$X*>6WlEjS?d;l7p$;@-%B$HM93VPy*k$1c3 zQj?6|kj?b-K=d@z-|{bAM~Ig?+@_23VnSsJN)MsR7%JkiLD+9UMh8YpTtxBWdqI$f z4SmDO53=;bi=gMk69k&Yz#K6SGwx+JI#}>w$jC0(<7jmbchy_m%u+X*eCXa=9)hhb0O+5vkTl6_%wC1~_l@yOAD0;CN6O&>eLP+(w@ zlsnAzg@$B};2~F6Vyjr~W!|kZ`xzi#4f`t_*(H@lQGK6MvRhxkIA3T+>HRb}F%(bai6>Cjz%DJ!(qTd4Hr$`{ub z_RXGcsDSrGgu1AD;|jmHDM}vNq76lS*0hL7IoLOC_+kmLq_%B*ssiX>{2h8Lj$=r5 zADEuwrsEAbcCg+!IzeW??+pL6e74n`t3QQ>81LZ=ecr5qewB9Nlw){$$ta<6w2K%~ z>VI%T>s-E8ov<@Uj@9U?#l+cL3upWX=m_jNt}z9txFx85Siq_4n{md=7fqdn9C&zx zOD9LVmfn$inl}@@8{w_Ayn7qX%36P3W>_2$18z+Y%4nqD(SIw_)f0?c9z<^hn<(q5VRT1SW*&+jSx+}TZxjSb6;xPDCl9jdPlKld+1Dp8?;U~SFvEgx_r zEgQi*DANp`*|9$Pu*uk)Zb{~_82>04q(t4DhVCB3eQ4eC>M`;Sb|nSZnfnv?Wg7UX z&M`eWTK~h?`g{K}Wqu7jOYjfMi74)lcsda?n-Ik|nfMWY|04V9kXcb;b+iAgB@KT| z36kxL|4v)|80ACb({<^W=qcD2MLc@i7!VG{^Cxmm)Y%`@tU0pGxLyrvgNxmw<*J{d zUlYYsan|hsW>{KJ-ADw`Gr1^;;@-Y$@~-qqYTQuMwb@YRstr{y)2D zty~?A1@(NTI-h2MqX|WenF*S$c*z)Nj)RhoH4<&z{R@ zIk%((arQqrYX4I*>HoSvM1Ee7_KeVaM9>-h68O!`o?r@E%i*%lc;)Xn!M z8je@RMP0G)>G|{s{jj^@zzwqIuLiF!K)5-n0l;bHLI0#GDcB|~Uc*+IF?5x_nrL~g z__^Da5Tb-@j+<;~dQcEPpVo6#FDxYMX90eCR&R{B`|SIGK=0p?e^TS5z9bVjBhQ&{O!GoZ)w#uzZoC0evjQTG)jVe| zr+n+;SY~aXnPJcAFC979Jj5ocxJK_TeG)2Uq?(2MV#IeG&qRa(P>qoy7U-bDDEzJ= z-yf`Y7fXCb&|)BLmh1V#+lkQCGl%80n(=MasCC4Uvcu2Q^7k+KkZCgXExe|`T8&d~ z55IxACs0M_Yudp)xC;*&5!30YxJ_bTnQuPTejw62MPP<$WKRTHz&FMEOQ+mlLd=xX z$iS^92j=SM4|4`<;%q)7O&gUR~d+q3JsQcl(JO{?pUh0OzDU-d9J%4AN$ys5RQSdCl&z*Ex;p6xEj(PL) zaeu^TjVYB3g-$P#-&6b!Fy2GyxE75LTq3{M&b8#MqMmRxO^yQ6SqkH*TLHwwbFlF{vlwK6~ap0D@ zxe3ahDu0sGDGo$$M_zc|v%8!E_O}I>70O@rJ{@ z0BhvoW z^1`?Fp^QWQ=N}Brrpzf7YV~XXiG>zReWfpLfVL7aWwy{d_Oh025U6~he^LM1=vL4s zX|}(5GO01^-7J6eRJ!Z~)OE{w7pQXgW*1z_5)_y`3T96RZEmW3LBhJ?r;pf{Z+2|o zeNanT=88)3R2~Pa@hq%3pI&>sSYFcU*80G5JH%+Q+2dA^LCNvSOFj-Vczpd){02r_ z*2?CH%QoVdsor~Mmf4J4bDrlJBL>w^v0-XY#R8PA=@wO*-lF# z4?*kXn46MWhQ^?;$-MwB!OKx;_SjWl{4cm!3OyB71U>ro7LEX{6zvIuz9XLRvvFwT`;n3Sub&qhjo02=mgn!WO#2#QF}Hem zCRkXYY{euwQt*o0S@mpUT}g)Mm{Rdr7nETA%#kXM?w`wEInK%s@A*QPoTcD5Uj;Hl z>gn+wydowO5T%~Zk>Tx@&Et*PX?PP{kmgOU6* zFDj&zKr`k*zUlL1{mG$PhfLqhA7s@Q|KkNDX^LIX0ZEPijzGU@+q-Yh`nUCJcU-vB zr82mFqw4o{TGg8(0N6ymt{iEu%2fj(tezV4N}bBFW7@R-gGdU5nO_YYfJ?~oB7bvN z%|hMFDOZ%`J20RHy`VT(RCya^rqR8`GS#dACgz`cHhR)^wLgs6DWw<`puB{4Pv`C$ zs`jo5yd)YHTpn8Lf;*I9J&O5$SthB^m_1dM`Wy03jwLI>1Y6zJV&kOIEf{B71X8X7 z832}~&TBHxpA5nba&*6-^zN*Wb3ZxoR6c;SqZ?n!sJj+(==uAAWA=yY42CBbhy+3j zg4S8oMPB479|l}(*s&?9h4>w&;IW^`3iXgn3r3ialINX>T&o{x#~2GmOtn}GB~d`)DxMy zUnZ+`rReFvz0z3H;n)1*m34I)-QGL1GIE}e@x$##$w!;kuQQbyN%=QXb@*X!C~Fwm z5`>Z;=1Q4nFufhMhUQ4XuVBW{F&P}gw>8~fI9zk1{MY)&Uw+7jQte$lHab#GEQyn^ zjK?zWjm9-lfTUedO3$DzQXL0NG6Ck|;3+yi7}9AQ>Z3UM4wNBNf4#+%IIUH=Jmy)I ziC5WHoG&EOtgBOH<)z_I{_KdTbg!*xXyR5Pet3!n*~*{68wR0}_vZ1#IEmn?gn4U- zV+cz^NaH16R3tJZ8UcB+u_g%;DX^|ga&av8=}G{H5j)+OgRL7#6^jj{3JQTpgJ72H0n z%D%3e|z6Z-3!R%c1BSUmPTFhREM;{Z#}ZLk+)3g$jlzz?E{EX_{$@q!j^&s$ue z8&cRuDr-}_56cI~?v-8=R%6Uy&e)qQ_&`sGN;F<-jF|Yz(ww9;L%@#@Kqa$Sak{b9m8B zC?4H8PoOiw5bu5E3CwRB!Yt1IrI%a^j^u7~ zHO?hJV$2VZZzYn8OdB5~E5T%GxoR)8pfd7SJQ%{PRxOqzTaYU#fKhHEk7C8EJWB9* z;*XrNj`I7V=cTg4Jm0~Z?M=?Woh3`1>7Fzbd%CJBULhouvDZIp!F+%Y{H#uQ-kG#E z8a15l8d#sU8OSRNDsPW3JQSCYd5?VvxsE{PfYi^~WECDPp5qKRsFOi2onk^=CkJHJ z**{-wXlknMrJ+Zs8XnigcRF>arAYebrn-~M^5Q+y9;CgFcZg`wc?v57p(534lty=a z9J`3B(?~X;jPu3}VLE{>$?-WZh_rBbmv`MVJs@8qy7iev_Ub2v+gltKxewZTIV#>r zNgF*I8$CV_Y^)=!IEUIu$m&uVx>8oQO@3C;3yR48xml)M<&`ZB_)Yy_ zq4lpV19@-TpL|`r%HFBui_Cx7>)p05j^BQaI-}{+nDjXti&?N$(#@x^wZ{0@Y#rHC z;FvM2a%P=0>zKWDxIkU@{5=d@F4?wQv;IMx=(jhYddIc`@r$QE7NiOe$N%h!pfOcf z;g4ec@NCOCD8mdw2Ko=)3w%qpCoE0B5M^^*=|42X=`Qm3_e(kdP0u*%y6A69ud=58 z^R=Y)mL0(O9A(b^xD{Vvs=nvVXUT)vC#&EzG27@+KA!)qeGJ!n zy|gTmQ|FRjF~Ua(HhD->Pe6}#`njtCV3W_)nZ>N76t((e?u|bL<~n6WUc=}3Qfz1} za~UN^bs7*h2P22)xYOM-54%ly_z8c~R8N#;MbYScecz+C55~RwKQ(4K86&}zrmM8Cu(r!OpB=pB16^DADgpE`4)@^S)8YP(=3av z(_IWvcM0dx&0LYO>OAnZ@&J&&Nwr4a)rw7gKyx1AhVj#K*9bt$2x_UV^D3#AQD@K^ zIW~RgMX2y8C}XXOjv={emvh&UPR(4;9r~rddSJ$G!iGe?kXUZ7XMpTw4R=dEg58R} ziCv~KoqS>{Xwrpd+c4{fifTv#2ebK%v`Y;i1iSxSE5rLb6s}FpyR*FF^c#duE2@@# zgK7aNXi{)u(qVHck`XB~p*Z>1sh?nLot;YE6zLA99O((w=|0CDP9z0N`KKytIJYhu zzpP9Ay7#Nr0+PoZc2|&Lw^Da0Dhbqq>tKiWU5Dj|01>zC2SL7h)n8?+D}-?TSMxIe zKBu(np|uUT*q1%+Myv07wH%rxyVU~DBv#gg`g*Q~X>7Znw`0FuOy%MTTKuEx*`t``!99$V@uJv9BIm0SWU zjsD_2Ynl03Ihn`T(F|c%ls9?FO+LE~fjE<8s^Dj1$<9s^i;ZMsg5%y|_EbrsRZZC? zo5BfpAz`oRzp?k;VNI=VzJCx9l@gjDH7Ft|LUc<}2nlXPM5I~h5EYdsWU~PY5)v$Q z0fj9nYzc~h2mz5MEdfGN5vhWNn#6(>Nfg796wl*3=bf4JJ2StTIoEZr^Ugc-XRZs@ zde&3cdY=3K-rvt#-YVmIv_((uIkA<7D|+=LXjedw&UWX$nDd#iasziM;9UBNopo~O z_cwMDUk++si2nto48E2LHh?teI^x@}koWO1>SnxUho2$j$jx>c2t8a>2F%l@4W8wF zq)!|9%567S%`?iWDf6{w8Ky;Nc*kxz&QLHNy&v|6*c24O1F-LrN=0GKN_8#d}Zsec`bg6Uv``ArN`e#b1ufzLp zv0j0~4WvN1lsEI+;0558U&C|9?3tJq?mypi|MkIDWic#kPrqQZGmrQI1-^`X@DMZe zH85fJcn8OU<4TB$80Sx~{>83Ggww+Nz_(+kTQ$4Soh_N!4VTxa<0KbWv1(=_Hcoy2qE=4Ri=&W2eSdmtdU8Ro-}$dDwfPlsq?k?ydjYsRpzKde*8LeV&RUq z+CvxkJ>vES&_T|?6wa>GZ!csX$~ELg3ZI0ne3DDxj4@4fJ82sTN9v)f5N%M&X_0$9 zQWm|?{?QSbS(;KyqaJz(RXd+<=rx+UCww@X6R*7hgch3I)eO-lVkcQcgchKvP-6_| z_c13D1J|amKfxReTfrtX;MXaFGgXYhX*KfEoCQzLbkzed-}y^Trd_pre4iWZr4XzF z%CK)?F>exq$UveHy25gn#P8$93JXk;nFV{mp0s#kI>>J`F5|K!`D&y_R}c<$p6wXX zW$tw;w`i{ESK-}dc2IF^>VcFThKhn-o78gaKUOUNZM$t~e!PLw1CvG@I?*YT;-0_q zhJa*aOi3V5e-(QhXGs296Xj6|CSj@17*4W<6gKuP zsPbFv9J?Xo%jfV=1sK9g^akwAkZ%`wgJZzZx*z15HT`yTORp}zzRRR(1{UlF>@~vq zGY|7$EO%#`rx2uANV#A}LAut|n|Hi5CrU(I>D%78IAd~XkkRCq{Zi$`KI~JwMK&LS zH(qE%)I@iXIH>SQ3onBXCI;3Zm@y(q;z{grvp7OFojq+5rw~a;F zNAk`2o3q;k%QwJYb9=z6(VTD;==79`BO*)4zXYGn?rB@vw)!h{hP}{wqSLKGTYVUJ z_=#+Dpv8r1f2QL_kA`H^=5#H=!NTCDf$nQJ)(TR2>Nyin#Fj|%R0JN$YPbq$1Ph?x zz{FV%(&$$AeVxL}l*XraSUK2@uB3JD3=fD7(%qH4dcOYI@f}Z_Q>7=|Qs<{P7QqBx zAfQ*00HWHfzY(OMD`3DtMp7WqN$#J=su9-* zQq94~tY3}PVZ$ol#|%ZV%yOE{Z!GpCEt>XXr9(&)7QuRrhnYv?*8Ws?qy8PVNnpWqF9!?q@a-`miyiJt&CPFAiO! zH}#F?YrV_%vng6oRWGU##hA~9*5%iCIrJlq8c9O z^+w5ajQAq1Dr9XnIch(pt5%h`m5WU?4UO$w8}_pOP(qdzRhbst$u-|u!eAKn_5Udb z@%ei}0+gsqh#3W`VIHP_Y?1lMcLFLBZL;Sd5_mzXY}pI^PCprLR1cVVW>@RA4LQhk z6oN8Wusw-hpsQ|MKIOIJLDS)9j0<hlSay}BEu77>dzpl-KsraB=0vq*#3hmbL; zN-Wqs@=b3v>e*71Y=qw^!KT8f$;-Hu1y{lsog8hkt(fczRrh94c%`QGA|2- zejaR|xQ^Hdg5a17NEwLSJ|o_uj#6M&Z4vy+b??H+e@bJ)H$ykD&_eeR!@Gsv>o`a=m*_bYW6kPQ8cn{YFm@ zbUz;DH4dW8<>dBDJoA{j6+Mt%qEjK#}G<*{s}1aF|qfu{Akp@-?7TUm)GaB zt5O;I^jMmbLxk1v0+Q2ki2H%e5!z>cV3`e_p!XJ9wS4Vdb5L^_kYbQkfJz8Hz6ucQ zGwTTY&~46y!yBrGU>`T&iXa43%FZ!zlUo#uAa5)b3djiRzT4np3urYnMs(7)o9*YB zUxx5e6j*KJP(XsKi+DA}SODXj4DmYD(Y)_|SyooR(-KHvF3Vs+VAJ zJf<%?YIfr7)@z;XH&8-L8iOL!o}0vlhPfS4>>eEwGHeyItq~3)I=R-dYDodao6x$A zBSZXd#^&3liKv*3uA7Gz*3SQ_U{<;vMmCluzMYsK=v7%b2(o7nBOFX0GGXXff6ZlX zD45=;m&#Zp-a+VF6f-(G`5iW0jtw|#y+7{4)aodGjdOLWrJ?!(?J zXJgY$Li*~%xM!1n-JVY;e|Ll_9h80LEZOPWCv)xMt)utZQP20EJAEqAdcUqRtlCy{ zZ-wjOTZgZ0x>b0{b?$Ksydz%G!~ZU!u_)E!b@cY?iqtr?+sn0&Is+25Fc%3|y0WF< z(Syua{@V+DLbShYEFa;AH|F1{Isfck9_%NpEOr0cB+_kV*Y7vZ0WUTG8Qr)~h%obg z;W-x@G_wJcUc#kaw$@&<#g#7Oe=+>feO=oZ`%k)TK5V~VTv_aY`pqfW$+#?kd60_P zdm}3*ydw4;u2pxb`$O0-eL3u`z;%Bq;N0*qac6x@wXJ?m#}UEvQO7Lg)GhOX5aj;z z^oaIApfYrxCY{j2`bIjMKM!|xRasO|4RM)rbz2O-$DR(Cq0Hgidg`_b!7Wa}Zq ziDBXv;K^$d^>hj(+BZSoZA8t2VUOz8m{Uf1&WiY~#f76e(*fg46pEtfu?e;dyfkp# zJ>k83!WstFi!tr}au08{o;&6JB7+noQCO6D)^ZKNObmpz#QpeKo{zAA;97wXwz9P5 zIwyyI1|exfS+h4rZdRn@)y?PM7%k3TTO9D3%c<@!n{?vz1ekEVf`*+MRO_#_p`*da z*n`-=PhbKad@OL`I$p)xK$|<|Jsg}@nOhCV|FZedxhMTvQ-8Sc#8G^v=JT2*^Fl(8 zce5Ru+`Ii<;G;)W&t4Z(0E6CrMZpfW>&BA!@Q!%>zf88okdT;{YO{&{YI-u&+w;x+ zFZInXO(ndxm<`y!1(pYfwddJDWE$mHt>f&YLjfa3i3{Ef>1K@Bg`mSzSvE1-?y?xF zTT+V7?vWN0!8DY`Byt8EOjH$Zr29iZq{U2ck113#us@{u#7H&o@dN8pMM;;o+0*L? z0soVxp`h2I&}-CTqv-sbuIGm%gXiy_k=d&FTp4v$=d-Syht8#m^d23>0jWMjZFCz5 zI%lks)?IvER{9o@n3H<28wBULR=0;HTl!+_X7RXh`__-BdzYhz1BoEW0|oP{WtNjZoLovqqjSzO^gitXT zh%v4HjM*2bg)pl3M$hQ7LU@_mmgAlQM~Xa46)J`v8)ThI-jjS}HY|Kg^oA`roAb9! z{{D{(<{(b8!X6hYa%{F!Ee`2K|}pR5&K#I1YuHImhI z{P%+;0gHlxcZLn^WvYRo`xpE7-POyts4JNb8h4-dnt5l~7j6vv&-vE>yK40&i;Q~# zkH>vKt@1`!FXfIlsJOeWx>RtSLm~@&IDOKBEW2HV%Jg=vK=JQyM;B4g}m>$eU7L%9|!S&(Zq!#F?qDqztCu7J0gKa_niFX&hPA4_zu_{f{I8yhH{QB&b;GykJs*eS_hXW=@~C|rI^AL{T@YIC6%TZVf;HKI+~{8M(U zDX(F-LCghmLhhxn9&i1=-=vJ@YI1yKjjpJN!fwISVYzki~#N6!AMhaMN&Y5E&l ztN+E5>hBU1^sf%r-}TcfWjMlORJ&f zqQ7AAu|7{yJt=;#4-v2!Qg#N6z=s+;>w`#WKa$f5??)5Z*kkY@aabg-BC z_4$@}a`*6SQH7F!-Gcr{lymZIDXTpZE6di}v0Q1E{uN*?fN|v}WtdKx(*g2^^|cZg z<#2zU%5F37iITB``7hDJDa!5I6TZGqFL0sCPoF1SW7YvgxGFnZuz4S=Vn&9l(jGNS z8voeQRNOk2Y})#(#vct?UB;aX_-lT6l|UT9F817TRf51Mbk9k}BNuKP4Ih6)vBpH9 zr3Km?OdB%E0tpUjL9RiJ9Vwym1@E?@%P7IWR|LgT7TjGQk}i(m@(hk;T|6?IxIfg$ zzu{>^ecg5Ow>=F<|LT|aAF{0ckMz~Q&+hf_>YMccwtFN{SNCO-j>5jo0JoG4En-}9 zhkDW#VB7FJz0*&7#6Pq=W>Z~P!t(9yd*&~nXCyQYM>!lRDX{cjus@q+QV>Y)OAI=D z8cxS(67~p-X|s8L=Fgx6&ad-)7JQLU`VEP)V}9?NF7giw%6SQ8bV%qPEf_MO_TgAU zgKhCCk~8D8R11?r#3NFT)DoTJzk3zvPfI^cciK16V<0tg`r31yjFt#%>4N|00b5CT#07Rle0#jq z@ynZFPz|p{_)H`%>diZ0%W^z|&+i%AbCh9D7p`M%{8o0SYilao`*!|wj_8lC72#Iz zXTj%k2mf&XnMb>hq>6pFn8ET(E`QgHj!}? zSd4s2EJL6HQh5fx|W1FHF|vmxhLNg9MpOmPoxRtf#;0`alj10AjuHoiWc0LWE7{N-&yY?`;|UX zf8W}*nuPN+I&3f$q4%gMb!SCs!E|^?gh^0SJUU(CwESU9O>XADWx4;)H^Uo#E@dlc zXHFsfPm#H31hI}3FtL7wst>K&4puqVW(QHV>zaM-y42~(7w#VKq4WI03I|`F^~hQ~ zlI?82rn-nBmWw;G=mlaM5pv0L%PhH=jckM_;2 z4^?=h9J=ye8{E3KQT%))}fAYht&P zd65(y27iIOf#ujEHuaYIKx4dc=o+99jh((1Wr>9YLy13{w)t55c?YhfU+R6uU4ONM z>3{3|xiN`zcbE;S+a48a>#Hsu1OanNVa7Sfee9%oB+;0F8uDTsXmKFsWmFu#y&-G= z9fHkJ!Mh$(q_Xcu!s)!6qV1O38=oXy;=%YKOmo3zOWqkMg%^uc4)&_*SXK;EFuTh( z44fTKr%OzS*75C2hP(2lPVidK1zz9v{DbBp2qxS#fN}>(m!Q$S{se);gOIgTUt)6d z3KAZB%=45UFlkZI=TW?;SGUMKtdRSCW1(CHk+|}2uYd@m4v-GF=$B5;i}bj1Da<9~ zar3EQiw~4D4?l4Xq;`b#^3!4i7D{>PDMy~5Pk{WkY*Z2P57xAdgqp+{dme1|_4cC%aHW#fD$S476a~ik4o=$q=AjG| zMsh%obLXt1V(&qYU1BX#CNL-DJtK&S7+NwZ-*QvwE-KCA&AG4S$l9RPnfsXTQ4@tQNM-t}F_9u$uxX28FXW8OcOpU;tX{7$u zZ*&>eQu#Hs zDCC1rX5o|A__$MiJplm(x)X@KGxeX-`4YrQuOi~`3>>YG_xmYy7N=c=Zxo=>Y8hjE z{Uf85{v2B80#+_?Fi_oex)5a;U8+|?c@&J^HY{)~3uLy~u+rgOdAk_~QgfJ2IJA?t zsK=>XVCyAyVi@~6(265O7(R_&AP-SW=GOw!&Wxa}STt2z)&YSjvkyH;u=t9nd5-FU za+`qKYJjm!y>RU?_1+tu8%M0IK*ex_>S7s?1NL;x)HS4|_u)f2ur(jkS1@pVS_eiR zWgk)%IK#R17XP?CDsdNN|Da%yR-3iCd~3r>NANtIU6e}pMfPaP9f;BU8+f%Oa+DwfaI<^^5+oFxzM##{yR9xO6``WGRU7KltBnnGMo37u#81aLlqAIgPg#3!m0 zlvuEfOY1ZWIm$UyU^q}0df3ome0mx#?+3lypiAXsT#>J>$?&KusZ(&=FSWG1WW@Io zy+%}jytXo<4SZl!2>U=Wv&HL@HM6vE3Qz}P=ks`_n=5i_-a^rIKg962OhxGGhtbh} z5i#1C5B=gYCM(7q<+HZxNa^x-i>66W&6mmoDt$z+W;9y%aV^;N^$5s5(!m>{2nBSh zEBe@*xQ$tmuM=?h@%~+xE~)-L;nU;)Xmal6_;h}ZsNe9;!wq8Dz-;no1*$*t?SlpD zVOr2k#HngFY>$C>0aaP`kw1|=*uCF&^+RNMYiPXw%Ys5>C z`h7%dKT5)7PH2cW;eaBq4Z}GO${s|0Xer?zm|)UoNUEKxnKX-uNALEY!h3r`>0FZS zKxBSM{#0yRgO_7N!pd@z{K1Wl**=XUiH`^i`J^YM3~O|jFbfleo%qW84Yd0993a0| zO<>swFcX58;RHuWzl`7mIdJoBIL5iNG!-ap_#jEGm{N5k6t%C!b9`b41#t~!Uosz# zzg;(V1Y4C5wn9_!HTqoT|C<=!j+4YIha|Z(EU9i>0%?g;@N~(!fa*&Ts%h zP;amfE4kpF+w}Qf0Pa%3w!z5cy8XsDlqrR-Qgq+p@u#qhEuF1_VHe*w!m^whxwFTx zwYxD-Z*he;W@@)nWk|_b4rTXBzx+(_9=w(AZBUw2RhQK2!FU6iCd&tnPs>LNkAdKySLZi8ugEbS|*V6F8IHd`j(uqfhZ$-_l^Yya3 z=;!$A0#_p1T%)siDRtd*u|=Xdn1j90`gzwgTntk+U7#Dixx>pDoyzlC3EKI=(>SzF zit~==pei%U6*kQoJ~~p&@QIHj&t^gf46n{XC*po4%f2VNMpaW)#sYf zkcT&&wL_^z;Zm9o&!0<;sKYaX{e9ZGR!%@VP@Oq!E7zfNR+CLAVXu$8y;*E*GEsi# z&R#cIV)sE<)&`i?(>`gj`oMhQ_-5Lze<78&f#H$6d?f8#6ynu@)YhLc*bSV}TwZ3H zz#WJxgWle(1C~%z`wrEfN`7=H=9@-7KHm4!O|0(abFvFJ;eWJ*fOm$fFjF8`qqp2G zEA8{l$!Lk7FL$369&_WW4sFQDxV9J;FOfYj-(k=4DL*aFcGf1fpBHJ3`1%ycS9ynEA0DT4Wsie-?y;uqkeD?1%Rup7C0;z}k>r=ixTDnSL{p`*(EX^>jU)FBpR~g4md&jNS*N_6m ze718JQUPF_hcLD1YLZ@OnF-@kZh45vm}ZuJP^tG!XgQSSZRu#JnEurJZBRqbhO(w# zJ|ESQnp15D9tya{8jfp4Rb*8XufUkAm+a=O1g(^&eA{ag_T}?zZF7o=7W%W*^83k8 zmrZYXWNmtBwqpR^5V|ybC0xR_voyZC`&Rt=-}V%4f>mcsJ^HU5hlO9K&6bKZxl(DE z*?Tkfxk&P4Kl$koeLEpF{>?C^1SZ_Vg#)RSO$S1a04i7Uxhzb=3NYJKT#22L$15@O zr<~2x2=+xmDU=sw^E|I}Dj9>H+^V4nU(%9vLqlSC(LB|SNH>C!4q%=j7nz&@Hcp_D zE7~;7#-)+uP#Ct*ndzKPP)11wv7O=L__TwArWp15R_(GX+XoAm%=5e#MtM~A`kEm? zA7XrTs%w3t_=e4od>DU*)b6UvlKlY_s7Ui*kOqg%JI$dj>CIviW@<{Bx$aEN;)_aw zH3!#$0K_Nm_cv5S8_I&b9c6qHe{2#jWz9h*2u=kRR^HZJyUST|D>xCD_<6z=HizCN zdJT3<$4Tiwi(waS_|9`!jw3vA=4n+jCg7(Pv|1~4pAA5*b$0Dl3iAb4&|XpnKE#=u zc{M83@bIMp1*NghV zot!{1`$R8K1jTa5cFxIY!#ARBpRjT$Sx$5N37ZGlz&v$)ChH_okFz7U{9q`H^2_%q zX}EL{5{F5_E$(iyk9a(Vf7<;VmJ2WnD%D=DM0E;0wJ*3*6BS%1S7ryC|!NtEWC#~kCP3? zND<`;_7EKus23;=40on6wIVucTTI?VDGwL4)kjTzEjy>pS~)EidbJzNt-2_nEdTR; z63jz-4?Kt?wYUr(eFN8BuvwRPPFPb3%0Q>3gc&VJW}ikER+bjnoGC^eCP@i`N(Co5 zxYU(<5zaNEE$&RRBz<-v{Q|&B=Z;>UbbV0_U2_>(CRj4fr!)(+>vD9!*@@%4oQMTo z5QKzwgUAD!MOso|I>QOp;7rg)R>Mm%Keo4O^e~+6vGPe91XiG^sfVgw%hgXZX}w^$ zgns!UPMrDidf3G}Z%d7s$O+Qs`Lv7A8N9OaOJeQ#nOXOC+7%Kf!g(fte(z)dQ;0AfA_gk`A}EryXoavF#0B!o-Brp(~;4>`n{)Yqj>KA+d%b`Xi=s z09x!fqR4g~H8%cijVZqj6Pc1u&x~V%Wtu*p2p|@p(Q-rvFqb~(3?0IRB9+=%CeW$- zb4@hCZgC31NBF=gYwc_B>S%$TVB1G~;07z%M7s;hX0#ui*FEP6TT^9{5=45W_Fc5u zGO{>9gG=jP(_gwD2RdJ6_!~Kihpj_oP=GZV-xX5)*s+S%PV8-aN`C}R0QSZ;W^nLY zX`-)*aD5MbX!>r!r_UGfbE2rXiDJt$^0i<2%B1#K;%0(Vz%^UQ5?pdOw3i~-!!>$U zV@1tY?a53S^^$#^ZH)FP904A)ma|6s&PJ$E0DzN6S%YnVV{;bogNrnYV@ELpgGFNi zHVP0|OYR>v8d`ONYPcC6c{pJ~T@3LnK_0R*y6#xU*nN7UH7RAWmYnGHLF!UHC~2Wg zn5;@{3>06}{69&}{_W;RK#i16XL5#>)~Td-Z39v{c=l{n2R1o86LLgrLHeCpkMFRb zjiHbagWdNcrBqhk%`&4xw#{z%P?x7x)b^Gg2oq;zYLeOwN$09G?lOAY^LpZq1G4PA ztJXtVqKTJsO6v_}!&_{M4;_BBl;)fPzjHgmetSHjl|_Pdccg3{>F12Gm(x)DPhOCA z#MwI@y!lO|PD`DC_)?e?igI9&{kKB7Kq7#cyDW>{#==A+WA624vFVisgjnvnR}Q!S z)Ux((m%&3&1|vyeZKj*!o6QVd?SY)_;UND(pUdiuGR`jfr>fH z>TciaB89M7^dX88aqO&%=<7Dp#;KV2FxLcy+pit8I^vDUkdbl2mUSO_UT=!}tqD<= zXwjACkir2i&U(uMakxOG>V!X^HXeJ@zrb0bzpA^1{Q$2l(nXKJ$Q%fpa=B!EF5hte zpyNM|SQZsIhU(diZbj^o|q z0*8vpw^_wbX1%v=Zn-x&AYlw(OGNW%Pwkm@Mr7Ba{9?%SLGm?i3#;z>BX8gK^tMY} z4P3WI>_l)}`?c?<_0VcpE=MKIA_9lONihR?OjmUG)1{`}>YDjiUMNhTn~i8Q5u-72 zkgj$%kFMW|%cSn)ZkxPfI#rPLKz93!ol_rj05HSbdtZ)kJgO=9*40h-=z&rrRNx+U z^_1v2Rk|U?6d}2wjd_+C7&4=V&)|J}uS3p@HBvBW9=VWUFd=|x|C5;U?=Khd?|mYLUgZ;A+m(7W2f$a=y zodujkK`e&*aVdd+7T<*f7D_{YpL!^?PGKk!<*Kg5+mSh?y=j(2Jt&6z%jkZaF@3!Sr zPXl-GkGYMxe#+}fuAMq3-iF>tYDbDN&fH~Y(vmDcQZzH8@B?;HD`GbP-U+5NJr2pN zN)Q2_?EvcJnYybOWhjj@Gt}sKi2N=QBXV21ZJjqP(Q-@la81+w0hspPY%q~Cl)8MK! zJP3L+?;13%!dbzEJZgXJ{UYYfj-mi`ZgebRRYx836zs_r&9LKRyy<3P!?$HdJ`3K1 z(8d?dzNUcks9y>8oZ4UT+1*r=G2}|ha!U*%Z8yqOJC}KH9sTG)ZKe!_WmcxoULQi4 z76x68D$c3aZAUd&%Roz@V+*-7ASel&Se{tsofSSsVfniVC%9EfErtN%q3)R5ktruQ zF$f|h(R3A}`rzw7bVplGG0Q`>$2enDJztta5RWo_*Pt!K9lM77W~ANI znd6pp{7trP&OCr0k9 zQS2A25aizEA|=cB1Vgu@#ht6mE5+1TEynQO@VPuAVIj(viAQba`k&ye#@Egu@b0XP z+`yb_?_l&+4zC!v*m|TN@(ya+u3n)!7;;(rDa!J`pW}n}a)w`U^z2WQNCc!SL*7UW z1cL)C#(sky+*iaZO0qMamra zq!yb}uQ_e0A(SD@I~@0*wRyoHN;%&NChRVRe|!wCF16&&S>|06J|-Rzy~1!#;uMIl z0dQbO4U8hGy8u2wI$tG+r@d$#75K6dn*;MqM_U2Ov>L2RQpY~92c_2euP+XIFo$Iz z0`unM&{~`cMttn@;u|o8*VC9YOS()lFdE}k3Cl&sq6us*CO*=>7LzF2#+}X&oyAB( zavD`jM?O3o5Ns@3nAS;9myW}_WF8wPdx_efHjS8SUGP=^>YLMhayT9hy5w5AXdiI$ z28$bE zaf#8Uq)uO=ca@^R{>|xp$&Ym-Em6QfF6V^v_L_Xpvx)YI=boD4i+{Vj%>VP2?Xh5k zVi5ya7i@1)I`xY#sip7-Y_GLKe#nIdoY-2Inkd9tL3p(@vZfZCy6_|@73TcJi`3sr z6GEAwYO+wmtR4mqUiYe3RR$4b=V1UIxFi81jWxlAIq|!tL!$Ukex)6`NzyBns&K8E zN>>$*xC($WT6}mXYf5F8wpCq|7aYrFA3|&-s@ig|vR+C{ zlL3&rs$~~ZZ;Ig+#GT`rH4xFhdr|HYLFbE#g4{-jgZq^)?XG_*vG=iyRKdyj(RQK(&a(huevI8dL{C;>K!zb z-|h-r=Pf+kbFB6mjn-WE^l5F%XX9n0@#(tSx~qHd>Nhn#%i4cBac}Pn-S{H?Khdb5#Q z0!vO$CQ7dg;xm8av_sjmt@?h$xRw*Md)dBbY)?)M_fmo+eV(YTZ7^gMX6gu=&l#mL z7?HpDz5UKx_~0TH(~4=Ktq%Nvsl&`mS93*c2)6b5715U;uo)XcAZ(gEjpfgg(qX@m z6w$i~rjQjggse$$1Lu^hA`QIR>-mn3cJ11i@FoG^VVo z3)iVBz*oZ>NGhAly@O1x>=ws_ZYw6`P15Btb>sRtV;vEa47=Y*$|`XV@+JY zD@&@2UB4&TPj{5~B1)KB zWSlZM?+xS>OvDi(j2qeahEa zv$a>m{Quf`v5(qv5S>%Qf~OL7Al-J1yg-drrAE*nscqF@;Sx|7Rw!^bg2$VN1~Wc< zwI3GvKKwM6YYqa<#i0Q)da2llJ3duJZ8-aCEo$+%_{->jVRdQz|IV!i;d?<3G_da7 z<;+(u>;9c{?q6EO;UWx_GK)>{ljXuYF)3(c&gzvGS*DeRuXiWai0f1y^Z+9LI(&au zdd%bC+^4o70b)5v3hnZ2zlQC&%GkR7tF1Chs>P^4CwvA4_Dqt}+*&{~ z0Nz`PpL{xMf|SRTysNLB7_944J@o{H(;SYziCid;okEL-JVUFDN-|gs&(m24e8eOE zv5&j#x%zDic+m{=P=N`j0;{x)GBnSq5NY?ZWQ{RuzR->d58w3*U87V@zC-Y;wpRV9 zw$(3jUK)1Q*IaTmEK`^Tr@UZGPp#}gAU5K^18slvpX~p&fl_^>dXFi-E^$Qs7J2+D zTm7A4sVrx;Q)f2APOE2IJSKB_yn*)z^o9f26A2=1;15MDn{}3$VAxhn;3J%#<$QQK z<1)HLsWP?9KS|4)V;FrK3~5|il5H*WbqJ59OhSzP8Q42`5V4;~>aCo|lQztWDNCo(rDdi! zWgFwm+RLFJi7XB2iF}R3f+6>Wc=Q!aL(fwDdJ;1RPeXj;kp&mxb%8ytP*{~I7(;H! z<8?@IIBtkg5XP$FcQ5D6Oy@RMBN2W z#F?ToYpK8f&BVX{H`@MO5-%6f!@&QH0W>apFP?o8{J0WjxTJfcmGhx4{P*1fBPPHk z(tWT>+S4KE_Zm=NTwM39X8XJfYs0y6Ra%FxOcmK^EMCwz4%a$t0-?4AULo(dTARM}viE188<<{R@MeZ|CLby!z7X%SxU{ z+oA84wMUmuPV|O{hKCx}^>rSPj~(m6F)*yL9xVKmND+F$3KZ!>0PwDz&04agi_C|2 z6Ko%P;j?X24T~4{c+6iKQ{m1qY-3_^S}zO#@S67X#(gm^&9H_8Azq?LNTJQuLUh^zuOWaTXV43rov5Tym?by{8}xl-T^ zlE{(wFh@sGfa2*uY$BGk@)sODN=K1Pq`D}3#d+@gJCnhe6MCB`r>7hYq)NbCCK5+! zD_(*VKVT$)gYkvMkm;EWe?Xo#1g?L1WI9e`o~ST_-VLpKKxD4^!m)ydK5jr}6j%O@ z!11wZXU*~m?z%!upM2`R+OvDDweJH%DlsAD2W+kmDg~VZ{{d65){bC0GqTyaR|r_H z21_bIq_be*o-Q(;zidX~8g@BEMMYIY-K%u3kicmT(c2NE-m_;}!}KOpdU2roMQ6Et zMM1AF0(4=Z+)LOB=%p&guqX`+BD|cPG$;>-VNz)!&TB?Q(B?MqP^>@@+eus#QZS$q zRiF_->X7nt1QvK89Q0s}MH6hofob@^U+F6%m0VlejZA0QC7B>oMP?&{@Q09Hw@3@R z#Vj|vz*>4R*b>3q(TtPB=kzarnRq&HVS}C4u=|}`_AHJ|+XDNB_?HHe&-d0Qs|$V( zv=pFe53JWu!G!iR^1CdI?-$Mk87m?0QrX4P+-vq+xhf`q?8>xxWZKDr&ym98BeWdd zOLZ;Rd&9mm`aXC~_RGX0RQqO~lXAmWRng*{;tyqdBkoV3R9^QyziVjvkd}W_Znt~G z38>P$*e=q$bkysE$t8~x>%N=tT9h6?m^ea}0fc2{CR`B8oeyLjQeb@IETDIc5}adj zp_)O;W^{KhfaX;=N+{TBy4YF?$|M5I_Ka{G&8&N`{=Q*Vq%r0*T&dA3>Y z7R`|BUX$KEgW5Z-wCg>5p5XFXDZ~TWTPn&DR|7-z#R76X>Q zDsl^HHsA;B%+Hst)L)kW`=8GSvH%94-AVBxu>O5o&VXq_7AAm~1_$wT{pW(m1wrg5 zg>nu(w7Qv|nKW&=F)D%pAe(XQWpRAT^H0-TIk~B`4ZyPZ>?_C39qpu2U%Fo1OS^EK z3^yiq`XtvD6&sMcQ(ioTj;+sK+6#_scv3rf%axWx0Uboe!N`6&d;tBj=A|aTw8A+H z(?2c3ZaoaLh@-Sz;#pkEFZE))^%(bl;O)hjuuaXIfH1-T?UVyiq?UyRbmOhLLP)8C~?*|YRl6x)Bzl8LORsEbJT3CUdiij z?bN02moH`A9h;Tj&ZJqM2$#sjNgo#b#3OTDFpQPS9wowWT)cg8hI!vmeP{HhSE(;g z?vc3F-o8=@U&v=h2}g@KAKRL4uMADi%=^g$XTL{&$M_$bsnns+FyqSe`+M%9K7XOM zm99 zIb86+O)z2(KG~gwSGR32tlRWVU-$Q{{TG!|VRJW*-`rRF3VuN6m>7Ddxp4gkeasi8 zaoqKfKyD`bLkyW6{kqR0Y;wy-V4d?kKv`@0_dG4nJU>F5<-YM;STh{-UW1KVa-gu<)M-lfJT}f575vNL*zxjfr42wVFol z?rGOgqIMH8Om>-ej=7x{X%KwN*pXu1iw$f_anJB`aJTdi@rZZ9x|Dl8Lg+6ylOSCH z`E#;E2JLG%wpZv2v**P*hzOrC9BmwEtAY^d%S3U;nB`YA@Iu|rM;HHqp`#HH-2CT@ za(!I(&!$_F`P{$!mJ*V|W`=B;DUkYyM?v=zFMIjKp;AcDbl^JY8qo0f5uo8;N#JFi zxtNzE_&x~&NGUXE3Wix+%LPA4v#1$xD_y=GXCVMHya)nJ+!oL&{f|iffBb+!aO6MS z8HoEtgi6p(tjN?F&PRit0~%~YW>G&Is>X9*54|Rpj)O=TJEm|Wy7w<#+9MKo{Q1&f zhk1&XtB(+(`+r`n4|c46E&26seGG3IJchanjI#cLotY})1kN1seN()Sx5MP0UOoXg z60V*Y9(%`%H`1d%6ekt>YX2$B3A6ZSxt}KtTvwJV$U^rb^>4lJEr6HigaeZ$A=#z< z2khXVd|^Qt<_qHcYT*Xri`Xn;55|fV{+GwtXj^~(n&`@bRldn2=^f_lvbB7g!>d0% z`wH04vm1mpg&Pz8zki?*m$jlP%pmc(NE|=FT8UDBKM`@}nbiT6Va+(wCCnyR(xUsg z{-V1YTX*q`2=V20{B{*aB79BaC2Qum7;V5f(}~z?u66m|pRvSRG4GeONz$NRfB1XHiHTlTyk64Mywk+a z?VpAYI9aUyO3JO8g*~yov^q-R+1tcaKe5d?mi4ss;1k7t?N(B3Ys8dPhaY+~VLxn- zcw2!Izb#VKS-rZ7U#}KyLPis`5 z&vM-3hkZ*51Xz&Eq21XPZ{r${HP(#mW_)#SDwy>1@MX*}z9)uQmdCu&bAd|@0R<** zJo^v?mVni#87aXo+Qv|nYB*j>y*`vQ47v(C^*3Xo$+d6J(X~j zU=#XFdo=EGPgE$*8E9k~)5EP=!axm1%X*cUxdsX962`n(x`y{ElB$8W`29<-aH0 zOS-l`MOnNS>fvt#vJM16;gP@sD&qvSiF7&ChhjO?6Gurh^Ysx+1`SQ-sVLp>LVP)$ zk=psC%@he=xD2R>;~$^Zo9|$J0IZZRn0N%o5%ad0ccH0yM5HX(GIVwfNm1!0$wMD~ zxk+82mkdokb-hFNT_G|HuIj+-z0?p$`Itl}jVoa7Hsyb7zM13#_vZ90UgICYTe5JS z%Qv(&Ax~yLG8v&d%lSha^`;6_S4Y9PXs;hKHbF{*VSxg?-r!n{X5ZHgeXiU(;?HqQ zXAZIq6Ej`78%MqwoNacI>gR7IzE;JkE>cmx1VhfN86|M6f{_#5ny97*EBguRYw!D$ z-#x*uvnzv(**~&>JUzV+pSM6aM;r2GdW%V6qzi|Qj!5+tn1bBGQBpgGxQ%c!pS7Aw z6!&ysrL}@!!kfr@8r>v?mc1N+6dIv~h2o5izs)52sdK|_b5>mgKT~v@T2cfiIcrNJ z4G~b5)|tw4%3>>}bi_EE7YyyET4Iwh8w7^;^*gJQ!M3!B1%2K|X-6?<3W&g%TbgQ{2aHyhu*}i>%ut+D zb#<(Pf3|b=h|wZ4^qQydguVav`XSim7|4=CNipIqwAqQ?&B%dh%pWgd-}kX+1d0nh zWnl@y^&!5Ojcj`xwJaZ4fJo|C3++jyZXXG$mL27=Wy$~EDIf}PyutC7;pQZgLvY+$gk8-L2nVgrYhHr>7@7%f5UDG(cTZ0 z#uPvK{lkJoHmfw15ZL6)N8FsZICm*}X=6xqBVH{l-YS<>wHV7kAP60(CCdtIfm}=I zaAZK>`T*bSn0C;Dd?k#{g(qEzS;;BVV_S)GpK} zn!>c>_`j0cEolBT4C0I(HVq?X0=5TubVWd{lc zQISUJ1OibA2@sl6N&!P7iIT1qX(D?ogk7fbTXo)X?-*y?`;PJ5_s1RI_a277)FJM@ z_F8kz`OIfNPrXv8^u_-9;F2MZ3{8~@98u4l7@Qk`9lO=~a z-BL)EABnASsBkqWN29MzrVel5$C%WYQX|#Gs+TE(V>Pk&if6b{R5ujyHo!whzQu25>(;{!15MQa;Z&EFD zSaDRSu~z7XpQ&7(r`rUn8n(v&gIOGMbXb(u8MVU{Spgm_hi6M|ms6Nr2dG+*Ik*lH zl!S(mr9^1UE4T|rD9w1O-uOWmW)zmHgP1ZXss zOU&(q_)~ihKPdq1#C`rmAnhuPj9k0j6tb#gJcx?{Oq*GB3CUp#H4*6a%w#{b{ z52r;P3A0`CtPb9rPa*|};}Qy~RbXP`8FZ1Uir%)O2C9gE(4}!WW13@Q`yp>vqwOR5 z0@{{wDRzcJ(!{gDtJ5)WV)3s0v*QDnEtqO%D_T?}3r+#_dG9txHRFbEExt`MP$FMl zK$4~tjzNPgc=NJLAa{!uWnK%vguTJe-7c$0A!jo5->=U2Zakh?lbXdk!R~$NvKbY5 z0$^YJF^JtHvvn5oB3O<8tkSL24cM-90V+9iQzQs*;O2U*YPoucIL9NEFFPq9&l7sC zv|31CXlq-0QzIsCSe*KDslgvaz`%Zo72pxlxjj!v-TL}-1UC1-lX6ewP5!_Fy3Um|c9-ElR zGwot4&v!Qa`lOM|X&w$wgkxprlJ?cS?K@sqoA9Xl75ca0xf>0*VHjv16S3>7fPIN+ zzDbRqcCf2R2Co#Y;-u?VouX~c@uOh>Xt*ug!$~`fQ2u=Op#Qf$NFK`0q9LSjFw>&ovhJws1g8xm^m(*i0I*3I`C684yxMji{n^VqhjiL zwU3Z2QbpE7Un(PFWDP!3q>@nQl6lKF&SRysDv4tp^=|6wp+<~3-Gu6Vx@%S5_Kv8x z?7wI><-<|1{o^Q+a|(AcK8brg|Mc}M%kEB;h5Zh$1BU|Xb9VN=Mf#mMP*XN-Tfc1AP#B` zRVCaWJ3-$u+e5h@&?EnX(Czm$7zH+wx3*53i*u!|Cm&)Y;w@YaWDMhxtEbmKEnumV z5_D@cTY8lFP*$rXDeK!wFfb@1m=$nqZ?C@{lHGQ5Ro?^34qRjn0zTfX9o?;&v2{Qd z>UOIYxuMSQr6Si|+SyJqCPh6mH4lD{kP4~H!(D?{^s5OfB4)t1O+2gNY0?=K{va0* zWi^|IT-{Ay4h0MRSf+({3k&(-4-xDA!Uu$RJ)ik zOG&D?Ud-Cd2q8a)psgXwF`wTYr=qK%p7l%z!Wt6d8wVTEQGDzetqHPCvTCQCa zZ+>lEb=O!8wOkYQ)SVnv>_1ZNaYfFs3P9ppt?Fay4|8v=tw}$xqn^D>4!TR0B|4&t zpc2&%ZH{hkh-fNFw***c4BmW9&1!R*V%DURPmbU=XHpg-_e3^fKq|JaE-9IEx!yYd z99b1(aNv1Wmt(iJ@s@+^`G2fLH33HiH2u{Nlo5>qd&;A(>CjZ72h42qKhWWW#226D zRm-hy_I`gk`4jEK0zsZ#Zv@MTx_tY~NxzcZ6XM1?Orp{$r*rw#srbX(>Z-hVdN^lY z3$dzSX(?MErKAGly2ha*Wd9|Vc>m=!5okSxd5~xLF|}+(8*U~ano40m`h4lqY*wkC zI6!%w=>E&I-B0yi>N;7_A;LSrzSi|U2cjmF-8Fp?RY`|od|Cw7OydO~6z^_&i#Db0 z>(lr=3EeuiH1dq%4bi1<>Hv&M$VipDp$}i1 zT7NY$_31m}`pxhCV)DoOoy`vDeX65q7I0Ksg*g3+v3LAgm)!_5$IStqfA8T_Fyn@+ zcW`)g@!&{$R4BZ~7d9ViHL|bwOI7E@xO^3~MP^+MxHGg@c+tTTG+t0&i2y!sS_*KF zygW3N_e842NL%>T=}82Aac@!m0CpnHAauM##9O9h1IFGoNGYK-w*gunB6k-2_iHC-qM}e|GaEa;p>QJ-Ipr zma|X5f>4X1VlkntDR}0I$hzMwZnj^HwN*-gpx&uf7a+8t6FDAWhS)>>d!cp1K2~;0MqG z){GkLK!pdg<)I(Vrgx$te1Fe`WiQu1T)zExSC8V;Bfi{Dc-?4=H_gj`S9D2{Y1mCF z&&`{_NfEVsHB<}7#>&Wz+r^+{vs3-jhqJ`QyRCEEdW zDE^ReCT~T<^XITz+mkbywfz>jWjUu9X1 zo5a_*pqLLdIhAKI6ytw`|4&GdL>&vC{dILK6JF7(TibnkH2G0p$fMpsAs9hEYB&@- z;;`_|WBu#er~DxQU{$jAF#tR%^Fr}xnzK|gkOYP`D)1o{X}C?ovrq*1%fE>?lU9Ug zX588b0{~bvbQ@1Be9==QG1u(2;w8H-F8RDM)HjA#OxwA{=&auN)qDe;`8-DJb7)gL z0eL(zFT9g5ra3b;`2g*nvgSd`wxt={0uvom7MA_nvL!-f97WJ zafbz}vE3K-Pj?7?)a6D0V^DT>)fd%NE6U}6Q3>5>uruXfBw7}POkjTfuZbW3*C!07 zl}rES8%!_c|FTb~cgXY(nLZZN$Kt=xMw#9=)7xfx+x(AAaC#-CS7Mq6Fr7|Lr<2op z!T+7SKz}Hly!#;I-QCioPYIkmvW0V)^igyKcK%$KBcxDgDz5rQpj> zAS-mSN}%!JAN2#3$wo1n%ODS}9zgzP*Ny)`IsDBwPwd=@T>^SEi%w^c^&P9Zn|+)2Y*R zLOGpgPZuB4CE0X!I9)SOBMH;^%Ks-(Cu1A?#sKqf%EKPEa-(=qd?jyp+Yi+7=U+9S zf9BjtF0c5q>}=QT6XZJOJuqwGTjoHZi)QgX^Bino9SpX9c@6g z(YHJaWVE<$D!ft|wHL_!+o_$BRJ@X)!kD@tFwC>73bEDO3y*-U}LZ=YF?N+_AOz zf1aLsZuTua+x`m$JrfS$9)0ZJSLGR{d+zTUtFbn^LO$%);_WZ;a^U{bIQOs0#m;Su zwj?an>uds(mbpE!*bj`m$KrniYHb@bAHsI6tR*_MW{x%qw~-d1eaJJVoq_uW zIrs$J3^?YuS{G)#W)@I*IXi+e=SCKKngw66xaIUt`~s|^0k+9XDt}y6%WM&C zcmNdLC=vdvI}Z0;{($$5W*LVb9gec%#bdJ~g3CiW-m$bKpg_|UQO;XQtyW|K-IrJf zc=a{{6T`+fW72RgNO&+*)R?!fnq=(JG&rMYZz==!YY%YcLbR&{ftSIteza<9YQf7Q zr2Omnk^M_=jm%iFIW{H&3_u~^i62lsRZ_4Llz1K%aZ^wR7^=sJ-Jb!pJ=#3nYGQk| zd^;BXVSg|QbA#=_lg&g2jMRB$J}e#GZuLf0^ zg~L{aq%Q@~Wa7<7qc}@AA+e+))SJo@)JC=Ff3Kdd^Zw`E@o&n5bp0lmw2aTCEkyib zOQ2<$G0v#wT0;CL+cof13dJWh)7Yrl*WpwBlY1*7cRF>PdiO_d*SNRir)^oEF73d) z^w7))hDRC;Y#Rg3bD)b^)yE}cZnEe2ixnw!JEU6P0gMoTqGJa&J9`u3<$TM}*$xGd z>1I&o!^Z>EEqfd4;Ehn4QOqyGP~W&gzhp;o>Ks%3&lSirivrjlh!+$w$b4iKr~P-0 zf>0Gl z#X1A8pHh_+w?0v#h8WW8m?iYti2dJcfN_|W zR}|PeRFd4X<-`1u_I)pUa4#uOB*+%uzE!u6S0@Hty-6(;Q5{y*#;K?%HxFrhI&BlI z(3xxj)`j{iS}&V1A2E_SkI`I>;m$Um<*5kbyixiltHPw8vzJrj-fjV!+FLodsT9Iq zHoqZL$u%rH)qc@(FSqWx{vROtU+3HK<|5lwHQ*_q(N@4w>8@L3loa0I4;d_%pvB1T zQ|!0p+&~%H1PK1!fArzq=PBQ7HMPAJTud2hzUNclJ)0#f1J=}L8?7amjbB`fnqbD| zIYSk|9(voTyq(DiR{HIO?PBQ*>Fx88EsCUc%{rhbL5^*P^i5|NEOi1ZDXo;mL4zzWBni&)?p*;hGq?`2prX*Ph~n_t;z8r^6O|-?x8_XG z`h<+l`g*sDmSS8rN0C+;7FjFNSQ@EZx`7){%z1pWWG4Ph*%m+WgZ$)g?qp5@`A5qZ z&!_41a2d-?Jm|(uo)ByOb|5h_H|L}5dj+Z|;pJi3{$NaYJ62Uoy^>worLR@?Xy`eaox(M?w+NwodJ zreSHo5g-B2E$zLe*9GQWU!$v|H+{Lh-H+sH;SsO zRxhEyahX#7Bx8wzzEmVbR^Yl!X3v}vf?u#67*gb}3!$xz2$b7w_F8ciD!eZz5%j4k zo6gB|&u;tTx?h$a@Wt|0b4c+1%l>9;DH9dmnnxer-`IgSWCRkBRp@KFZ9oTO)+}gB`Imab zV8G{qwc6(z2J9idJC(K)Hb`(9=DL-SSUr0IShWjeyxr|o&{H)d=C{tJ8y4q@m8+t#~pG@)dgNssWd*s`9_c*#)5-Ov; z@ILIC_?PNEX^~Okr#rV9G=r_t#OFi%-q~fy@dMaTX&X;U6nrJtp`NmCe|8@st%CfI zy{!X70=ukl7sL%!df%PEWBkEDG0rgzUQ4k9Lo$3EZvpktr%%>m<(6hE2Oeu{Ma-+84k zaKHoJAOW|4$|oX*Q2$P(0S+hBJfqB}xqz&h%r$(7WPVYc6qZh|aY9=R`hD>I{OiDH zAD8mt4XYCgY_A{-))KPA$QgZT3RoO09M{dg3lZfNjfA*CJVV=j@Lz)LghUbo(D`1IG&we2@I?LhYs z2JGY&$|l&z8!qE0W7G~*ebr?lTkJ5OI733US6sXaU($GAxwN6!N$tPaX5FiIA^Qvb znhIW%R|#$xTaP9r?5nyLi{^a(I~T%vX|wsH@fmcXZi}{%yFfZ_f|Ts)VVvts7qvI? z7rm$6bqrC~jGKkjzPxm)1c|uZ;CJ+e)%t0~y(|{E(rrjHt83Yp zp88V@^y<46UFE0sNB*hVFawB~0bB{Fh^OEKF$2IdK(a_<1GVo%YUDQ2@~K#z#qi+5 zKH8peS#;EMxT*JS+=yF%2Z0~(}=S*PrYx)C4Mz*y1 zZoGA=VD!6>hee_@2|cB<4!Erv14@mi$>g&f62%7KQack0&CE^9#HnoCWsFiA%yujeYs!R z7D7*+YQEm&9@IiT$XOY#J{R@_RZVCozKfFTa;5(G)<}L$XB#<47VxBeki>C0-X7<` zZou#DnOzweXp$3S!f^$K>(O204Z*^`Wma|XbN{%bH}x7tE0QWbRQxPeInn@3n*IlL-O0<+^-$?$1JETV??ES>BhJ)y7sv{qVvQRZZtE&TkVplh1U9 z+a(7*K$oo1e~sHhT?a=Lt2#8UGZPaEjJ?T+F~)Ju79 zFZp^*0uU}d`UCaXex}CEK-XcX-1!6b6sVu(qQIZV4bpq@P*LgMGF?J%q(e>_kjTcB zL9l(Bi%(lcx-IIhE1`tu1ywY$60(C6BgPj4aih+7Hq(^K^y+sdMgY;Somt**9liFB zhzWT^O0&X@@9Y#kU<9NOq!l#_;#KxArisENLY@Q>TJZ#7=F<*Bhtgrbv?$pTEowgv z;oBwgxD_w*gzf#jb@2*poP!2Wmgg>ScJ5<0xD$FEJ5tvk{WP^tm~*Q3tqMg4Px&9g!EOe@S!C2-eF=T@b5{LQ!qs%{exlE!?YsF%7`Wxmv-f@7j<-&gqU}A*X!nBF>3w5p7TD(szl%Wx3Ys ztNkbKuToIB5@t!YL?t_Kk; z#v%Hv@3m!&;*sox4%$UatHiS6(_wW9FH==FkeYe;5MKTH=Q(4lm&T8AL7OrL2NyMM z|7C}(SZ8AN19jUG0m)5pg&N%a!$U0#_0&Z>Fn_dB-FzPzO@Fd>z$C8`v(kemxSmR_fC@Snte{(x=D^8$?CVh zNFU1FKgZx1qv;@Cnj0`ndy{{Tn9S!en=t7ZcE)Y>Ioj+xh|;oO=Q;|ImveFlg4}Hq zpw2Xh2h>-R_B`XB2xn-?piQ4+1L;IVmcYdz>9U(?uzLB(n<>Gq_n(EaF+gr@mO+** zs+BU3B{cvxM4=3^_c3j{ZYDKJXGUD4In$*vdx}rwdcvP=#YwqK27H0@*r`mfL#`olu`moiAG z;ADWP$5h=yoaLXvF59oOqyl+kcCHi6T9Iz)jVNW&YYN~)=@t8n!+fd{qA#EOEl5bV zR@-~>8Y=r5aliNS^xo6^@Q^P>Tq5PP5N{C8*u(*OyDCPTQqA$l$kx6XcfbD056;b&x+V26NKs@hy_4J1H@_hnb)l^gJGBMw zK3EnD?PG@Y{t-=#_ThPLtm`U>*+gW&XUrti?WjrndpB_R%WpXH4R%5zg?u(MI#5AD zPHY}=QPsbbuYr3kDF1w1mYD9-p51f%5dQNUhu=P|?9*Mis5gO$<4coqMzBF+E>@1? ztKD_oFkJ!!k=>HgE&>Oz5=I&bpQpQd_9Uz2VcmYdNLYt25q+A5>!$6wM4A7&S??)v zIFfA6Ybf$`;hw?NvQQKFRNKYKPtdqPV&fVNlF($9m$Ho_*k z7i+WVt2y08a~wy@{;@kd^9hM;Tz1{6p!LraTQmEfEZm|0)l)YYyr>A!f1PrkADWrveB*KE^BUn` z_^kYAzpng&I(O2mZ{hEf^?@kd46t-(bpl&MZ9Q+kPUtI99#M>gGhvFeLI^66Hea(A zs+Vm@fc@GA=R)*^h}kb5j(qQA0?pAGqjYQ7GS$^9=1O#7Xq^owxrQV`BjFy<2fpe= zy49$tbc5bF=2>llf`QU31OHL0u2nSEf?W*mY`d{*6`Fkj?#vBu7uB>UbB{j)exlc) z_%@f?1Zi{wT~3%#6OG*;d8}e@@)Nm-UMdNQ$rJUxiT1NzijL)6_K*syv9 zqiGcY_X#&{YZkIRkX7ZQzKh3$WKOxr5WkDSPpc@*iSKHH;A$Bqb(}g(ZEyJXUw%%6< z*o}QC9<>CGQkJxwMOOVKQlF~HBU*)h4^El9^kk5>AKol!1u>#b51##E{^%CB-wmw6 zS5rY)%>thQ?PKm@*h6QSu0D^XHf@cxwT0K?t?)lHOsSpntmO5&O{csbJ2e!(xFSU} z1D038ZxYI>mdEnOeH&nA;`+(@H57X1nd(y^oa~0oXL?$T>4f{gtt6%1U;9BMdyTi^ zZPdMIK%Uq%h6&Azw+x9;J8KRi<8pM`;8NUjsQgzNCLa+t4H^nvovC$)UX%^jNsmqjfx^j?#$EkW{alN?NXc!U(FkkwrAu znIep~riT!r#ozhVvzl)DG7X4OB?~jFL)_c0n%9)oWRzmdr2CatujHN!8?01`dY@bj z+VO}z3-s)4G&rcNXe>}lct>co@=0^ldMFH9u_;6wo-MsAyEB=#;!L|b7_>Mv7^%(H z_Ob6@O3POXHAML~*4~p2pRmSvU=K=hY&2Tw4z89poTl;gs|HMbFh7ny?{8Pa^ZwqA zC65rXl*~!ftbmFX#CX@3bH!W z3syBR0S*T;{8iwxzoGl76;|v(1X6|(2{Wt4hUEF8u5SXEJZrG9RYe*%unO53ItNnh zA>hX`j?E4Nhxj^`cWWm}nsS zI^p8eOtC?TM{bX~(D~uTRG%@?r<$U7O89PVY_KIhj5B{g;MQ^mvy;)ZhBu2w(1M#@ z%EDCpG70pcRu)4e?xv|HdR4>W`D)B(pN$As)C!a-s^ch}xJh-QDe+>DT z9S$LXvsH4zeVoG@=#=xWsn;RyO(!HK6t0tkkF1%U4xj(l>T{LfT;f05f6Ga@6Z9|k zJQg_e7r5?}BIQng#!>z+Kwso~P;brRi2axOXi*dSe50)dw3gMr{-+pC%fWVdUg0oQ z^ZXV*os)MAzV}W{)OF)6#xHCLdP!DIiD)WLUsc+b%>GTd?%xg@5Wo}VYjbsO^tb#f z%5_&8^-nZs3b-uITxa{@ck7m`CrpvLIQJqZ}d7)ct?u!{; zKdH5LuWN-BGdDkqy~0f9hhY$h&KBe4Q_XxdSjH^ITt@Kt{L!t#VHMDmU#kO~z>v3& z>fLN<`48^K(I~nR!U!rt;!lu&y7zw1ycLIUl+WU`3c|KFM@ON)=j#ls)pJklTJVON za}#E~sTO}KeBx%gsRZ&QX z+LJa5*(B|Zvz-UNlA>kMLR*g0r+N0X`M@pLPIfy;$}|XbdCyzfm-(&D>dUo2s_1f5 z?H_gicYE8)s6V&fO;fMh6nmATF?W};S~^9b?$)XgYD|%zWR-GY8Ok!%m=}iHE`$^$ zPzCgR*K^>k#0bylZz|;J-g~+(aC0{|t3Kljo}SvdEY`17e&wMD3L&Z5v^Vi#OvDQ> zy)UUDG-2WfO|*|_p=wL&_R|oj1w9bo27D2mq$K}y8b3&}4;p|C;xyj!HD5H=fpTD9 zl4*HVJmUTSgEjeRNAuOpo0Ky5!b53#LqM>Z2NH*-0|5FICH?)d?zH{dd#>BnE}9kE zTz*I}Y+DTh`%LF+xaG8+LN@u3Xm&piOZ|cJtLoLb$y$UmPWNShbd$t{W=WQ_EKczX z0@f2(s zH^vq-%!ZY+Q8)Tft8b|A&$uDWy4v`n;ipk`~NYMWx@xBcWGDcH0DF91a0vo zVOA>{vTtWpVFk>@01H?Oda32sC*ZaOxz^}-?_~nAS6MT_^*`^hetqx@fA7PPwvhSL zo(%Ef?DHqz>*Gmn*J`7)(E3=yzxQ!u7muA-oMN z!CKkPa!y*G6V&@ylrmaPJ&!i=tRDN7w7~zK?2i5?)_{-BumJ|T^3R-=18N(ckd9%= ze06~1QDdjHQQ+r}WLj0k(I~C~^WlsVnM0JUsAXTN#!YTRIk>u`B@a{6o6{_6%g-OZ z{#hAZyeB{B`Ndd+O)_E%A3BZJ(^%DL?>LUX%a@hc!^Gx6(I!+H z4EL&S3#p*#+^j$Pqc(L!Y&7`D*O;eDSs+hmfrlmVGl*4FjaVck-9zPz$mHWU1~);@ z8V5oW!_aszH$0#Ei|_#3b~Tdl)K@If=3ffFg2^oy#w~qbqsE;RGILSC>PHLkwLTj2 z{G+gKd?Avfn}#y2RHS28V}qpah1AvM0Q`j^!HMpq2`2^g_}*aYaDcP z0Xwlga&-Fer-paOJN+pDAv??hRuR z_^FIIye(}NT-_8ZrI=BLs#n^FxOLR1gI>2r#-MGKpv_C+6Ocnz=|{i00N_tcm`}8l0WfK1ENQzc}weA z2q7?43bKr)V@sdGt3LE6#3AuVg=72RGJfKp_z-8$#g&PE1pqv6#y|&%H|R^jQ=X&$ z9$|MO`5=qCIj=8}C--4k8+%o6X2+0Bo)u=6CIdne1oEp>`V2Io- z@(K);TVL;qs3-Y}#r_8-Bm91bXUCVs#uUjbk{QtPbWhb~?Qe7}f|lY1<7j%9ty%9; zv8qt}tA?UrBrWfk58nKEa(Jp*gF$*9BK56#iy&NqQ;(%pXF`9g)w`5I$*Ii#meAt& z2>ne*>r#xvPW3i=4<2~S_N&+GdRXTCv;4WbCJ}zDrVL@V1+0Nv+gpJL*L>YJ+U17c z%l90W){Qg1$rkQ?g*F(@stugn3s0&ZI=o3QAzebQ_WdrwtL_<0{D;K&e=p4Y--Lz! zfB2dPmawI4C{E`uCx^XMz6^o~}#K0Kb}#4tqa1y`AQwO9MDl@E9ZJ~`RpP}(;Y z`PzZq`Dehp_kLj(&NJ-mjp|9oXYcR8FE0hi3s77e(`*B|PNx!_omqx2wD)reR@=1q z3bgsx8FPIE4`Nt4)1SBUOgZo|h6%qq5}?k|4R`q>!8(VQ>^ryFuQwWu776%C0do*f zDQm9A86nHkF->{;(B5l>)S%|PMO~$DJH5IuyDeWZD?OoV?fULk+f$G4KYjts%H>~1 zqEk!m7o0Ka15N#+;!_}RKN;{&`}AwOvNq}j@N1u<^#1Z7w?`^4V-ALS&OyY_cpUj|I5?qfu3oO$u!60Kj)bI zyR%TIPsjA>m_8ly-oCTx) z0Ut{zN?1#%oLx`>uP9>ibx(59>vH0$RUcb+$>&4j`-@#abH?T`TWXV@_%QJ4fOy2k zUs+gC^r3B44e!~D#IJ8YE#Eg^{9erc_4VSVv2gv`rD^aEi+{3Z=b~VK28NAkq6}0t zTS!dlt{P8>(ah5SFj_}RDC2r5+ydNI9C{9~t~yV)_uyPv!N7fzi#m_;a{_;$b_pF{ zyC17F8_u+x%8a#PWdMJ0jEt2K0g$2HFe5=@B=w)$udMrlN_P#E8`}v2EV@eX-`ZB; zM2_~YuXzdy{O?;@@i`Nm0&e8zPjL;7+{_kXaQX{Zb9<#CcF(YGUVH%v!Lw- z6H2LGy>x3aU}9Y8qbyg)a1xfs_^3}rYdr=1-}{o};ee`6YR-Nd8;w_D!4v!RYG$e3 zMK1H{TM7M=)vkY#0neXYB z`L>|CraHx19DT0$Q(qAGtpmy}UWEqFmO;g<-uCd;X*R>?=5cHK8w|U@F*m^2Sw22C z4!fK@598v4VpKteNQvNk%U0hDxHVAjH~&2sv$I35`hRHnqm~d=*i=ZO+w@HSitg;3 z1DY3CUA^E$!VMf+o5Pppfi5Q_1e*qyL$`)1Zo(}?Vx$BMKYkJ$KLObrUVl58ej=2+qV%+XCuOGSQa$hw)fxG#gXq1w8QT0Gs6YUs z0sG#zikZ|P;7pC7FQVS|goCg1>>17YN4mFlyt=#@y)~V&p827DDsRK}6$LM#f{*x5QR)mh%ePBR@pz@t%G)k8Sj~}am@$J6m zgB3D@Y10)&GS^Q25l+knjB&5bsl(llhUE(382i`i&%CwIh1l|P_Aqu?&kh{;WbyZS zjCIZ>uGi}Pa{9a zILU$T1zUrs*ix{S6M0faQo3T*s1CGU8m&gf1L*41sjD$C{L z-OMCyepzTNV9JS!(9y;GbCMK{2|kz@&#(4rC5nbr_mGDVz2qMj$btp;rO=y%N7P+L zWxG1nj5dZ@jlcbgZVleNN3^w8l{s2Cf;KK^hDVj*(kamoUzWsPVpW26(H?#XLA0WU zUpcPSQ*Q!IMm1ud%JJ6r`?0Aw9v>lV- zLffjd?Y`{?Ic}9$NxbTX;-+UmP+?`M>ta|tm@R85@_kFAUsxRbMNi$Xz5ssEe(rYl zN)p}>5Kuh9rb*+6NJIifLTVVxgmIpqWOcWJpM1Vs2?Bs;OWt}|Pv~@0Mwu)AFf2;U z2`=0JAk6OQ3ourDZ~bjRD!bw2wnV=Ze~yK$qd$Z_RmqqtJ0(%QfjX*MrhQy9ZW2JP zmnFr~E-Cyi<(7%K^&wX7gT|M*mazWbZdd2WBUXiXO<0Vp-(wnb|FGP8HK5#Ka(0j7 zz-1LGNtFSP(PMp!%07RDvmdIM=q%GvlrIOENweZb! zM${<*-J}qMKu=4g@5n zp)qGEW1zhSw~hmKwzCF)A)3=%k(+>A)Aoy)8r0I4?axo0{NOF{{g}vn+DR!62st6z zP!uX_I5Fn8USxN}(I$w{=P>q2_o}`Zh5JLukQQTRaVcslpj#Lt*nEkG1Rvzh>vs)> zo#jQbw4E}ox2&kyh&#*2yh1XXTbQ;&j>selTG+6(m!kaJ#~m z1Co`ENvhwq#S`PPOh}=Kx;D{yZO{fgp&+|k$#`7w+WPWgU0xSJ(Tme4LWKopVMsEdX}0c-A_ZaC7J~*cK1xY zCV2HYcJM_WvdfvinK{uG`GHYr%?g&;uKkp#&`&$p1m3=v+jZvJio>&$G)u}pf+50H z^jA3__wf~Y-dqKJJV)oy-d1&~hHx`|Ma8NLJ%2Mk0wu3=$JrHm=l%gIB1i$Q9VY2bxNE-B~Yuwq{H@? z;w(Odwi8NA(UvnVRJ`+%UCf2TLBhng zOXkjkm(l{^zeN*>*8}u~+)a;Zp}pKA3S+O8@q+BZ8#0nT-gM=OqdAKFQ%I$ZQ|;Gj zdg|nx{2Gh*?0ei&bDsp2A8;DfIRbT(-=AYR+Gu@YF7Z&;5sn74F0l4OY{T~W+3|w(kCd$ zHkRrP1XP^F8}Q=jcHJCp4t*_^0lKMXWpo=29y!mO+p`iPw&h-w$P(VfLnB{?1l5Bf zDiPOqWj3^r638%5U#$)bOe5IhVNLV`_7s@0S_|xg?BPEb?E? z3B4pYwmy&|+9X#8{-USkE!EyWPe9ffZ`9!_)Tq7mDTh#lmuTbv{N z60d0R*>&Gh=`NprGll`NT4rf}l1UZ}(-(4Y)G!whhx@)8j=b92m&>zvyL3mt9ucZ- zY0d~B^Ua!t^uz8deXyOhHjKijAGD&ha-bakr?@T zXtF_DGsp~*4cDY55-pgfEh)9JM81=;k1C zj9K7cTa_W%TMN&UUasS?h3pDrTy8W-S}j9F8NW`s zYTYLKl0@VO8)ohzP2?LHagY7JPc+h zxCU~pnZ~Wx^*HrrtI-Ff5IZ;QYGhW$h_jjd!YHf0{35UNS2v$BLX#VJ=uH%jm8sG6 zSAb-IPmEyBrT@V)m_R4GFp`UEUceR)Nl|5^y4C$3D>)>Rd7rC4n91>j-ITd;FT+>o z6uc~9oD20PhRqL++`9Ms&>yI8og%T$FjsA^d(Y7=>1TxU<3zzsuAj`yF{BQYeu2AF zK0X_%6}wx03k!08(eG+g@i{A-m%`yVM{NvsQH)$AC$uUj`?5j(h z&AK*QlOCGBdJAnC)Y)8t9(C>}j;256m6ecqOJA@p?Ta|c8h?2@ApmA1XL)*d{60}U z`62oU)6-MjE9@JfY}oz4ieFtcmIE264hiYYLNO>Bs0ruT=E4NIZ6)l}enJA>Mmk$D zV*2*}vN5HTfA|}?D4FXKUZ{O4A+VY1E&HsW1rR>%e1O4{jE^_G?? zm#k!`E0YAoQx1<%zaqSRdG6Ie2g2xU8iY*o9}egHRI2V>dP)hK171~M#fOTnyPBzY zQ|HijLHujDWuF=5G;9HD0n*vb8pv~n26M|oUADeZNoG=01-=QNtA(09rQ%%dk$P@- zIc{LcKUDbM@6_vydf}@3+DzR{-8+U6mOfY4O`nZ7)mepEy-AlF@r?mDg#g6K{;F$F z`eHTi!PN~w;IhQZ=e)k#v3R%XNVoXlJ4>?zPamKtG(SWSidJx%V<^(7RtcCLFy)ye zsfXA?C!zt8x4mI+bBJSqoc{*uhICO_rd8(Ma5DKyA;~I2TUb#vC>BJYV^E^34xw-x zwK)talLZ|bA8?j0B%1T)(%;l=xB<_8<9CBinNMZ5+Pc6RomJ+aGeb37f))G)Nb14v zh&ju*_zjHKW_rrE`$gxJP$!woKgoaE;fDRE{2H0w%I7!@0mhLiT$*uH0d7v@z+0~^ z0-Zx8Y>-AXldB!9ND`%?qdjv0bwNvjb#D!MPC!lT>)Q0v(~{w<5r6OB`=RHqT)7m! zbS55DUQ)n~2Zd^5XENWAzMi%cF?xug+a>y%W#x#atoFqNB&+>d;Z0fR0_+W;Kl6C^ z5Pa@${wwJ?VG&7j7$&A&e$8l&+B>4Zn!PutpzPO~{F-3R0-|cQwl?Ai${49u-9^kF zX?DTH>l4q}0E2@NW_!Tgekr7J?svI!b=I2-NZpEC$nTj5si0slk|#c#h#s{+RY9?x zvp^ZO{4jc_wg`WgKaizrL!t^a4%$aNi%^WIX4Qk!4ns-vqm`6h{jOWC){+BNohHsq)U%7`IajtXjQaIW<(`kRSCYm6HZ=2hZ8GC5*>|c%Qk~VAC!|dz=>WbQDadwWo>qJ8WVRDq(bn>mIqaa(18k4PJC2Z%K@;;ONGaIiuT|V`|LO z8B8Sr9%nw+Ci2N>b1^cdibHG)ko@*vL%T!m+N~^;xq(u&g@34Obmoc7?}e38j43tD z|MGyJxIMV&J@uLssciEft7>!HvUigHL`7$fb*PuoU-K*5lP@#SyY&> zEh`a!E;`;*6BB*ZHY8=Lg}xTHEhwYrw?tXoeC<&C+xNc8814O^o7)K%eaX*a(T_u> zyTa35;pwjMbXPcb+juh36o7I?O}0Qw7q)B>ImgqCq`82p-V(45OsZoo1pB%#lef;! z`=a{#G2Zm))A?)8X87ei8MOC18T=x9(P@1+UuvMSSUs+~qkT@FPw&i|q0QkEW&GIx zr@bo;YwB9pp(v;baX=7|#1T-0IDk}!L`6lR7}N>^LR6#?Fr>&7A!OqK0TGc};Ruze z90oy*%*v1e2~bOsAwVD~AwgTF$WDuKO9t=ix&QBT?w|YIrzijNBhO0q+H0-vTi-i; zBy*Le+_arw09_=clSF`lj<=o!Xa0OrxCZ!Fjx9xE6CYQIXa=VT=5qz0CgMAEzHz|r zJ>`J6bH{H654P?jT(;4D_rO-s0^`}ra3n*4xz59H%aEdha*f=G71__U14Y?65Wy{? zB>8je{AnxcgvgM=cS2^Gbbx(mARV7&lCQ8$O!ZRSGqFM~hyV`$+1gwE+!bBM5RI)@ zGta?2H}6VKnOt%{QMBv#_8*|XhO-32^{hLM7`nP$3KhUjQ z?^8bK?6g27Q9!oNh|;ujYdiT|QMA-UHUo;aY39Uh^KYFLBsIG!9yXPzJ8#T)lZo6x zS2IbGKCxLI)4)!PZA^0K6MIC|n2aC;;$7>m{>QUA3w!^*>A&`B_iw&ioi3!O6~7Y6 zkW~1!azLJ&Ie}g>Gc-eH(@6X{lLapGW7nFO^$mN>UuPxUJsqA$uMTuqE4gn72%@S`Gvqdm|c2s;aK*Q zEdvX;@(Qkl`&F|3>ujiXH&8_abvq~mQ5n1FYkSinQg#8K0gPuw@$9pSMt2M!Hc@g(7$PC2o2CF>ibgO>;PUKZ&~muG@8+o(8CvB zZ^)9(DWhpD3Ax1*$4mIhmsR=cM$>U=)^e!ry`0`~Pu2j)^X*Y8n}N*;TUz0A>{_53 z)?09ij(4D7eFPseb85qqo{9s>y=eR}s#O)4A1p zkK|t?Xz9KB4jXU{Pi3v8+ewuXX4Xi2lw9a8phw}DADVV`Eq+y-L)oSI)BmNn`^mvM zSGVHgJRJpBwQ9-N2tcnFr|dn0MYfXKe?50Bs{ZBMS1KFbPexjL(Z5eG`rCdJ{i+85 z|JCswY-6xnf(ap1QS^S;Z&ahFvRAV>4zx|3V|($N;Cl}NQgXA&8#ETc8BP)4TVpdr z!0-gBg=)`I>n9uZ9u*I#bUeCp$?Nl3?9&(>Btq$>vQpP_48XA74#ZJ`!e9L$hA84m z=CZgKl+Z}M)Pq;bu|rJ9g&C?1Pe$k-%#L2#FP(u%+Du7!0=+j(gQ-zkJ)lB(N^K(L zL|bQL2hcH9rTCGiym#xjI={O~8s=s-MZRQ5_O+pVvZ`w25~7s;e<} z2A;h&`EDkEdiS0%9ylwv%F-V$&Og>LNM)n!7y{B#0)=pm1fL9At@xnM<$kALt*C?v znNa8!bsl4j%8i)8ScKq!>UT+a9BcIk`C$F6OSL_if7En`9Lo{$cthCG=NaF!)TXC0 ze5wRL3u-U6?BIrBlR+ZWl7(!|6swF^11p_>02Dfm<|Xx;l^3augiT-lrP4QpOQclb zQ?g%JGb)f$7tLT-)P=2@WULoZmiy%dm_DfJDjl1ll)id2ysvtCe2qqrzF5s|0szP2 z6EIpP0Cw{mU}jqu%1gNsDVGH0^5*pEM`3OjvGrv>5OcU|bdSf!- zr1o~Ky&7t-hT4e!w~f=<2h&Pqv=v}&1y~#AwP9Wx=C#pK8x8*-Mnl~n<-*JuG!wH- z4)M`z-gJjbpsx@=e(-MjmiNs?-Sb0v`YAOT&C&iZQ(yOQjig#%KUVc3$JXWIyO%F7 z{2`mj)&!tbr?WIhUjur^iC58!D?#T>8ejPZ)o(G*Zr^Gr8L3u7BlO+T-#dNy?Amzc zsA!}^Zy(_}V6C%6LPfOtc@rAPCxPNhXDVYGE%^1cfnfk;l~F0if6#MLeBi^p7vg!U zbPzweP_qWm;W;KyTQ^+6PUlKca&_*otDmF?pO{ar4qq{w(Ov&i=`=c@@ddSURC)4H zqo5X7B~r6z<*3ANt+Y&w!vGwHKA}AS1@-E&W&oHAC>`@ukek&EK>`dXLudO?_Tm$1Sg{q1@B? z_7NF{aN9}Cnl^x1{BL06eb#i9E1jl%NroIF##=F(?)8{{9PyX@Ni9b9tG?})Ci=Yq z)lk4Z@iNr)td#3zj-%I1=3Nf((qomqMYx`QR{isK=W4pvqs#F-G(%8bk1Sq!i5{W8 zLpX=dAQ%DjVp6KO%8{A+6! z>{j~F?R#q|7KZ_WnAaSlG(BRP*LlP5m_X$Om_>xLnLFXWzHtfLolm`U#@%$Na3?BF znB+3#j&38EhJy?d)|^35?F7_&3`3Zp$cR-QW&DiAHj&{j=}-~5a0;`gf3$7rH|YeA zvsr1BSu`m+6OedjvS5$k=^Q0yxMFU8&M0uK`ByE;_IQ7?`6f=_7A>`ktMxpsQSZ4OLHP7Fz{J^X>w8sD5fq06PrRmhv48Dg$F`Wx~d#&`+;j4d$iHF zKL(qMw?taZyY?ZtWm99T2I$aJx_2dU+Z9Kgp7pKmF`EOrmdjscT82-?p zBk$o8MG=~1V0|q51-$5%tTd?3Pv!(iD1KGv;&-UL`!p+69=UBSLsv7nx|6in)m_?X zd3f%y+?2Tyj=cL2m)7L+UBh>UvC&RxuOAsbGPiSjyw1AKEDPi&)2p3WdKG zSfbQNwW-nn!_?^i>@Vs5jvY1Cc$+G~(yER^B%rlR7k^$y1-da<5ytDp&wrow13Tpl z3ONevN{0&NA;*#0aan}4M#xzS6M0uYHfA1bIw=q7DA?XdsmVO>$*sSIarIl>ng^aY*qlX|axV}K7`;HRBSyCArx3&}IwXXkAi-?D zq4S)FJf1(=eSp`oCy$(toA1ciSnWC#J;7c@EB7CYIrIW<&-{=pK`)vVF>gl35LZW> zK+&%%_W{SqO4C^uI5@rrn*o5ui+vD_X9!mjt}b`=Iw!xbh*Uq^2xT~BW$h@xN(Nw{@-Vd_*s6txtsP7%!d7w-6mxvMTEIw5f zFU9g%!xjo7c_)vZ$~90~K0%=U>MGUA31UVA`MPEUlEv@*OOAs=tXoJc95aI)3r+G} zKZ%MYb`kvK=}TGhc94fk{0W8=TqS@@*f zujvV}{%alPK`l^axbmCvw=LTqr3=O2rrJ3LlXAv$EYZZGLpU$ zHmQ9^3ZB9&m#Z*~8iiEVhWMgsjO7ruhNT;k2c=VrgcAcX)$3V2Q32-?eXmJnYzgSu z^%$(5)gzS!TO>n`A=K&( zT}VpwMV7K@_Fqsw2&4?zA2MO-!5c%%PrWNRTmg%`AqnLHs~v4bB6Stp7e*IPIoDP1 zd1&uocjD8&7gYrj73*~;(8%Ufx3j~*!p9)YVyM-bvsu&2T0t1k4Is7Vzoegwm8W9O zv8g89wN$q3cD{slT?`jYIa`%49!lR85NuK0_cV5D{xe2 zB=git)Tx7~4*9rjD_vGNvJZ1D*|IjeQFl{v(%v3yCdv-9*E?Xin^@OSuwY?f!;U;) z*FGCpx#fLJR$OaTjA_qLR-cA9$Bi~uW_GSOoz%tiJOwdau+7L}3SaD{mx+zsN>MvS zk$)er=4(!{^Iafgc24BH&iUznkz%PG)lT+7_TJ*cwdu7V*564uYWyg>vw9gSW>0Tm zStoV5kB9l}ZJUrIg_*m5D9tV_yLR}9ZUxHwe>E4zT5*?l3bbXGzxxS_IVtaw#`d(b zZWQ1VR>(NPjP5f)w~&C$%@c`*mB*afnXZ(lhB*r!sje>P2}9G)uZ!F&ZhhmsA9cUv z5Aq+XT$IWP*{M7XGKp_OLC}Au>B6G95jbO7hy*m?5Lt|KJ8)@3tSVCS?=Pirjn z-5fB#X+417pjs_wcV?v|SkFEgpGyWE*5pf7wiDHCkfnG|iC3@h1y|Lt-c0X_6Z-dq zGj-{fk8;4@x^dY8!Vg}+Z+N-k+#OwosUlNd4v|?Sn_BA_1a%?9mKG@SONq7IHtm3}t zKk2-`jo#v8EJ5EFE9;jZ8qAi{~Bwr*3!2^ebG2_Di=wRNKKUk^D# zKUCfKaqeHw`02uwFJ`5auy|Cn@&!eubodcTl~hKyV4sm{ShA~12gc8sb$u#7r6)ZE zj&BRX^8HM63NV@x~U`-=<@@RXi` z?$8B$)HcnpP#t-erwpaV2gr%D-SWGD?Hj`~JQFs=*%YJ~G3rg`RZlDa44OJBMH@!M zC6LnQ_dfx)@AwCMN{RwT#rZCi6Tzqa0=#B%4Ka~%q6}TX;KqBYcPmiA9n$xG!iBlt)1rApiTWcolns;`gt&9G7%=xc zdjBKbw6p>Fe+Y;R}g{W;~X7;8@Mh({L|I~=rL+u3yVhmIDLukB-Yjz3m zI2p&;QLWB_LV8j~C9@wT=(Q$;^xdJ*#M=n3Mmd|`ZNPKB74ICAFj!aeG??c3JL%#F zoYAF;d+(A=JtEdGB}8(U(x7qBCx)t7>H*4SdYR_{Q=Vl>kC%6ivpc*9%R3gkNJmQds_mwwuSQlxJqS~ccyPJWm)|G~*4<__6)_wA;xx0zJq*-t=c zjte>;>s6~(j&K0WxAko6UuBwWcUAtnX0O(|MT@8QVPE`@i$c3+{zImR4*Co$wt^_H zRH)PiP$UuYheinSBZe{E0|8pFWn9e)aXl!?gHoTtSHjbEnm6FfLd~jj+$?T3O9oiR zBP=*Q0!vlm#WDk&OUyoOoR9u{oGcKOm?n`Dd4%FAOqD%S0{CWuJ$qj+K7@FIaoyYV z%2ZgmzJt0P5laSwtvT}0XZIlqbxlNr<&UOaWuy%S3(_FZRSpkUNndw#EVM=r>poRi z0hc{dmTalqPr{Yi!Ul>PAgE?3{Z+gA9C3@oSZ2UZ&(KtAl|O+_HUFp3w4PI_UAbM|odqBLElNkQPrg>gOQ@n%LPe9h8Vai* zEBNX{U;)?c*UHj&Oyn{#7=#Eb$DvgE;f9p@n*@m-j83U_^YFsk$W88+5+6@vwiaBB zBzfgX#{$8p_sJ-AId}Xgt})(@F$fw*)o?+kCz?2|{(<9qk-L;D@jx0+VVAht$;)|| zy+{-~eXhwrteAxOwFf9t$W%sN(H}LRgsa29&n~(cJu*Bjo|68tPmcj`4)_=~o#UV` zd8n=iB6H$u?10I_;UGe=z`NpJ zwy-!N_1&5nXUs42@)+=;v~B-nH#+>CCGv%2w7s&_sDK3Aq6z7 z!qG#<-CXt)*G@N#)sms&=`o{9_|whDFsm(V5smasB~a;e%xUp$<~MNh(Pa_28k@!e z$Gt761$V^(btWXa=NhX#iwHF)1eG-l9u(KGGN6m3*&gH|L1GFPmVsu~PeAaqLD7SF zx*h^KC~-LY3kuZNs%X(N(){B3hv@pr|Fa6X_J_1IK`l*COB2-61hq6lEf%hghT3ST UjfUE2sEvl&X!su=4Zn>17yGy3KmY&$ literal 0 HcmV?d00001 diff --git a/docs/_assets/dl-apple-signing.jpg b/docs/_assets/dl-apple-signing.jpg new file mode 100644 index 0000000000000000000000000000000000000000..af693b3221fe5ff59fb004d50c7cb62dbde6759b GIT binary patch literal 593662 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⪙h|8zW<@-AF6LU7dq1N4h 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%0D7tK+R)t+_t$fj4yiYaI98`} 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Ò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 HQT_h_%pE18 literal 0 HcmV?d00001 diff --git a/docs/_assets/dl-apple-urlscheme.jpg b/docs/_assets/dl-apple-urlscheme.jpg new file mode 100644 index 0000000000000000000000000000000000000000..579f151f02338d0453c24b8c959a1de24caeb00d GIT binary patch literal 590283 zcmeFa2{=^m`!Ie~l2qCd(#To~Wi4UaqzIwNIv>e8m~0u0nKny=PYa5WY{@cN#zdIx zpHj&>jAhIS*=NW&%=SO}EZ^Vz`~BYc`d{z+d*AE5{{N2a%z4gp?&m(wb3f1hJook- z{678&u-)X`g>!&_fB^6t^at>1zzZX^mpcHMnE{6Y0N4Zw3P=HhP)YzgO$4O>Nm~gV z0M`G^Uk5$Z0H9xBH+0%ZdjT7M<^zBqbX_}sgU+?`Kd%}`G>+;W)zCYlA$wFyPeW5r zRu%x(zYzEn8=nsVFV_8;-VD{_#ri+f8z7*ygHIDt@eB&Op{K6y7pUfP9d*r3%@yUV zj&`}BepKyGmx8qN0O8Ex^5t6t8I3~?8X^4Pp|V~0dCe| z=9gW=kgmtC%fSt0_0f80-y6PeK`ydrUmw3fJ+y(`Pvm+~dM#UBPWC5A5Yj;Is@Wyk zGpGPJS#33KwIgy+>459*dRAx8{Z$saGm!hMk|7}>Y9X3xr~nW3qsNaQS3jbmuA!j{ zL8u0X`USb5Rs90x|Hg3EEzmW<>qd|l%1?F;qsui^aFBr<^yZ&cy5WfmLIrxFZv2D% zzoEcCkAKqP??O&RhyWxqJCQ4=!ERmAw?;Mv$vvGPZu4^4(Aa^4Gbv@YC?Yi7w`GF|+pb(b;w^JTaiwxvWxx0J$ zc?E^aLcQnZ;pY}0d*D>ChwM=eS&bt{k01QIREVb=gzG<6S{-_=`dVlISp)TdU%8*p z{>{Mn8yp&KYsr6xt)c9%;}->fQQ#K^eo^2T1%6TB|9=$tm*DH>2T8jjkXXx~1rA^O zTWXZmR67D3JAJ`ygW^v~dV9CbgZ@OIY{TR&;iog;X)K>EFarr+h)Y%$=Pq0{g0uoi zY9I7*^$lE;=Y9Qx0<4Tr%U-p!mlYZVM1XyOFeK<}xwr=2ICbgL#WkFNUw`8N=ZDq% zQ}_qERM&9nSk87XjOkb|_gr5oEBG+~57>X6*nAxlilIjw=u~sP5fB8`=`fU*4+*-l zmc9g~cLzX~g3{O5(jI@N(QD~zf2JS>=^W27-A3rMJ6!xc8XOQfv z8#jF1WH0!+svU-8L5-sTutvKz7ywwb`iWIQyzXCls2l(|#)5RAhyTjE_5=WkQ2?-q z@~=FF3;+4DJm%+ICw})TSxcUalJEVjm{aLzhGj0 z`HGD#L}=IRZtfnQUfzL0!8b$Dp<#FLMMg!(+>d?q_(@W7%F}15FSB!U^YUL6ye=!R zAXF0HR#i7NHZ`}j{_){sXIFPmFS)OuLZgp<8ylbaJ~_o)Sp2cXS_W5E*V+Xsy8n>u z&zAkWc0oiCShr!r`VB&B?GjiQ0-fu3Y!KXkbmPubmO?K6yW})(Z`ytOVOD9qu)L-f zL+n~W$7XQ_Et(>8t!Y17_W!P7cmAhZ_D{q9)h-IKWxW8@dFyuoaDbPgV&O3X;_3wk z9J-cZqsHZn9QerN&-?hmT|Tg%kiP6hRQo*h^pbc)=3qk-Ie7U+`3!G-cSCzQ`>)Jf zYZ=Dl;aC#ad)-=gXa*I}2kd|5@ADu|^MT$MhuQF|=x4L5d|>I7h++Gj%P;s}^!dMa zJZM+{H9RMdQ;@-L{~FJP*m7i-_0`to)nVG7qj&N_D5`ia=$t;WcUe?(V2KY*Teknn zIkFRpxOzVD`(I^CkN)-ilE9xu0sVFqnGY176#9z@z@h;O!6N{FGtBx=EG}-f8~B@< zewF`8-(U3mHGb9>nqU0$YyS8(fBsrO{y(#Rt}jj-p*HrH@`0V{M*frZ%stQfz*vh) zHw%l4=Im+>P1h;@R5uT9fH88hkc{zF)3ScbA{OJy2R`rM9(=ufj9E*mOGGuVYwE`S zI7C^^ZOcnT7%wi?rHh;y$!r|$y4Y<&;wbJr%Bz!apLDWpds7CE1$Sjnf|58-SJ!Y` zlX=wj%ptdxx?9xsJn0XgstvQ0g!V9PAK2#Mrd&|=_?b_l_{S&?nXW$T6V^2p#s}0n zy7UrV-foXZ^;L-_QI1N@T6F|r{bCO)trmv}oZIM;>@7v(m~u)62X7+2TmE~d@qxcV<-Vp zYU58#d|(e$3Ep2|&k&UUdll7*4pVjZjtJ0_4{U*dM|4|oKMz9$lHHASAHfxva$32$ zPjO$Z5z9iH$GdpDag8vjov?qk^DS)3iVqy&b+$t9vE@N%X3zWr`$dpnBjgt^^#7V1 ze$AG@)`dR>f?vGwf0`F86u@c5X#KDVc!i$06ZC7f?Ic8K|JZ>F7LCPNz&}LLRaMO1 z#%GawP(|s^6xJ0b2d};B&YDRd^=>F}xP5_O*<2j**lD(w^g&|FO^uL=rsD?o%R7lw zX|?KiL8Ys*q%xry@VrpHJ)XvtpyT*}4(>~ht>D&VUdX`Mc$ik+_`FiuFbiqh;cQ_x zG>iW|nsths3IA@=Lt>0_F7YxnVINBl*>v=WDF>G6_YSw^-H-hfCyWv4O$Ghy4upk+ zow*-sr8)NlQ0E|XG@SN3$)kOBCjr4ZM%u*(R?179kspRsRjI^+FGEXSSopXB?z(6{ zvpiGKd(f5Vt=_~3cs|pfA3iQmx}IPAb)hmKo-C(wg~N!vy{P+CPXCqNu>X*ENdS@v zacl!ftV=1x(OSTCXdEX2zX1Ov*)Q_^8Wg{H=I8A3ixqyc!Y@|%#R|VfgY$?AiNdM00_DeweFA|W1qRDSCD1~sWI;Xk*hqm|g zu>%c9p69Da9gTaO@-jALMcQQVYv0=aAMw62%e^ccRe>nUQT)OZ-eC&ezA6YANJnBx zoEUDgV(oc#He^9Pf6@TAS@CXj{c#JC`}b_-E+1-Ex1m3h(|$2=fPLPe%J;y~WHF() zeXeSoXcnh1dAgeYWrXU5@8fZ0 z0Z==>{tdSoIIs@>XBg(C4Num}3$CHr7!mlKc2Y|0YtYZzzjFV%>{$6LTv;A^)!|D* zw|HGpoWL3VU_RiaugC`q@}rS@>4vzho=7lvfs=zJCPXK;c4ba?aZ*?MITm9p@_pF^ zD3r60`+QsL^JO04aZ;MYEb49Fquei3y&T*Ka4W!~1a5+DZ--(c?kEsYwIl)LsmMQ@ z_#f*OeeBrCSEV#FWsi;w-O)sf&*>m`70XspM^ERC zG$;RF0F=zWT`5g!zxWnqaL?nQ8=*5_LOI958!q<5G0mHzc#~!8j*8XTFp}XF<=oM1 zoN6xhA%_%`HMqJ?^5xt6N>S&>V~w`%ee*|Ivs@-U;jE%l_(mCjXL&2L7E6Dx{`_n+ zzv60Q>cwSiD-%m^%SUEfbE#o@sU3L)Go7Mk#TPDr_UJ!-_aBM(cc=dX`9DVqLCGZ* z6^DVXhM}=eQ|{ldHjiCw2=v&L@h!AK+Gt0De2s9^j0(r*(s$=Q1)-#qWcR`VQt zul#o5V>(@47bs-gvGysG45PHm`E%XbQ3c0L9a>BtJXfe@m)TyJ98$u{@xDOf3Lo&p zQyl8`q7!O%u`SSeOw)^B*nZyQz6W(lHk|N2i$vocLfo5 zIJO3)T>9(_dsM8vsz~?4jTlGv_iTyQWV{niC@JHJYZQm=aok-%h`Az{l&cr4Xc)HZ zNtIW)nw@d7Z)G+oyS@s3zs4)&n&x@tgEv2Vm1+-JrXR@N)KHi&T}bJ0thK&La(7^c z+=Y+iAOx_opc-9N5@QE`@xi^}__#2VYnhK*o!7l%8|L~G8?Z-X=`s?tnMfT~rScal z2h+~hb>)XY?HB{+cU|L1{L>~OsMW`yCIXgiE8+4 zAs-Oj8-F>oU!gKA34}8}6Y-pQeeN-QyW)sNM_x`2AD|zi&Fc)9+g-yh*5>reDAuM~ zUI@D286nC!3zw|2N)cq2nn0mczxOB(q^)}3c`baP65oPPiCYNS|*^TzQCc}!P=3|1rDwY!2R-lu8TYkUyO){$xrP=%q(QnGw zryl`B3pM&}`vWYG)Qqjl-TTG-D&`{hZnmCgV^32j{xmvF%f&t(Z5@}dF!3ct6qL=R)F3`*sUB z-!fF=66b18@c}6OZH7(b1EL_g)o?u@xHrwp1Fwvzq8z{odi#+t3%9x> zV`>36{L~okiwfU5o}n#rLM1ItIxeyy_m2#4eqmjf!PY;=oT=r zoaUB4o6h!`{W2SjX&F?(3;-1WyAZ?WJXIH#u2+OuN#L{^(gba6Q zpRDN4F6-X^wj#=&kUr*DJ>w|8I`q!Y)R}#Ak;*s`@5(an;GD?z9+rhdZG934Di!>CrZDVBI5j{a|l3Y#Fwj^P5-qtI-szt=QocuMmRO|N0T;CD=U7dbfz;2`zmK zKCrMvU9nYz9JJi2VUJI%m1%CY0bG9}9p5ldv1SpNt&ugsYzK}C=x$B7Z5j%gZx~i( z6s@+rS{={I|Ndsuep^;VHeyO@L-k>+=^MuRNGVL%Bk{?Q#x?(+FM>7gWi_TF+aXHCi`eXWmO^F$jXxuwFJ(2${p$*Qkwpf{9Z^MnKx1xBOMvsQA5G>}C(Kckj$7RY1 z-|=N=Ua2>OPh`#<=L5G$G9>V`iuwc&+$lG|BEehtWt4RpBtp*g_UJklKG4ur#!yXp zfR*F~GTR$W`2c8}Ts?-5#^Y#Px;VPyQl*lGDMnH;K)YbB8)GeTBFDUDxMEW=pSe3(lTQW6~T-Xg>7)rzPZwl z3I@IajCOdJDy=GUvg`Lbxrr;?eyX#E9b=!8z2t}5C5cfsmxl;Ek}?;&Rb`TkMXqwN zSHBu=HMMkX0jQkOEyw}K84$SqyR=2!q!$UgN3HYKZo2kv- zzgJieoVrnFZ|6iPQ}7ojEX{HeW{B}1BZqv=g}Ss!Ut3!4qv7$JwXZNf-1sE}m1aXV z@L4ej!%Zy-Hc&TWM&aqx(#ZB$#Aa23bW=rii)|P;$Nw`ueUqc3VqW2veqOP>c5Vj8I@AvBWpG%qR#NEDq zwdDhg^_+MB>kE!v0o&PT948P@OT0_k%`szi)x*l?QnljMo1Axbt7^5u_i-?6UDh2m z&f(o7l`Px{b+cH6L{sY7ss!Pj%C}XfG4r#~=<%k^txgX?d+9<~)Ls<^;v#=keh97O z1Hp;;BsV?~zm-X(iQlK2Ie%1@Z><(w(-|mRp>}5ic4J+Ih>!9^w&DZ*G}77AO__5e~1irv!CzRx{7`NdA;efrx5WJFH|I zTpnVb=sImq5R)2L;|+J`1O1hr1N1Zc8W<}u;Wtz2R?IHOx2W?I)$cODIE1%LI6H{+ zY0d7t*tlNxeT{D~xzH_Bn}8Dn_D7YKZk61vQxB}vu!w^ zd2jNv*;xNzS7QF)aP4daqNEPxn%hOB+(Z#-#a1zOqqDe3*lztD%*1*r<3x@?QFGCE zscwg)C!6Lf*stD8*gF?^+vSw@_*_RFTKM9qt$Chpq-7{k&r0OxWo{5i*0k|XeXne-0i-B*8)4`-7S zzdz!L=3;j$wLVG@@rHC@NUrU%!htYmj{NH|Cz!e6`|1Y8nQrBh`< zX&NgNS%l^TEzS}Q!}!owjkyj}!>Y`UiL}p#5vRk$3tttfmMj%ci-f12b_iD~jPbel zWY7$S3_k2Ve9FdbAeU>1AajnT5tpF(L&oA5ABf7}K7)TB#R@{S>|q%50kz3M+)aeP z{`8v4q|uC@J;>G>9(17CW4~r@m@82$kt5s@LB#Ic^!9BAeKf$qVPHV%9V;#_E-g`Q z&&w!f_T1cu(w#QxtJ>2qx*t>c0DLmz!=F2++;;vc84Il7vOr{0W<|(-xF>!udV-Y* zwlk3Rq>a3z9AnTS`+MeQ-hMCAR(;i%AcEGU6A~63Q*!}l_&A)^P7qlM78&54^HlvI zf>u78>JUo1v$yhx*^u2p&veL*oI35?u8!d8*R{(U#trlRB#<Z@8u^C#7$&#?w9EjUPDu>J%i(`*Fmu(kpEU;}(?18FPDh$`SO1^E`{{gT5 zmGzwiC*Q;juw9Y%)F?i19YM)&8s6JWz=@*oHd4z&T2+y!$yzd}N6+_GI3Z0yH@fc` zlirF5`(|3VRxQG$mJl_6vD?Q_wyLc9Y*l10I_r_XSP>U~g&P5FEg)F={@{_+KXE3w zX{6trJm||aiwtRcYYcAW1&(38Ro5BJWH`_~nha28U!ks;ej0RQt7}W0P=~%*0mYLs zWhm0UbReh=`Ps?=xd}xuI6ZaZfNw8-Zv2}?pn>%?7l&XpHxt8GZcgF*IOJZe0g@*H zIu-D~3?G1G4UO;4atty@ywDO<#G@zdxUc55@D!2L+=ms3BD%MhG9{72%H2z8(rj4t zs@jXk)AmuM(5wN@kxFKb$CcWzv-#(`$a#mzLqj*0x=QMdU@sBUq-z2riT!c(Whjm< zipsE@2M^3YXuZP|L@$mi-y*<3pG`~i8_}=85ZYYvC{DytCp!zR(>KN2N$wpmuX;3k zwzrskxl_&cZE3eW6?yX+0f|H4Cw_yQ;#_5rj!fm5X!c?7Zc}w#E*-Xgnp7VB{xi~< zxsh1lgwz|aErzBRj_Ru^N-yy>)l_>fx6nI_8t16qc}-)fJC>UDl$aM zjNVsyH#Ag;mGP{ATNVMc{`y08-@IAcIYz|-a-U&_N_yZaMjU`0_{sdXRSBWLWt{Np zrG(tM9Cb6sT=p4xhxs+NJC?gJ<8t2>S~{nDZyD-?cFc(uJy`sF-8Sr3o!)BO2hCp% zC73}fzHT(C_`ql^`9jHcsykvUs5R!ArY2=glBDb>w7$ zg1?zK*2?0K-F(0ng#G@l>YIkXTHrY`PuuqsS3D$J(^8AK_*u`q=<2jxZ9cb>To${+ z2X=Gi!RQlz9At`J%tHZ_?P?YCQl#D2#}q?61MNcbz(IeFQJ~b~{aUA~Gh{XjvxSj)hbPL>XDT;uy}8&#uG_&#h^DLH#6Wm!ukuOeZ>6aQ z=Wz{A1?cN&oOM~ooJdTGlv!ww-V=8x!+9HCw+;oxXy1o6YLz^va_lo%n5Uk z@!>0*3%)Mze4VxVQCi?cpyd;hV4@E-zVYIyz@u+s$6jWr-_MZRJu!P^ z$+N}!!EvYKCYF&}G|yb^gE}io$?Z#bj@z6p%F%eUrKm{K?)=BHH|&p%Nd}v~+0uPY zR9h~zSb{Hq_(xbRCx)ysD=|Zzx>2@3$2C`8vN2-FH zah$1II~<)~_t?cSGvE2D*W!m)V9Lp^;+)>OA8p9mGq$B=gjD3S-b28u+<#-(`OCiZ zfBPk8t%CsTS|X68wPZeB-TiMWe8}xsy|eir>r%Z6i*Fsg^?%Nq_FrJR#8|Kcc!TgQ za2M*mW#{9}qEe)xCfSwL#S_Qql)pPNP2H}40qOVHphi#?C4KR$7G6)7V@$tLT%sEE zRGC1G9k|pRYydOvey@QW$rx7P;xYb=bJKLu*?94|Ty$IOu+lrG?HzrXD~$~oMLG+C z;jjAbWRx2-6w6B!wC}J^RMgd$b`k7?Ma8_re8&j**d?W2Y)78gNm$4wfz)-=BvdPk zl*KTf-O4sbXEqpW-)(@25~PvxFE)K+iZxZ*NOTM$EVdH5?Trk%3FuK1fyH6FEtezVAM7mQj+Y0 z#^01be|_x3vF^w5#zGr1mu&Ct+xkuaOaqv(pZ-bA@$@If1J{3K#WcIPosK+clYcmz zCFT|Qu@(_&pMXQO#5GZ-tP-ZzXz%ZP?s93Lt<HDnTXfe{Ct1rc&L%vL1Q5&w(teh<+tADb^G#l5AV)BWOXn9k7CKH zQ+1wy{5Zr7IMi`r-VNtWy1(dhQM55angv-07TE`QeTFI^v_n#Gy~VZx3=Ax$JE3g2 z>2ObVQP1R6^}9h9+u8~p^B_qb8?NHA%QMyOUbS;3-OSXXF0;vbGkJno&6F80rWxQY zn5r>Ca|%|%wx67erDr{_8*eLX`dC!9?wCN?&5_E>8~+%(C7=lSuYUAsuG@l}!^gC8 zm+~Q7SJPJ^myq7ps7&8?EhRe2OU%O>%EfNd0oR#B-Ub=Z?=tNi zH8hI1Srn?IRt;0M0e?4h7f;dCMyh?*LAxdX71B_UajuH)tJZ24+y0)VcaLJw!%Ewr zmqdul&L4EN*N+n$s-a8L0PbGy1Hupr^3Xv$EehxsyO4VLm>OfcX#cwr_bNOX?bNMC z@C|hCUBX53#Jhu?JnVZ=xf#pWJ%kg}&*pM^}i`GAR_oZ*>`j=tvuuTL;FWpLk3dvW_nGz5}nGRBm?nLXbY_g#& z4U&)aBz-_s^kT@C#6x4vt_#)ZqK3fd{((uNMQuCI_1SwLx?Et-EVQZV&a9}wWpE@u zDyK2xgZGkmSa69ua*h`?=rq+jRTHxxhvlSK7_wlcU!N?pEqQ&Cr-eAl>D0yqp7bc* za77Y7X78-sfgEDYM-r-+%VLz4?57innbZz1wz=k=Dd)Ik-`K|$R(=6>_Yw5F<&zQW z$nWylR^b~jaE+I+eJ?v7^0lZ~N3SNBI`ocVgsw>#GQ?W{eHdV#Dx-nL^|rs-_GAlfz$WM(Yd zI6A1tY!v*MlasA4H=Z<@X{ANGf-|G|46{_aHKcNXbs z)`f4PV`m=O>#oH39x+tr65!*VkeQpcX5XIcu~skVDO|>qLAy5Ipp;@lBnmRyd)%3s z(T6e1?ZIaws5^#|V6$Ka4|nH>It+*O3QNwV$3%Y9^Q(Q???v*9I^i2Y8K-=lT0Jq1 zIz%6W>>)N}qy7+LoAK9<;++wQ5J;;xu(fV6)WAqXTt?b~*~-X|!ye;Y2PYY%(UcZ- z5sn_1!swza$BuWG5KhFOGwzwGIYs+?#ze{;Por-A9#)y;6rnGl^JPu*wd>~>g$|mgQtX?8yU#;X2keod0-O*%6HOQ04w-wE zQS9T>&fB7ezXtM83(Jt2YHgeJ)ME^fQvawvYd_DzVE1+vX+@}8Foy7~96c0^ zm$fn5KbYmwQ?A^_V|H&Qqrq9-MP~jJn(K5O0_Yxin}_P=ze>c&)ZLM!DfZv@uQTF86jW z$E}vF9)oe?W^vQQ3vr&#UWVrqQQUNO%2+AyYxl+^jrc$~HgNYRONF zt>I2?ow%ub6iGziDP-3mRPp)QU5vOE>h_V%3r6aK&75lMPd>eUeA{^#hAM6o~LWa2b%giRt7T1mycN<*{92jgWKO-mR zVU;Mo(Mov3cJ#c&1w|wkXW%=~wmNO&OT1b1W1*9~OkSN_)SZ2XpOg}ssbv-r9!odB zMoZg${qar*p@D>SIiyXQm$O)9`Q5|{r+6%@W$c>TturY7Pj)Uxs}r4kd*-{k+7XjO zkY^~QYygi>&SdzaY(RsT$hy6t5hMF7Q<)R3l^KOy-$^Jr$_IAUsy9lxMHRgjtemO7 zm8YwtlliRr*^`&W_>~|+(YxU3>7bY)DsSuR@bcnhSLf%|;-Ec|YhemPpP`8v*8KSl zO`^fz+G67k(^s66%!rx*~?yoaTGw6`7s$0wQ=&}Gvt$&_!aPO}x&b9alW=TgJ%rZv5FQc~UHaw&-BFdzA6 zSyL&WIX{Nyah<(J#nMZrV5%9Q~Q%uWK>Rr zL)jEZ(-E%y`QH||J{i`n(CuC11KA(Rl&o%T6;dKrIr-F0!N!mKfIc>YRjvrhW9CwG8-uw1ZW=&tHF(2D7-Xm)QDz;98ez$y`l=etNv)aN>s(r0S-HRlH779XrF7 zDcyJj`w3Se+Q0{5s3H@3A<=Np`Pgb9=sp%MqPo295RRb8sxP(Oh%w;WEY=K5iydZXN8 z*X%E%t?l>Ed<5@~X5dEf9w84fSNMPec?`rHrOR0G&SFVSW7tX(e9D>kr6?nHs@k&( z%Vke43YyQdKX}${J&|tFx>1NHCiDTC7|r;=Bk2**mHqE=-3~m+0t#Djgg$BV0yn5s zpvWbM48h->9>5LTEFkB}0jPMBH;MO@VT{YmLy)J94{#oC`3?7nE6;>k-`Z-3qmM9f z<2%gB6lTcxVq6MB^)!n*Z1JwPE&>)IT0puUG{Bg*KMD8VQQl(vEtB%$H0Kmf_v}~2 zmU|jFdV*OWVIp(8=#C8C-wqUKyr$R{ukvtXQy1ncLV71>yCCL*TNH}joOnK7bh{g3 z;RYPhE#cW~$U|IK`50RC^jeY%c>UB3KEbM*)&yc**OH9h0=2ob7Vs7IdHpPrM30X&ExamR`kerx)V}6(G^~E?lwC2_uel=Db1Jn zPG1Sf5T!yWI+fF=1~T}?zC!k{WE6nO#cW?PwD>l-RbFvk5GdLAeo{?wJ-Ni*|Q zGEZ2;moha}3m<`@dUm2=vxabbGx%-w0}bBQk|9&1Vmg>gG~?QGc6sj{OP?7|WLV&) z!(qiAmZL{G@tCoz>@T*n`Get?>)P9w^yOKv8Sk0InP#>zcmRxUbl$N~6BJ?IZD?&C z*6Fc5#juUU5$pD$<1RoniffUYHoBpO*y2e=@;b@EuD&<4X4QJUh-{<_Rto(6 zyT9i$qOWT|qm$xwiBfqIcLq_G7?}oXd*z}tV~z%0py&-@&UI(?&iiQj?lK2>(RDjG@*s|(4$Yp?SP70gV>U4ovy0}irzj|1 zu0{6f?dmBWZ<6Tbo!U|m)JdJ95IE(-Q@Z7Cfq{n~pPzfbFX_*aL7`X<3RI`5KNyzq zRc{hvYg%_L2EPC^dbN3-9jGUFcOAZ!-JbtJY3tbiKGij*sIh zF~h-p8Yxx;9X0)4u(+ru!c~Rp71o=EL~Bi(B8#sUAzw{NpGvdnu6df@6ZGoda_sUA zv%nw$7Nl|mR(>CdWoEa*U^aSk71H2+nedZeXOpL|kh<%Hxyi$Jvqir5#Ot|9tE$B6EuEY93$ z8S}9eGP?KdjTS{5Z7bc)2u-^9rP8w$ZkwH$v{&^&PnNp7B=-0^nx_EsG2+tdvfEltE9>~g7E>H=LK)S0HPSzCxWgNJoDm=YnSB3CW{#tGh7?ouesR#I8EthD z@8wFYLcC(P_C`iaQQ71{uMmH3UUl%$?CYXg)(TOEF&Fw?vIMcWGmc&@xzEjZ>Mcf} z`4&xQghpTjFEfA7a!`A&7@1RAk!4@jq^I$+bdPv4S7C(F0U-3)yW>>P&`%}8$KAq z+7u;}#f*~zbtsntqUL6&iVOW#%fHsCgC2DC2hcpw)(98IDjPG9bi?wOj(y-6I)*3Q zX{c~&r1+Y9;veMe44vBWJTF5fw%p;{T5a5OoxQdXojrmrRCzwj?c?itn;IcRxH80y z1p6|N42PUjo;l!cwk}7q2j>&-J;6eig2zWt8>gg*&2Ry9YNKNfbC%e0U@82w_X*P8 zbfK#ZR?3J<`VNeC{*<$NWvZFU*pGKt=ici#Eb=y|uwB6rRzw#ZrIH99LU49vx9pQg ziFzV-Em1+myjZHBDxnv|6?!MH)?^4k^|nXPUjZjztungxtM_zL^P@c&-`-4OJqGZ0n5&0Si!)9LQT|l;Ch~LR{=&8%pW23L;l`b>Y-`pqukOuC2(6i9S1p{ zJ*ZoU!SxNe?KQjdGq+52_JiINO?A47PNeb*64U3#cX4svzV11Era95H*wqMNCH9+B zd7F1I*F#e&OdnQ&9fp@D&hBR{H`U3MrLlhF*4FKYED)$-F#i;jNRh+s@Y<&f?jI?> z&Jky-Cfwifdu7xrBF=|XAa6_-oT=`#`z{NU!PQqmpS{C*I*E=T5;(r}M2h!7Gap!& zIjTOZIKsB*=U{d-GVc2OGWA;N?$5SmGu;t!I;pedn35Mg#TB0ejxuJxKlIcK2V?Xl z7E0n=qyfxvb_g1N7Mhh4c^#RI%ZP+jCUh@Ry@vOHol8DYQt|%qNw^>U30$=%at*3P3dyOGO*^=-4q)<%0I^&!H7YVEg*C7 zw>xv4$b%kTxk)e3{g(lZ$SVvK<#vbCk8N62=j?tBqgafXOs2x?RYWODY?cfRs1VjN zK#epfMr)y@rtC{fnQx|2QSmt1b?<%aV%g1M`O!gU>L(dv$@#CGzNaep*$g*c1oq{# zJ)pR|b2#MI5L*cU@hSM52=eV8Q0ASu@0mO2mqa&V%sYRyZ%5y3nj&rHNlx>myK7AG zr}AJst`1 zGAqqkW;KH%Y&UeF1870ZjH$M*&lKjYW8&-iz=P6Bo3P9%eFL?JG`o_DOmVbr6Onk- z)81)p>|1qD@4#o%OA&HTI+RA}^Yf(3|7>FTFYpRMdi?)BEbd9%6IE!zHvc}1+sV4D0i<0%6 zgQsnRGc@5>i_9c~-Ig#)+X#A(>=y&*J8e3xCKuImAu@2t!KRBj;Cj|crg(u?5&g^P zRc6xUqx0PdhgbccjkH9ps8$~%CKVb5*>Zxz{w# z)nel~F(lyilQ4rs>J40(?cugJNEkHDoG(ff6x^fNhk=RyMt_pQjM9~8vUwCs$UQ7x ze4^R!lmtgCk+)fx9;#5qu$?)sklg9J(4jBPL^$4*{4H{6t6s#hqqII@pMkdzxU<9Y zFc`-6%YI0>v*y=oML93XclyV@UpW#QS8TtRe8n?ZJXSx<)v(eOhTP& zJ!q0*Q(JK5YN5hV%Hf_TDTbAhMOjb|V%7@R#J)SYe9i$xVm=?(2g$0C#-tzAqEZIM zhK}RgY4QZpV;GJES%&MY#&JzABi1D+PFjlO7r#xsd$?Bhb|nuHDhnZcj;pr{x)+|f zo!4kxoB44wq_(AiL;1SLw?@_VmSE;yW6xg7T=@F?)LDxbQK|hB2f-^gI%aJ{pAJ{q zYWmltn)%j}oDOhB4DU(S)F#{gC~W+gzhD6$nS3`yK({>DH@$MxtmzuAJ^-r^9?m5- z!}|)a5P#dG=|Dx7*Wb~(=;yV+SN|w|=WE^8$kXSqD8{J0!$xoqz9k-dl9i4|S?w|( zo>P{HtWD3s>&t}seW7}*BN3_76hzrT1NLwu+j--v>4-`Wml9kym~uQIfOIJ5P1UgF zu~~(ovt52nGo$<|>`thiJkG8vVTnXTVayfAlN|h0EuF6zJF&MbH6N58En704m!8@q z^31H{MyoLN?;(!EI~$|DKNPW}%N=t+sE@QxKQvn=y-7+MW!a?fv^5lsfugfWv67h3 zx9}$CE%a*JN73ZmINEA?N5Huqmp)HkE>I4)j@th&7hjuC!9h{bC9pRsO-aN%?W5ZH zk%WUi7bzYIS`pR_y#ZVF+*ZvXYK`m)xAm@g%t-} z-}F6~3h?W2?k#c>ge(dv9)C7gMb^4j zGIV&GIFVH}`|`0J?yyZwr{N+4)r1njoaubo%h@^#6G4;Cy}g1aSZqZ{8!-jrqK3-3 zD#mrSM5_S@zsYkmGF22aY}T2h@5lW>N572~E`GLAEi`07pm*_%_vN1AQ0I5^?kNj? z;SG+~4SRZ0{3S#up6MK2#7=8}SUfC+4+ohIN}{f5?7= zWr^-RHj{b# zbsICcIHGT3 zIHbk4fO|>A#3q9f-ezO=WpJ@EQvws>L4U{HMMKoHO*4sT*AYw|toq4h!1O+eRO2{P zQkUGbV9{ubLW3v0Yu*)%EEt;JcZ5tLXfZ^;Pu<#VWgBN2ej@A#=j0+P)>*#-3>=9^ zHHRE}Y?eQ;Vq=qM7PV~iZsUMSnbpqIFC8XTIVS9i;5XtW2b5e@O-KJWNI$J{>L!A|r*d(8IIPx+xZ=Hho@i)f4+q{QK+!Ga{( z+d|!@>!43VGF+=-%tXv<{A11m>)L|e%koi?dWFv#lThktUOqEh^7)M+wT&M^>m4y4 zk6gtVId0WECKdZ!;l-OLH?D>iG_y@io_iN`rBC(*Jbtb;>&iLa`^^zH&yW3QeOa-Y4~ao=|M=9;VQ3%&9b+ ztNQcOafR>gFq2i6>RoRvG}FuX9#&}%ph}phK9RRvG|7o*YaKeedWxa)IY1x2d&IK= z{UG7_!SSVo4LzmDBRm960&N}_Ea_i-K8P1HkCH1IT9M%crb$F>`eH9>NW2IqNpR`D zhgoD>U_Zfy`2Z4iZ*`(UJ+4~HJ4`7r9+E3r(|fV93|x$SJlULS9JwTZF5-k;S9(Hk zQ*sLHk&~Bwaq(PAc&NuQA^HSoCz+K75*XR66!11Q9zQYXszhhE(kvnmmNYUJN270- zzzJH^jo*2amBRF2z2et;Q29AhPql%VbQW&#J z=C(Bdk$3Y#j+3S6#wOifid#=>RE@fS9{P^NTg|j90PZ#%scJo%$k}C0Z*7cLm~BB^E~N=14L%mYc$wsSofNx4_qJbUv_c zc zfqyxXf~&_pT$qUCbwIR1!DWoOmhJb`aWfam$R8FW@Ne`RaSo6hk^f z=VGHJ#j~#+cO;rh8@i^8)ZpJxdjyn9F6SP*wrHnYbK8FGW zgm=Ia1LsqDPSKGW%CA%y?tYmLZv9Ulhm)cOk<)|RMaky9TBAbTcXvBf4G7x`LSAL0 zd9Nx&;~Fnu*G%h@#!zax%mxzw+Gob3fO8UDvY$cm5?Hze;2sAN0XvMmem?p#alS z5f7t5AA;)GyhCk9@WEWycV3%t$#vl-J(JFbuf0fr*HB+S*^a~?Vm-*9T`H9ysb^qI zuzWfAOIN}(7peXZSHGi9SI-Q(>Z+X(%X5gbb59#H(exa&C^0X)=zW@;>UOI8T)eG0 z^$E)L>09pgsri1K(DUr;$8s+in~0mO9Lch5LLhMUJRF?J#xBBVr`VGDm@C`&L(l*4 zdp&5VJ2F!D*U^asZq#k-R)A(5{swK#@y7H5wea^PwBRp+v3IWtee4$&95~G#_LL~1 zf0Ex%J-k8Pjanly*lsNAuPO!a>uXwkp)e+Lz#<9Uu@Mt2? z2509@B}J9L3KvFUr)=XVn5>uyof40_WY|Hkbjd~)>F}%qL}OS!MIpJ@9TVt*(8xF< z=J4aPB2s^uKF;x)4{fPi8=wYfukd}T_@;*=L4(ub7lFR-p=N7f52;+wZkpI?7H7(s z@$iH_^KvQ!DsFgf)y`56t@soU@={YRp}D4M0KX{j{%(|)xiDdul}^6*)7fxpLeM_%ks&BtPV$wGIsl7>BA8G&>X!8o_Y5fZ#ZKPZ#z=R zlh$wMCG%Cd25j6Lv>o{H5?9z`3LK3+#`R+WeH6aLG=YeuEmGN6G^hvn2c9C*B;j%dR)x(YG;T-t09FNZMQvf->j#tjTQh|${ z=4A&!_VGVsYt8Y%X5<|^85S23^i(rR6fHAYvG;i(84#(jFY-=WkKf9#Zltgu``$m5>u1tn`K?)Um$ZGP`K8L%;H6d8h=Nf(PnZ641M!J)hTjFS1VEjb1H=TbACqd- z1kikX4g1=O2hb7|*;4D&$V|bf>l|Dy@J2_4&$nPOitXo_0HQSLnz>>ee2-7bOpK!U zHrx0427WIh-Whe&!;hHL7xXi|`qvjjl^1Z~RK+Sf@jZ@?fOL8y!zIwLfn~H5=Q2uY zX3>nP6@jCh=ZqgWJ$`5~kSgNXBi}^7pE5Q_^=v>WHbzg%d=Id3oMYpZ=Xmmnb;|Y_ z0qZ9OYr(qIQ5_vk1361!Eq^Oha$&fh4Ta>I-#T@DK}J*&7XmEN)b?@h94{~pyMzlZ zW=pmm5&zSXTKS&uQaXE2Z;= zlyRzJMdQ4`t$W3&XX7Fvo!C2HnE8zbr^u7^rI}j5ffj6Iv>wx{9m)W3I_LqeG0^m2 zTQ?eJ0qi+Wy8zt>+uL6Qjo zG3qI-WxN#UOSCHFz0p5phknR5n_P*uwRM9LN0zL)s_%mJeHtMN>+^X;MrYj)n`e`! zHO5T#O}{8VQCFYYUs2XRFEZG@VAEfR1d5u>r8cc0Ma%*qfpX^#5TA>$_HT@2QRL=Jl3tv+1L7pyQAYGeAXXVK(pGRaZRIEcsBa{vKvaPmdA>HPGvD!M8B;XQD;Wmo}T{ z-dgkewM2|s3nVb8l!Ge`!4I(Lv*hx!r5boxjp;o68TJ@jlp)h9seg`{HuxTVOjC--ue`O863QpqQyzet8Q)y3_56`$TySVu%It`NslgTg`_ zi5r`a%i*#N;Cz-OUAL)tBqfNI9wjr0o)5r^5TriwQ*r^Ycj((wqdm;6m7c!E<8jAJsIXPegTJ4uJch=_6bOVP z*s}mmUERC+OxGP#foU}iS7l4uH8NpO;nocIB)ayZQmurHQH+1*=za%3}-EPsDDZgdBE0m?l}?5{g`0+Zx-@(DguY&au1r zqQ`*Y(e5-T`)acYFoyy7rb8SkY2``4|4G5LL0Nt5Qm!+nw2zKEwutcoSRXO%;5jM< z?q2gt;A+gLtqlGiz<{BnYlXnSYNB?&1Li>p|;k{n`SWwE^L9ca;26n+D z!a00qWG?Iy=fYf$aKEl>S?dJs8Q~P~O--<_RiFa@3=`QtraoDbSFmt8Z?3YBRvbuI z8mCar>hN{X$ky7&;x>}B za!_T@`dNHxVv*6q{_&2gVPin~KaERo^xEX{W*kOw>BQljhZ}S3lhpv$^P;$qHL~Q$ z9_9M8)*YPcsM*{pzI$su)wZ0V8cIiSm)%{yVOmY_I>GD3x-ib4bLGWXS-q3sgA}e) z!${4kpF6-e`h9dS`33<}`zpaPci$2_7m9kRMkQm{h5TA1e1Pv#blFTR%-3VI?sZcR zhaouuiR24VT%jGROi4mF1{b=of>(QZ>=A@iAtQM%QQ7y0$3qW1>~ukzzx zdxhH2g>j00j!{#>#GRj0DG7JB zr)tBLFA4vxe%T^U0f!UyL#y}k-h`h(3k?(YEy6{b4a!kHQzNmu%FHX~OiMP-6j=DG zfW=7HUNHJD!>6{^A)nIb6}7(T`_NfwA4L{w8oh8RW&Fo<#g}f1cS;kPXzB=W+?IFN zvJDzB97=C#9N!LO4aHBuC>gAHfWZ&mhkXRzqfsyd(LGBWO_D{Mv#ZaS(y)=|bL0nW z7Vj`+aZfbDlvs=HdfSVp(4(}pK&A4kl0}Nderi? zxCAv{N9!aLGQq37j7~4pV8@&3M$i0oa^6>to)Qrr|BgqJdQ5%GiErbct%hjZ$v zrhHl7byd&1zonf3VG7a(USR{>6DuglR?j*-Fx0DQ^j^UwifJFL#o?EL@(-RbtQiXa ziD=De|0Pfn(_*^B1-?D~OJMXlK$tlk{>_cda^Stez#|E2Z?(IXn=@ttz+iqau?o91 zJBj=Tod7-M>Ts0!ANBtL_IHr)Aev3n8&v!x_5*R}0!6=$3AJGByz$ny0UQ#nDjA;% zYC|=pD^gAl-ui09>ZX)-Nt?CtF-NEKr3#i!X&Xb!BjI)HaBR;l?kP6l$dIUS8^M=C zTQHDIUojp)5_z)9_Gp#UV}Kt8fW%cynT@Aze+9A@cpu8N{gBzjRbGZXLwbB(`eaOC zmK56RCojvir8ebioO|8$J=>rV9nYm?L|AwT_Ytp(Jr8W&Cwb5Hck(|$>uh7u$_&H@ zhuPR>g9!*FVhT9G%V-K5gAv{cL(=>-l zoyGd>xD{snPlV(FVEIAd?ocQw>l33OCJz03RTP?HrLx0RD@qteljDgh+h*%p+wKDk z(jL)V>*D!@%zVo3%%W|Ztdj4sn(%!K$=PsY`&$|I1A&zw5HMIUFheh+9jCxj-q@-n zdP?38v^MX3IM__>DcJE^nNK+6+x!tQBHo5vgtr;UYG27Wq~tFaof&9`7x*x3Bf0c* zrafi~yI6l40PWZ>Aa+gQKr%|;V1CYr8-lZ4?a-&;r+G!q)}ai%udA)qnC@O!=r$$+(sfhuqCdhJi7$YQ*h&|i3trmeO zq`dp2yLu|j=;ol)ZNRMrxtAOqin2Mk>~?A2r31%RllT20uv`pOcPX}JL1y6s7$}ip z0S0>!L40*~R=Y#*OrGmoPr^lBdPSg@hVk`~!E`ZCXpKThA|c%{FMpT6e-U8M607Mb zjCg#eGG}I2ND7I^S$C&3zBYdDZZ9Wx)Oc!vQ3N(pv)kaeGl`VfXDVT$(9)@kUR|O~ z9*P^+ownpH@8?>#w!uFVuQ`oEJ_69Hx^9oCqez7H8OieKJR5vSZGp9Ua@3J`MJGd? zetc3coIbo9uETC(5!gu;i`#^viC%;QJD4^~hgl2)%jRAbtetQ?{@Q?yRb%q@M&yWA zwF{g&?qaMt#L5dgo*8`S&}f%ek)xfR0|qs%znd{54*5W`Gc+ z_QdGg zoMd(`=+0vekQn-MXpajnOrCN*Q=Mljqm94s*EWoE zsc~}z#j$Rbz}5jA27TkR|7)1=&+lXCaAggt)C7`71T!?*o?2;u$R@YhP(>y^s z(tYkV+3R7r$9C2SGVAr})V@saVA1Esl2H35$AT1F{)-JWwA6;jS`tS(yaS3SM)QTj zM}MPmPzrRy{8esvFZDqNPew1ld2-3Ec>EC>7;KYu2Z+@tXbAi41nm3yF8;pnKwjElQah-7 zyc|FzQ}Ae4SLWsi5vz&9CK^&?tRfC8)*Q%4YnGAh62Y{G)J3WEdT@mSt8mLz%am{#Ft5yB>QaiiQA3M*NVqytsD|?19BJiH?ytv8qu{chFS|= z>I>z_&$(!S4KTX`pulS!2s(_h(gls)Ux2>Fj-N7fG;3ia85s`jz{x~MBc^23y}&Vt zwHw15U>SCu^?-(+jCpm#*9~EXdb1NNwgQ8^D9l6@@jV<6xPhW!97K4pix9hnW6RDY zSu^{(u##-*%?2hI5D*DILtiRoS6ebzxfN`Wb}>|tZAROX?G9`dz#9|p;YnJz4BXo= z(`T*fkV6A@tac>;kK!4)3c?i!^M!3Wn(WfnDKlP1vz{MQc@nu~KPACL#_0Z~2?tzG zCL4$FNinen-`EkB%!e^R)~~jzti-oqJ2UlTwVrBH#TKIU+-Z2UBj?}{X5u~k zC~+bi3nIEgLE&8(;guRtJhd7esV_E9tTULUOVVVZ0v#M36qU9T!`06uG%#*YekYtN zYWLJXii+Ti_THX?<$0<;=1zaRZxi=aNB?~q9%9nMikxv`XZIhflkQV5J>85bat_%JYC zSQ+ju_IKF?X?Wy@td1oE#CrIGMioZc%xDg-Z>=mz+sjccPy4;A#UIud5M1B$4^8mD zjv(>B*>(F5oQ=lw?kW25RwGkyIku?VHB+Qr1e@{9w@`51~R>vPBWpGv%3%gn>#xw#kG1`RN)a-qq5=`nWmhHDG21 zdXX?k^}+UN^0BK^8FcFqTW z;u^T_cwy)Cyh3J+P?z*0tTW~F1FA^9mZ-LWnkG!Ml&&H4x? z0-9+T2g>qn)kxFUN}VF7EZGSkp%X8m3=15kkroK1tg&8YwKi%pwUXH`;6vVW+5~dN zN1H>VC`VGAH1v^*@Ay@j!U68p$KP#i9=}AlR5JWKVWP){0HRdQYO}68YNBLyvS4>I z`bBPJ_A%)Y!v%>use#7xQX$s*ud!Ef0`5;qVY1C25>rk;ZJ%Wk)~1b2qo4|Q&v#MW z{NG6>i4LZEHTZ|3g=UlQr-n)&W!_Uc) z%NX3WlQ#JT^$196=8AFz`CY_=^tW}4x}|wWy3}!s7{`X;5?`$jg^~RSVpV1N5T|! zA5Oh?Vm8AjV_Z$5YsEq0s7;o^m%n zZ+@8ZN8C{j-noJ9qc8j;<1WZsU)_oodUGJzFB!3TJY!;len3v_$af5O`K4HV;y>Y-~g3GTiJOMnPLa5sTAC zSl-^6L?sKh7deUTDzPP>GHQcw!P_oc!e=1g>AwVKBcYq~P|A;G`Q8p6!d zVcdi8nZ1-B8&AYHVnO^K)9<9Md%oRcoZ9>UZj}x=|S1`!U8Fd6LH_q zttOM3$I`QJrtmkf(9b0uL0_ZAT;WJQW0RDk_IC!jKAyb31~NPs)0TZqUq4%GHkHVp^FZ5RieiswN{@?H_JRf+?n?fo`@aIPLa zbH535wwI8kFFy0^fzw6ZBT9J>(ogPqIdz8K^KjaT0u%O-6|;M|QtGh**&E&uDM0Qs z%$A%yj7r*Jem3%qlTpevd-`LoWoLg;Wnx*;{)EKB;F~Fl!|CcG8kCflDP4uMvgOR{d>n0sl0tgz`h1Xvk>eitSYNlp z;q~#v&O00T*Pf|uK1hAwvnp|V0Ac#c!}Jv|HMwrr$u25e1-_)Iy9qtoEC_sx(l#-C z&yK%AuHeECNE_hW!QM?No%)B|M>O{4Tv(opTj^pN@AhP^37=4AnT`vg5mTE{@5<_n z6w5n<%}!~VieEf=^s=Vxf{OW0i1_{s1`ZeI%sP}iMILnU%#cDD56Hm7bfK7-W7eR3 z&3}D9K|4?p5$sgzrqrK06_sw0QmgW~K?en}0sM z7b}ZCmz&VXHd@d>!3c*N+GW0q0oC95k|RZ19ATxQLJCa2rB5v>9wqlw*+>6b?UzaF ze4RhfC(LUPzrcA7I}l>ud2JIiN*o-i^V`o}1tY@%Pk|sY7$OJ}=&MlK=j*>aRzuv7 zeypmo@vNl?=E~Rh8|~yMA3bmDdGoWcl`LO-U$%ICGf!cXQuCJVOg7qDOZ+hPV9CJe zgllB`1d#3Ur))`+bAzPeJcraDN&`T<)9uvFq6_t3&KY+a7gi*yJW{9BUQ|maUh+Kp z|IXU~Up>lkfhYTRi#`GU5iuzGLt20z1oZ}gw*{yY;{KE4<($CqR*D^wZHm_K=NR%o z4}Vf{0mDHCe;S8Y%pFpwgZR=)@7A{rU7k+|-($Onu@X(M$J}7Z!nX}SGBzkRlm5ll9?%`V+z8CmkRYqCnC@>^N0 zMXBYn6k13bYSX)e}-&EEo|MLmI79{)G#f5;2r!$>K`^fuo;%2>sr6EAd80R{uzG zk@_VNi^}MY(lR3eAYS#B+njyJw`HlA_`~;Kat{hU(~73SB#*hMrOVnBDWN_Z++d~2 z)0GORKbBu;YFZA%KKvvy%R zQaY+^ZNBlf-?S*@yQZ?tN8h3V!}@E@eQLTBm|^S_g2Jt4M+Po}d#&w8yG34(d$+G` zfn{or@&SHHVshl*ojet5?Pp3B17eXWH81#X%nAekJHLBKQu1r>FvF%asZMiSl5JeO ztJBIp{;HjK>a<2p!d4#ZUWjaX1%7a=nsJ5oomZ!?%pZUssQ?Uas0>(q>Ja~rh4>OL zsBE~_yhG}62$ZBM_Qj)$X&8}*N~fGix?W%DBjMUa;B}r7 zoa>sHKRa^kJ%OFaRN{Yy#5RZF${tjk=_VVicBas>wI?UH zLBed8(*-sCW%+48)7R{qhc+A;ApG2}6ac&a>BYeCK7+UK#XZvQ7T7|vrhW;eoaR+x zmH=tACzyA0T=fko9WyHg-i(Ly*1H8Z06N4hjgZAm;_t@-T2r~|V(PrKQ3vFk2Q7(I zZfiXd)iAg|rqf9j2!M!;FG$~Sj6+z30T92jzo(jO=J$#}6P&K7C{EqlNA#pdZ+o<^ zuulYaB}H!Q=VIP@L4|?!85RrhfNIKNH_mnydrNyf1`3R^Akulsx*ngZQPt_O+Lsx& zf9@MN?yr$!`EK`(9rN(YKJF`{C4d@qw~hlewioglQ37FRz)lN&!0%azA9ryaLko*y$Gfw&V!FLMQ{_$MMpUfOl_okpXQ^rMt2jaiR5Ig{)4pum{k9P$ z7jND#a>1WkGdF+0R+V@-J{EKs(|QtmHwVjj!Mz34V==9-0G7jM64C|VM#vmL>2J!5 zI5j|BQ;EXz;gFG^9^f4p{xr8Oh|jVaS^So^>Ag}(14@`o-m5OS822`G^9%~$H!ME_ zO=m78k*(TCjhp4n8>~0FZ;fY{zY<{!ei+8ocdE*e!A~)IG7iCWpzNv3=URGb0O7;=N4i#1bszdb=x|0?OtbnVNSr;}24=*gs0QrEZxKWgJ`sAExhLak zfC$u~lI#&AQJ$xdan%Of}N?;C1c;=2RVGy{1dB0A8;LBLP!94K7%isf_&BJ zC>$Sux(vUgXbkQ+>N3hJ|K^;NjtSci35WI7SKu2%*X!Ue1Vm32i;FoCIx9D(zOhj* zZ<@~ESOJ^wJq)`UX)DV4#(1V{{RQ#6U4@QLW|X~Mc+n$P{+3RO`TSA^jSwBVS2y; z7UjOTw{VR^dOUP3zpjPXHvxF@A4KnDY{oT1X)9uEY6p>#!Jf5cM^qrfp+oC*WV=@Q zA0q)gFl_KH){49yCP~M5^E;whlQY}G<(Fq~G`2J}v}Ap`M(Y&OnfE2oeb<(+16C-2 z=`iNSWCpQvBnI9gcaf?8m~%ONNPj1waD6W;MtigZW0~z4%VB1MG<|<3~Oqsc>R=piz5*T5W&9Ql&}C}pxPIi+s>ne@8<4j ztb722P%LIS%rKaFe+>-JE9D%K z8I1?jBzT$Z%M05xGuz0EVsiQA80cct-W4Qd@x319W!(Bd$c%l|`A6#6gfV|?$c#xh z>E80}u9GC_4$@Q}Q?FV1tr>HtvodEdOcGYqs#YIx{|nQhe6-~IsUQ7){?pYz9Gbp~ z%H`Pf`}<7~Z?>do`i3EK(__oaPR^riE`-uqOsncMR@3#iM~8C$+UT4AOZYGFF*cTU zj`6Hv3L=T>Y9mSl>j5?rG8J}j3TQok)feMhX0#Dx2b;|>zJu|DY5%}skC@nUICtF7cpu3o#n6=YJkj;Y4_$*EpCxU;$nD zw;!-}Ozeti2A^-h_=e)Vb50Hi;=~uoh;Rh};>Q<8E@X~3m1vVBW(tB?p1apbUY-?I zhSKM5YKjK=J|r_;74KlfFuOw)Esp=))SAJH0j{biCs!izke%GiU(2{gv}}iSYAO)< z9TQCncl&OVaq_2w3%wiBfF^U$=VV=D-QBQc*N-?+79#{@@X zs)!_F4B;GE7lQ%Ft#R1Hx>mH}WmkqK(7M1KO_J(j@O4u5xzdC$t^*__ZM(e3^7w{y z;jFAPZzyIvyqXuL*XBJ6a8%@cz{#wh^5MEVV9pf{0*3W3MrFtw;HkgFfoff1Zr3MG z(09(nUVJfpQM%{@HX^gIs?1w*y8>70O+CPsDfZSb%*FUC4h`{mKQhlbxp+$kiJAI^ zg#{{%NM?xDyw_&rX;h>TKjqVXwYL#J`kT&|ubGunU2+;9ssjc*uYffezOB{w7|!-; z2Bt!HH~PO@FJyT95_o);$moSv7lD~c#GTAyHF4sE9FG&1X7S~)f(b7lI*P&f{ftm6ren=Hx0T+kN0mV$BUexj7tSd z`IMFUszDUj6mxWR?wcrhKQ5;5Z$D^henxT&3D4tt$IASJsO||7vaE5JLEDVrvp*cT zf69b%Tr14}_T#^m4|@%B-MmWdUA#iF%L@wtfNJE3LwXj*3mNQQ?BH~n(d!lL`yjd1 z-^=gt`zt{RUCYriM^lw^ok68tsTmMQDz31Fli9HrfNu<$AFayum1sV~ytJqJ$f8iN zcY0-)uTRwz6C;r_rK-Q;Ol6DDn2HJL#CxU@X&D>a53ltCZFdrJabx*gYP;N6HMV_1 zd}AW~%E0eKfS!bt0lM;Kt{)%BNtg|F#)hkd%g>=kkbvDB119or17vl7o80piHl#?017Zhqz0LQ6%JS6Dllb-3yOf#8ZeL0?u$vpfmxW!b&51e~8-B)% zlC4kqnATGoNeAaBwlTUFIpF{nZq}?vIJ-6Kxn~#Lt%XUNjcBm3-71}3u^sNl>YK!*cLL$RB=?Q{i%0HaT9_3gjw4!JBbCXs!uW(33AMXDJ63bteEofLDqI{V!0=!H(~o;Nxt{C*(T{z z4c*EVaB%j(6Ui&(MRiSeFX%IdPmJHD?pnvtv`D_f6SHm9XzG4lh<_;@1wdJketSfb zMjAJITb7%Ga#1HqEIFBhlfw{Im359|xw)f=_I`*5zOt$|eSR9HLVxQXC7`$WAB$3u z1k-3~kpb%@9?=zH_I1Dy>S~sw9oUFHblel&Ab+nv5fs^St{6$Rj-p!hMAclz-#=JC zL$2yzu3UUzXlQ7jVibLPtbIam=>WY`)YRVdGCRU0LzY3lz9aYrPi2Z z36HKF6Muftzjb^+qwbN$9bmDJSa;MDzGghr$WhEBC^Xjp(d+N0fm7{hUp{gnGR0&@ z2jxq@y-KIk5(Ts~|FIAL-K7qj1NCAkS}Z&E)D$Le{7>dc8&!gRxyyukFJ>ak*|Nux zz|Nr2ZThSj>g*Pc;ksdc8SYhv;>L1TAaY9fFRGVz>Sl;Yb;zsKwRfm%H-lK3mHzFm4(BXv5@?~$8$s_Mn#oClmfSdwf7}>9$G}N_ z(LWtN)HOonYP>nd6WqW7OU+XbiB9Do=fPklD2rbL1IzFdnrWM^+i2_=%lMV_;qU9! z?eKd5H>d&u{WisFdOujhGav29*_pX`y}6252UvN7=*DI9Wh_hHn@fRt-td~R@uU*R zzH@)6`39QGEE?1EG6xV|#~V|R`N`?tk*M4Np8kT|xzw|Vm1zsQs$gLTJ{2(#@MC`R zJ^>7DWEWbsl&l#;#lr>X-(Al4HWZIbihQ|nF3|*S@YpiKT(`mf=5SrI*=-F=TUg%W z5Ojd}eUTQP3lJ8tq@<{joC4o67q(2>c2G>=kk4c?MdVW1ZBhJyqmBt{{I2@XtxXx| zZ1bz$aEUId&F$HCDFS8#yfmG8+x6*oQmu7MT;%aRW;StgUZ8?+M=-_rSvTIR zl!DR?i|{uu{t`f?IDNTCA2rPKZ3_MdSf+@*H+^rqY*cgj15gzHgSfu-&o8%@@D6_*Xn}w!Q2AGky!2Gy}r;JH4T?{ z7^i*}G?>5%0wG3?Kq~^ztCiwCH-3l#i4Fh@qHK+fmn%|?8Pw>2QfJ94WU+wWS9!6WUE@1qkd9k4j?Zh|^$v-LT^YZt?K=oxip5?it2 z#-*s}ZsZ>p4Dx!gd$xRx5RgO zQLVI+HVMT(n|CD+Hv%easw61+fPp_&nmvI^({0AcEGn{|8poY2S(p`R4Fo#{o>QI`c~VinRL0 zJL6LBX{##H;@P@Ehi;}s8N`%GX=_#;jT^Yh==Y2KS?v0{v?uGk|FEw-?;fr1ZCAhB z+~XG$7e?lsps+Ytm$-Mof52C~FvNOE zu-Cj`UU03WPEpAwHI=xZ*~G%4(mEp?>G4u`#6PYt!vD(eZyJ6y|!0!lBx z&o$kVVs>NZO(k1bUn$`Bn9q5A@!~D07Z)-C-^Z3QtY)k{;i~7N950h;b}AZ3kk@(X z^BL|!2X@zxYrd)asK)#uzNgv!$(skG;>dLyuwVqKD+3hS=ITYZNI30US>tIHX%lOB z*mYl*L8-Az_v}_lHd77LZl892RKIua`pUVA6-TL8caJvTQz}o(sBOQ!Xj5u!pmXVF z)(x}OZ;Q4?ME@@6(?#bITd#mEFEV5PE7LaI`pAZtBj)*naZzR4%YRX(THI^->$JVz zz|PaIaqh}07Tx*a^sBa3*t@&^$5TtlCGHmtO*#FRb*80-H@$Bb1Y5q&RUJ`yEt6qp z1rOfZqEuZdfuTyt{tCpuWy3_^g z4$OqMAYg-#OpRyzDrm8ylB-`d8Suv_O2X_*_nVasse>7;LioN3rkZcJNuaf&bfCKw zUQy|JDqYScAZa0KcX%cr%2u?@aZYB2L$qiw%~RU%%ID7w4N;3Ds5Y!`yeQJ{nWVhK)tbndp7;}+@sv*`7HXG2e^0vd} z^s-%7LW}z*kuh}-dP3hUk=N7XfZf-@L4~;PffL%#O77NGQDEF5ctkUTVOhp>QhYT$ zIW8V$Z`(CPb3~U{dk}9Fn+I_>Xsj^D zHk9ckOG`Ma2ZhlOoVUn1DPbu_>MzLfJ9s2rW=8@+U6$XM>UTu8**fI);F+|Om-9y! zY?llG0-yz3lH)`wVngkkYT3@rd<6^G1XR@f&=t2yoy5n5DXk72Z4MZOd44uUwzvFQ zUCT*?j@}hmU6v($jH}A5lV=KnZ+3L&7+?pS@aLM%t`!fb4T6UdgDmg-3jEv2cSXvV zZYC(ov*Gi4>*7qKIi3yi&@?-w*^icHGLSAA_dWrNFMpJ$bg#xG>=DUSLRUh~CFsDH zY=;JPo^g-3t)K&5TAXLP`_R5WB0kDL5057Lw`@4%vBQ2#qsz(t@qaz}r(FAcUHk9L z+y8<8?AUiesPaJmp-Tc!KsPQ;L;#Hw0KcSGZ?<9|ohPVN0p??iBsfTg>o*yXJIc-( zA=&r>s4M#k>r`&$%F>M2t*Y8Yd1beJFF!la%sUTE<+2JX`-{#!3Y8TI7EI*ty4h3p(#YPxQ1@M4hEm+{97iRl_tmH&?C}R znMJ$4icbDvG=XtJtQv6i2(cEvIAN<6fNf{bF455&el=7+@MWRr$^vbwFRmo?hv{LU z)!TOdk}_d4-DZ37t|s)(%A@{d$<`nRzwB`}W=&2}KH>OtwFmxnQWJ6!(w00dAPIP< zdHe#(!YC(o>Oy0)QTxUpKco?v;$L3h&8qfGbx0l<{yN0on8Yc=7d3p9aa&@H4SIF; zGs}GJ-R$8-XINnWy06w>1N53O>0wobu)*s_uCV=O$uWFc_O$AqQQzv-*L`QZX4s7l zg&q!pYX=OBhsqtw8Wzm+^H)ymXx_!DxJevsQ#zY))6LDhrG75CW!+(u?4Q8IMiQ$> zS}~7pU9<^oW5x<;d@q6h3YZ*HDAuOolL=>3R=chL_?X`GM#psTk9l9DU-7~@FN#^s z^Lc4wVvDqU;+v*=u`_zVg|;&rIy&E*uh2s4Rhvh3a2Vba1QOF)~`c(8Zf&%YbmHvJpLExuit{QJ>vvoEMJ!?kITJ}oHHt?VY{s~q!8}dmZ1)pnS@IQ{1KRUIu!~fBZ-47lD8X&LVvbG)F zP5xi}oh_17H(EX~1Z?pmN-r9vQ^uzaokjrdXG+}^Ps!x(laOsM>=Cf70KkwvA%AZ} zAE_Bp8GQVgU9W=NUf+InyyDT{-#)cdTgX`RWT+-WZ8J+*qld{1`!Q@9+r**JnvnAP^tPKaFjrmAQR|GV#G>&+s09 zTS_?gts1tyMG2?$iI5 z`Z)cs7k|mps?>GX(i^NbR?W2otj+!`RroI zwquhp%w-B_5aye)791DZxw(LD#Dg zQd5<~uIy3z^tJQu%S>gH@Qq^<+NsP7-%TVuUC&~lQ>%-X6gihLtyj5z2#zKH2jK)$ zEuJyV<5MSaF+v0L+CY;Asu5v1Kwob;Rl`K7fACiwye4-6K&m^^x3~M#o$o?Kp|l22 zG}>s&-2Y0V?)7wK;p74-+5_v0UvvIUQZ9*!I@(bX(Mrlx-;`Ivr}&55)&rE9SJ8L2 zt=R_aP+A;+SD55Ebe3%Aw|h=nqRjH*yGMPBG;@Ve*S`=TM@R6Ja*FYJ+E#%|H$F^1 z*d|El#q|t30q)aOfVz7C=v`#BIT$_WOS4T47#UF-!tS*L>&^$;hT8`I*s0ui`iVmF zGHc2+d6mCv8b3N8;pE~3^ONtU4qrUz7(v^!A{5f0O(y0JTokwe8>CnwC% zVn}UP$$3#E!}KGOic51AMaHKfe_3~8NJVS7Tz$*47Dxu!y#o7mK}cwJ1^0GohlADP zD(^4lzy3bw`Cn={r4tl9M>STaUSL+R-lAR}45hO9-`S zi9fNhtL#bv#q@m4q?8)1t{!%H{zY@Od9raC#ks6-wU2=j=O=BQlx%ERIbg1<*8$8~ z6M`(~*a__djn~#FtNS+*4Tk!CqGpPxIru-vUsk}~3)4K}$fi}yPF&c-;mzTo`+80DITve_XU6Gj zRRWQn(2_V)8ReqIopRB&|~)vp!r(;Cu(J&G?gx4E6rZi$x~LPx_U|h?@VQ5XC_)9%lse00woCC)v&D0b6c{?^=rl)d?--FLui1H_6v#Zx5) ziTczbezZ-}K!V*Ox}@V=BPo<dsG0;jKb zaqcR^-WAP$N$UVQ59L$hBUaF;TA*{Z;wibFMPWHozPrPvw|N3A=|jjbS|XMjs7nOvq+V>u7V z#PXLw7fEjD2JMy6RF{c1)k)oUwYqNX-H3bnOm@hFrpR2yu#4V?CO!Scmskc~*U2x@ zK53v2wmWoc30@uucwd)bK7T5xW2kOtSK&-fmv($Y_ME^CsfyVSx64oV#m8_v;J*ZR zXsmIUjOH^tD=vvZX|U4qC_vjixHf)kl7iCUDLMWU@J(CcIlxdRAuAD6^2 z;=duT0 z1)3zlaUf8-;4gu{Ab=E%$iE3@)HVa%?n_3%ywC&w`n(u8L=b3^U(o~<(o~?m;|bl~ zfnfumR^R+D*GL3yOX0XD0A@i1=MrF33*1X9@cU_kTvePT<|_c#GeBklOGyd(FFy~a zfcTH#d=U({_&<3zBz`mkXdDqaxAp-WU0eqYW1{X$jP}dJ*xVwNj5K7tz2d}Hc z*}&kVf~c=ko8qCj9ST9e`oy0`b>|1RR+D&0G1`JN~y*;r}1+Kb_V8^Z7+r z%UUxW;Cu{bQ*#S<69P<`Bfu20Co+W1fhi-6S>Qo`N9V3m4ls|tN(1wgy7hZv{r;A9 zAFsiSI{Xm`Ch|Ox^rl+?#euu6I^dvsVx?$Bb&&Qkoa7_ zJj?9D@^(^X5`6W+wbgyltyjEt$o4DU-X>g$R~QtK+u8N3ZB_n<*fHh7V|WKf_~IB= z+rQ5}Tqn5>on+$HUhFmz z_B#RnwZI?5tnVcw7&pyxdO~;^ z)8v`PqW>7(@P+?*k!SzqZh%A#BsJ=`Q2j4~I#r!*``<5BzX8j49NqYD?7eAJQ(4z8 zibW}lJ(%H~Rm#8R+2&f218x@t#5EYOBAyJe@5K$B;L5PYF5kf>dX(N3p z0z!aD5JD1>Hj>bU4Qc8wwW{9td(XY!IpdCd$2ez<`sI+Fz4zK{%{Av-vw5BiJtgMe zAGPq3?j^$T4rW;U98etJ$EgSc1z-?=Nc{>{z;(F%eK%o#1b@5oLQ*qRX5pm2SRkpk zj3qSm^ZkX4%zNVkFAIW>3hJX=g(wLw`Gp`#1q3#C!V@t^<;N*zgk&vHu>^EFHNo|_ zd6@%vz7UZe7Df0VL&1G`jR#x)Vdkv3jm`(BX_xar&F#FucoL`_^toby85Y(Ko@K)Y zJkuGM=jUHN`Mi!WyGO`d5FdZ~et@}xN%kOoHCc=jgLnK;-&Dymf1tkqUS6OOjqaSS z)WWTzX4z475YA{^+3ZIveqb{xwr4Po)NeQe4E)b$*CAozi_K_cr z=LdT$SfEYV;5RA|eqj9eyTSz{B!ZoW4OsUgUtq=rVz*k|4tn`Y6t%RD2(79ZoQ?Ws z&GdkEEFlal0cYiRLm&WvujHH611i`q+wYS*)+mtB*%lEPB&kb2^Pigg#Gh6JDXJhu zf1!Q8QrPMu$*rZ1OoO_kKcuu~|1y^a!2BwGGruPRfYF$T#2SSx@L$Ym-Mz52E*AjO z)N;#fUN9Ds+4cWb<*!Iz0=h#5S9>!>SXmfsw-ZM{rO%uJbCbM7j6C+&{Qqq}|D|Y> zsHG^e6jh}9mu-g)eVh4@b6rc~gpA*RrGD{UIKy3vexEV09M~@6xIO+1c(+fphPwCD zF+#lfzJqyP&XfjS^eBZ1Yo;u2GzZ<(i(lak^z=6y-#LHduaEneZ-M-`Eukz(0W*vI z?p!qfkIu!v_RfE7@Rwq){l|!?WP3Q}V}4<@ELi8O>dfZ^|6CxY0e?u%3q|>PzCRG7 z6}JF+c||h&4otKactAg^fXX*D%8f`WYO>;U)Fb7ptf73v%m|eCSK)0myxCv@cfnOX z8%`7dAvON|Mb(`<+o_Xp(+mU#3DmJGNXT&<5cNbnmRSRD)}Y+B{X?pf01OwWREjx; zQY3u%OyCiL0)ytI;2-OD09yh!B@0RVLyA8kg)IKYEo5~M_!|UAa8HjE0kj!N;xvHI zB>{2l*5^`^X1=RVA$%9rG?7Ps5w)(NE_@^iRC_- z|2nK|uzv>eV}bseiN8ekpPBe)CjQYA|7gsAY{&nfR#aYVYi<9PIsugxx;TL&34J8p zX{h3bH`DUCQ~bC@pB_rDDj+J0RkiBw!>orok5{~o+R`K)rjSS)un7!%F{yk!U8t0L zCj82ls89tWJ^^r$wv3>&ilC*S2y>P9BQ)MXb&zy?sCVn zHRRnNDPFWt^gLwHV(?K`pbeOM{BTya;wn(tH7U%BSmWyM<;0r4i94QC%T12gDy_Cf z8wJ)Pk8eK%kDil82LinE#+Nq6#OH5GUuHDB^z4c8;7o;67~bTlIvOf+)8EV6I~Rb6hfa zYWSS;=6p##-&g)Twru{!sNC3{iT&bkFr*qf*F2&-9MLzDex)&7BZgz-qI~x$` zDKmF78_ri)rV-ctbQ|Z^Jvj@@+!xPx?0X|4ybPru{ZhOPZ7ng6J=K4KLv3olE zismD7C@?GAQI#5SB-btYh*Mb5S1#kLz1I+ryc?u}mDtfi0;cXZpK=-^V>ABY@vVjsaJ;&DZXmV@NIt z8)96Q`Y+G??LU7cMK}XBO5&15?9HZD$oFFLohuoRvaS*A^R`8v`NyRl|1Uq@M;NrYlu!-4#~7y}H4 z7YE855z5reMzf-v-3~KTmBfA3F1=GeA?a?#eMlvKV8g|nrrYGcr{g2x0=Jc&I`27l z86hNXZf@KQ*6$O?DJOPSXQua#XuCf+S=sZ46h#t8I3n4(WXMmQ z3w#5zG^pY^)`lI{81woA9_|?^P^wUNy^2t}Rfwrs^L!9xH)|Bf92 zo;~aytqm=5gdU_LG6%kv^Ey(0=@_K&`~m{bj|p%i$veHxZ=84y_zht5p6u9-tq)mz zsEQwJR%ohiv(ZJqz=7-zRlO8{m9+BpcU$<}<39F}OBRmN=OoqDlVZyV;%DK4O9jo| zX`J-MKwxr9h<$SdaIZ>0?5uf}l&`=9oXbLhqy``TeuN?TU`r%%j-m=f=650d`?CE% zm;afTe@V+f;_%Ndk@-g){@Diqdv1eeP%@H7ctg#_S2~e8=a5F9lQGS}JM}JEdsrYs zEoLZwICktO^|*0KM6mmD&t8B1`Csc6HGSgm$Ew%lJj<~zygz&FJ}Lomq;D&)GZwJQ zj-IIFStqfRP%Yk@`f84o0~pL(2yOSytvM#iI8@#aD}NRdKBi(>xbBpHn#)_YqRh4S zbpm0%(-JavuL^Fz?$Bb^(Q;E4jpfz~OMpS6}9yzLW0t*y4vdVF|^+GOyP2W0Mm zSe=gI6Ju~D1@8V!bik;zradokDJ}Vlr`_de*c|u1c~gVtp4o{+3-8SpWuBRuCHB)- zhDa*d(0Tn$?@QcH=HJRs?Gn5wJ7T!mrEpX3c9Ttdt1Y!xt$T2~(yzYdk$nD+)J-pt zI@fVN9l=8;?_S~7stOIZy?=2;acAnT%lW^|XuThdD5<)F7rZJjPfAPt3P7bGpC-vq zeB+#9rt(Ksw2k9{R`wHFLxwe#RNQ1%9!Dr%&b^WJd?ZD-!0w)9(mc7Wx3m~GqFZ1{ z&M?cS!A?BzF}2AE$=xs*a3Agdb$8;ch^^$1-an+OiUAbqs*@5*;*z&_aP_A4o7#L_hz1A-N!&fP&UV`F1XWjH%T-6iC2u zNFu+biu8HV=_~X9_V;BH31L|K@8_&Kl}Hlf6PJWHXO=e2kGK9I<^AK$atVdgdgiF0 zA>vb*uFrJvcm-wBrniPl5&cr;)jt?W!^}u(1Tcdqo!*ZK^J9MwYh8hPn*)8If;4uc zZG-UB5_)o}YaVpa13ptd*Q;Ufa|0qO#qvhmSTLOg7e^q-BVxkv!5tklv@!vAeCgMj z7Q_M~GeS}t<Vh1>pOd*R(x2c05}`971>q>E z{V~d41>F*|#Ht1)=Job=pB6PvUY-UFSqJ}m;orB!^>LV>(fF3`artT)S_OS5 z<7sYbI9fc(XVIVW8LW&8XgA^#L{k5cI6iCdL#qWcv`z}8F=ZQ!l zV9Q`y)DC3Jf9#vLnAzmNmJ#j-SR;7rzR%PDu#f&+g@79#1XTQ=yY3)(Hv@i;Y&sI; z;a}cWF<4tu?f2s;a=81S_z)rK0&f9mG1TJDJ`LwdaR}fqvr%b^o~~RPE$K zG1ZQc?2_=>pJJ8w+^Aw6dUT(x?>obl90RtDF1ho`#(kQfom)(f)tm75k^)VGC5r;o}=D zQSi9$dw_tV8Ikr+)&cP!2H#1-%dj6E#L9TSo!pu}AbEOqX#Vr)NzW_!&+`W7{TXz0 z2tJZK7NM}S>q_F6^8EQ;?b+U1gzuaKNh5Dpg6M65xu@_&@Myx-z(WH|W9EA&-E7}2 zc@GhJYkn%N6-Yh)`S*EvmXyBV|8m*i|1qVD%Zesd%qvzUbPxuQ-(Na$-`03A#lE87 z!*yZp_IJmlA(GaHB5t+8dx;yu(!PLD4=74WX4-E&RNId@UV|^wFY~~xXPz3g3nU@3 zSnbxo)DYOe{50hK#-PTTVk2|C6nz5l)VJeIBK30iuWlm9^2tYr_CU0BUY6-Q-1deI z8C}hsZMIcLioKp_f7>JEy*>E}H+Sw0Z$Q@MF7Mp1?X8{oEw4m~97E1&yvI2;S*@{a zfh)g!ZC0rdQ;kXT^wdtsIsSR?T34H8@v+L=-tm!>YtO{yn;yBdwfyvRXLMucQUq@y zE`+dhEW;!gXP(Cxch|p__i^0aA^l8HS{43b-gtTOsgM1q7>DA?WIePVtGwd+?&AHc z53d|}4JzhXJ4-M97IAXB^`mX9@#8rTS$nM&SSmYjYp7hZ8%#(z?rrPEB=D6D-(SY< zPj2ybD~o^%@#c#0EoVW)YEhoH+^uHU>@Bqc^YY%^Wf5iC0Qj?JR7bPaYo#aWQK*=( z{DYH)M(M!Y0PT*D2i2|M)3#Aw7!0kc2#i=PyArJV$p34!spIs z71EBd)vyG&pGU8E%$PxkesgZz|030|;o0UJ&F@a;sCL|>_K%);mTP(dbPIpV0Nf0O zlE9Y2>iEsgs6)wen}V|yI5pLKnl5F_?jfHjSBf=aP4slmINQj%T*|WOlS|8 zi5LqP*v=-G;DV&k%}a|y4IHiu=}+jNW_7lBDY9%WoLNE>dg*J`UH*ve#qcwHwG`cI zijqR_+1Ema^eal$v_nY~tt($+Tj!LQ@p0IJ8?U@I>kkE=9kb5flIftIt+RG;wU?>2 zeOa5k;wA;+o;;4pvlL_p=)JIs*+`AX>+qA~9yXgLn6C9bVS06o%Y)06);k;(Q_uRi zD2&m_Cr<6?N!#9?`%8CoORcOe?MgbW@$nLD1m#CLAEj32^$=q8M;QF>?(^R-(*GGd zAGzXlGTyXh&w%CSua-LV<2D%#M(dZ+5dgc*d4p2%V4Wwm5Uvvx0L2g74f3PY)lI&U zG|M;FDbs+rxN>5(I;Y81#WgNe57FXW=0Tm&vLL{h8Su&+2!=bBnTL`mG?$^Z|07MaPCBIlA9{^X8Sm2I8`5a3h z_HCu)VSAYtrkq6}+tPeLFSPuvuE=Rc79}w39w88_@?zXnb~UExx^FBM>d^)Q=pQT! zkZsm|gL*XYKI!@G@)tNM{i7rc-%p<(^?h`1i+?&zV4eUl5nXpQ#6whZcmWWM!w`y{ zU4F4@V+|LoVHF&xOAq$yqipF< zUhnp3FY?c}>@E_SYu@$0(f}Xf4Q=r~HKg0>u%mD<92Otz82bbTyBV|k;Dhwi4h`-7 zoPaak1#wws_lsUFo=^3;L)zYZd%STxJ;u#gwNaEKv$2QN%5Usz@d;Kj(#daF6B!Zm zV6(x6ym5V7Yh-QGL6&9~cc!AjYj?vCK^5C*om68PHjIYv=Ucci+-5ZTlsGNfYP^so zFV>|Gy4K8Qns+@mEji5JGUE_h^C~@^-}x1)Zg_ZpQ_inR7md}OTG@Q8TTi2Pmcdz8 z>IKu%0P1=Bs;-naadg5Z`<_q*MzWp*AtxL2NPkOv@uW#>O~tk>v%R7fXI9$?1M`oc zd7R_4ep+T_TQ<+$mSTuc%xiVl`1$U$YZ2=aHLkpN7miEembn<)X7sE3b~DJXZC5(h zWsy5KyrWCb5ea*E1Cmw8g${T+aV0Xa^JDTG>Mw{j*aAQhM&(-__xJ^8DclEHy>SoY zZU*vj+N1rsNQbW<_xuwBz(XM$cgm3mCK0A4Rck3>yZ4jaEk1aTW;=@NBJ56byTTaa z5WNHXVqJ=$j%!fe<=s|o(@RwOLkdHc$LaI{ygT)8w7qNq4+Uy8wOb5g%L(#E@P1Om z5P}y|R?*PDMlXZz-GkUHI`=w(AU*D_(k((^@*#6a{;8PK!LSouW!q2RpDB z8x%s=2wAmMS-5zs^TT4llI*HY4Y>H0yS9oClB(9YzjMJ25l!lZczArJ#sHu21(yV> zESH~#3OEL9yhT?bB&df1{$MK~BQSr(H-7Sj(rO?pI>b9kT^E{VVnf&DeWkD+SK~X4 ztMIvOZsgHdJ>2PKJF(Gf<>e)xyxM#PfzZ?)^xVMAbcINXGG?S$K`;)V7AdF-%EW~@ zxbPUh-pu3;GP=%!UZ;wkZs}w6C8-fxVXJXF;skf=`fA{$i3Q@yn&T|BfXG0mtkp22 zjkfl(YE7e?*?)OXJy${FWSEBKO$T)rr7>Szje?8Ton+I(j`VfSdM&vbk-RU|6h#dR z&*FQsHN}qr3?)3CSqi@`+APyZP1uF|wHq)!N#Net8#a7g_D1L}U+Ep_9#!StpIF*u z2bX)xa)eI^x`rmIjB3gmvFXn|1C@3~rMaAvq1YFdUA3P|6`~|6f=y>Bx!k^YU)x-` zp^-YZ^h^(;6sYmsV#vG&kd9oNVYdk{VXcI9UK2w*Gg-_A6obeb>?n>5wxAmiS?~l& zEJ9M1rm|U5>)O(N z4$#-cCip69K$Ne*0zwP*u+yA{ma9-83l)!8*R3QpNIh{i&R6c;$I+?71QQcIWu zhmW5}Au>O*acKQ(IvKIs+aK^mTPU))$a?qK`-P}O=*Q4{ju($x_XH4C$z$C@92F)q zWMV_m#vD)?cQe_ctEnpHUHc`NzaDbf3$I4^h*~&|Jb^qW%$}Y+uw2H`igI@j_NvZF9 zNCu86(qjkq)aPV-f$bvM*E{EP)qpfXXt@&}CQ@FMf2+<+1l74$?^v77Puf^iOJqfH z@5)@5QB5D~i22}fWjey-p+4(>k2WTjUfD&bxc~SQ!udtH@axv*Ik6+u)u|71j-WT> zicJO3Bk#R(?%k=4`1`LjWakRzW#fN)uWX7XRatVDyXki5WZ#dWz)}Oqb;4W4QAj6= zVQ?FDnEJctJuXC@RrdSr1L$pfaxYAmRq5x9xEEmR*cVZbAW@p6|NSd|JnhWC-)j0@ zNvHxZ0LgJy-i{h7tGWB<;C_rF^UDztGx|pqHTL^Q^!#|~zu);|LT-E??2pGAT|y5{ z2jZXnn77?3V|7XS-hJbN0cXvxEz>aV#Dx^9K6o}?M((;Q8zlT{`+ZDC$FC&K*NW~{ zXhz}KZ*&fKYklVJR1b{IK8d&!tubLzSTN zzuz1E=lUOv**fs)r@PAy86Q`ce_s#c_cgy0OUYSxa}#{hwtQjpb3ORPp~KCZMRb@VVtcZ*wS-&wBjR(=G7)Dby7zDM7>&%% zUX`0g^fDeNbSx1+EQN{8#RNH2T6^^pI&_?NH7fMy2dFmk64i-^k*snOp2B}bt^!Qk zl$*q#s23bJ>Bn8>E5GqxpXtCG!1}NR1>$NBQW3YGkGVNFY(!9nB9D9R95lL z2qMm%OMJV2xreYs+&_1QS5fb+$LqX}oo#+Z+<2@0(vWXL=$=i+{*PELFx`f8i$OkK z7D~tCbDZRMVC3RoRQmN$jIz2(uXdK9n+}Yy%m_LIsqU*h?rO^$Ss*!4Rm<@>frLh%L9a|Tb-ygAfll@>J<#a z9zhU@?+Qkj0PPWD5GB;7(`4y7}EC0CJOVc(Q7YR!b3YkaXa+`S2u!G){@1oQOHs zi?d@hZ&KIP*t6A6*y*e>EmMp1;sqt;Pb#xJ?d1IXZiPmL>bCj&`Uj%XHLXA6y?Y&J zJ(6eMQ@3&)^xo~RBDl8A)NSpY`J@OBJW)6{%rh<0SrbDtOQjW<-F^PONvoQOMKd3IyYOE8Sd&yJ`6KRr;12F0Lr zZ@7rcbLjjy%l=8UUHk;;Pn5-4u`LJ}%t$xp;A?UFp!nLyRs*3`=&y~R#RavVQm)yqpkLD(x3kQOA#SJ z4F@>hWY}=6SeX8wgvWY0P%j60GorJFD`RV~v}CW2k@8dD46GgML|qmAfUKI;w6R37H) za#{RkCiHZdw5xi-VWB^-mx}V>P#EBd2%ItoW;kpriES&gQEtI7lpEENeBZ`QS;sX2 z3qzZTcF^Tq?@9a?ufS%dv=V=J=kD>Upj^#$8-sRT4pb`}aL;l&7C{0pyPB4 zwD2@;14Ixy;^f5lEDlAoPeQH2{aDu)$xbND{|w8^=Q!`vlFc>4fp(NP+PB%bd^%@b zUVOu$F0Fg}*G<2FXtax-4wjSuSe~15`W#W~+bBTav%iq{>0} ztidNeg`y8@nSv|gygF$~A86gbh}ezqAgnJ%CZN_Dso5OsV)NG~Dv{0#B03(Nk#u#1 zlI6W$cH^vA+<*@AOuL73Ns+d+P=%7(;##3ezX2JD)8KRI*;WBS|A;079R}QZKyT#% zI2WH0K--NhR++uLnM|I`{-ry_Kn-_@@15!sAvZORvwb2m;*kKd)RNw<|tE>LPwF5n2Z32LPxX2-ru63PSS_+Zp?ar)yfaudNn$|O%3>+9Z276KpV`vNu zDtVc#^cEpe4GL?3ufZFPWlPg7Rf`fbVga&;Uym5O{ITkxY3;AgZ*rnXElbY4|8Yvh;kL z(kcMSam@o7cfPHC_s}UrJ%s;P@~!)g+JepZCoi6Yaz{>ZdjU5vhZh{X9iAIqh%V^RcQL5Nx?3! z%V>I-vX!itw2NPZ&c$|gf0=MjZmWp)f2eU9)|LzrTt(|`B*`ZA1jq^pj?SZ)eekRJ z_sB9Ppg6n$sh)yTg}X(L-4Y#0bsyipHM)$j&fm;6el9W6K!M@M(2mzH^+(q@=J-Wi zue@=XubvpL(|SQLVUPwh=kEMu^@~h5fNPPtF6n`<&m3k>&GU2Ex7QbjNmfCDoHdxk z>%Z=-D^t3^!!LhJ{@e8d-KXlQYesJUHbtny2Pe#8KR?>jWLo+;-$uV}SE$bkk4Th{ zk#+lcm~%5O>uXVRw`jv~C3K6;jKe89+%ASs!W7SMSkee-$=K+?uR`h`tUV&`iCiA5AL)?^&7owCKm6Vk40Ep9^p*I!o zLzU0>W1n74ap~6m?BB1n?X)ClN%ynP@`lB9xnA)IUgP~_gON&Ns@dLE=|>(hu6&D+ z-^nF+?rphJQ%GMj5jxi#pxowbUl(m_tUFq8?X?r^PDqZ+voo%$+3#`{cR*O%;~3cW zHXhS;!Bx92ury~!nU>SiGRmaUt2vv+-3r@D@TWs${fr(1V@a zOkLjy%%7Cs9{=(sYJ8AxDB3}1ds&hL{V?r#VTj!tM`t3}J&9ZP+PHjAJg(7D;#Fn0 zBT9J{k0{6Q3y=GKudiM~Gi1cF=nJ+I0sd`|?^dQ@lr9{()4_qvJi#pI96^)%CP;yLB+GS8Kz#l6bOKA!Gi~ z>4_rJj&~a!pP#u)SQj{os`_+}Zs_5dm!Dm0+CtvzeB(>ZVe3m#9K&4YS^HhB*AIbu zW2(XX@^1Uu^}SS0+;tXm05wdy1DY(6>+tQ875AI#boiY&jn?=coOMu~*5q}*gbg*?>#sUf@eHTW?pPr+pJ53SP4n3(3 zc=IoX1Jj3kc>@QaMjnw3Z-mRWs`?}L@-XotBf$G)V}1&d4OhKNJQkzrG7x-5_iZ?O z2RcJFeoKb(os+i84eXeI(mH(kRLF$2qQ=IK+r6f*+l{nWzJATN4KxM6Jcu{lxR(S;zv{Z1r3})~-^WlZ|GjjDQUp$Fo-5nmuqV ze_Id9?8+k)OIftemAxY88?IPs`qU!j_cR(-zNI{SM|a^s;L%qBdwG=j9{8f*Rpx;Y zTPkjEUpD&i*5_3c)Y1;$hvZF2g-Z_pdb>T{n@;_IC@1s6T2?^z^@7u9|Gl4dEoa(=&dYL*L)OWN}M7gXmjDd#CKH**ey~^_XSunh-LT^ z7;OzEb>`wn_?=idM+jKSxwdFu+hQrdjG@yUwb5W9ZzGmp$j^oe(U z9*Gy^8`LeE_gOAoL!iX@)WGQ*@Z!$6Iu&dV=lt}oDZ}JM_y(LZ&!pi5glcf7Cz9^B zdYh{xj@@N4{L&VbjWfdf=d!HXk@q&y*UMfGB)Ltf+!pjXN%@0iD6?tsauww9;Zv7= zqR6)V#s=z&Qfjh$$Gxq$!j&)q2e?oaKWkNCiUVyob-Ak6FO`63QmseTg=Z5#4_^gE8`F%o zJ*_&txzDirH8*JEPlNmNcfSbQ_E-(p%4Fya$4yo6I8IQda6j%SucCn%mto&rmfCsC z!WFNlH`;@-OVrc0E4{U~CzO14>X2a?!{MHPa`l+i zCGSR`HvbG54X)EK`n7*^T(*A;gah*seI&s3m|MSup)S4Wll>;SOv)MH(Th|8wl0HKFXbF~PAm6KPnr*O!Zbd1PsAswM7+}6eF(dsF!wca~*w8=)G9sLDs zKru|TKPnw4z=)sM$xC|iaA52mZ>BSv1zEfb4m=sZ9Q!8F-LfU=vM*nTRU=r3&3MPq ziDsf--ki9K4$R-zjtSAk=-yX7wj!BpB(xFj65o@^V5bGKP+MeyKXnaa(}3RsejD|} zTx3?{iLx7BeD!2jpv(=s(x!!9Cm18q_AirnD5dz^Q}13jRi#hyVXuK7p@&r7TnZ{7 zxdkwAoMf}sXwSRX?dJNTH zEhrafA_JK#C)7>E830dQnFEUpiEKk7Jzw);3-yg)Fz=xO)izb+`Z1GxZrB@*uIc43 zW*Lk?hD(-ZgO&Ndl*09|u4zw|2u}bKx?=qLeo-K_J&HV`zPyePPqffO2eZ}IPc~L% z24t_MQ*h>mU%RI_d}>9DbIu??j@~t3kOfDdKPkTkdph=S9?9Q+^q;m48Wp?%B6m&F z$}CoEy$;xLFiBO~4cjG}^=wt*&s!-^ux;*UB7|a;oW(v6r{dj$f>BD1_82+8r;Zik zyX}HGp$T!sGko6$LW!?PAxE%5Ou;#Z4io!ng8NVuU#G<-BWkD+r{QZ{@C2JTd4%>k zT89hRewYcR?Xn&{bCag}@nvOsVrNXou@sGUu-DI}JMnrrM;@u(F$SEo5Idon zr~~vj;2>!s$0o+(cU5=Kk*z#?088xfpwcXg9#jZOOot|q^%Q~BkL<&ol9FhGz^FmZ%eux9xe*g9qdp&Ue=MasO{Vb2P{D~&eN=~RSf`UIo3Ws~c4vt75&ZSzBoi&6Q={)gUqM^S@M={w%sjsxj2Qr=jVbn>(j6& z|DC-3%fOoba z<8Sy5t}aSJwP{tdUM6<^n*AAspS3=Q+!=L8dy-<$KO9v_ghHvT-S^wecQFp$zltGb z4^`EMGTO(<3(`wYHGnXOk53;H0BMj?wzZ~to!8s z37f*6m_1Ze-fP(Nvb3_dYy+A+ccF(&D7{iA-Fi7~Z9&_s1kwIm0N3J5jhd(Cu03r# z@74DXOVnC9yH1IsbhmDG3*Di>b5PiIX{pRLG2d#Xb?F3Wb4(LK(|7T!@{O0+qn(O( z8qPt=b~{re=Esk>o+KSVJ4t)ukh<#Ci5HV6({&%6e6Zyc|2#xcH6(`d3o%;y2>MM3(HN0vn!9~-Vk7qT#8kX zSp`C4+3DS|o!HzUwVb_X#d!r$0oxrCG7|Eq21Xo?A9+^W;k)%y=KcGGgQA1bq%YsP zlda>wAlX3uz^zmEtJ~a7cxmL}<>*99201l9%uS`;e%V^D%L8>HEsyjK*cSJ2YmjKx z^qK)|utP67WN(NtxfqcfE?T@btn0hte81=Ao;~hH0hiUy^_!jF@0@?m;ydaOcWAvR z4iD9}qIlP-2e-IBv1rIMS1+C)>nSXjvpr4{uet9F>F-&ZdTF=($O+Olvd4tO?Q@Tc zPhqZ5UfxzXS84EeiuI1HYCb5|Shv~Q_ID}ixvxkS$mr<)oug`AU7DW z+NM<)xIKJI%yenHLz`pfLAke_mFSTk@KAIVL=WGFlC3f45aJ0hsjUVB(gJPq%lj=AZ7`91iPHxQA2!*%g{W9$ zw2*+7J_%V8SkuZ_!yzcUWq5F)6U|=ZW8F>G=UzO^6PLbn_cxB2rhT5LmyG3pt`nB| zqR~+Xb>(FX48bDm-RKxbq@cl8j>juE0*5YDoJaLrBk#l$6C0)zhBnfv{`QWIjIH@> zH8`sx9*5$U*uMJ(p1k~I%4wveuW1^IK{2-f=3yCHRMLgR|R^E zN9h;#l~0Eb?s@;M1`CAiL7~cNWD@FCg-AiUm09KsLIwVMFczsf3(k^h-prx=47oO> zU>%2Tn)in4$$R#2?l-6(32-q}B86l0$l1@`9`_Z^xzI$FqPPCwi^?nN(j6tTu2nRT z!T#v7+{mFJE;*-)Y0Vh<;^MN9f$le4GDrX?GkD{4zmr7Pk}tz{Y~~_8iy_xSNecn2 z9S0WAFo`khR2snPOM3Zf#DcM*&3xzd*uqe+D+3K?b-9n5S&;*oYR1zlUy4~Di+)z3 z7`;Cm&=#qO)Uh<}X9bp#*Qlu6vQVNO+z;7BWLw>r>mIMBu{Z8J_+aRa2!Xz{1C@{ID|X4^|A2g(K_ z%^C0dX3%3F8LybGUFQ96hF?pot6gf@G<#2oCRu3-P7B83ht%`%k6m?Yk`E^8yLdA3 zdNpXiQwx0c=L!hTv5#PK@{-Bea_E`*N_vQ;(t=G-&2bX;SpXi^bJ56yyLG5@N+s$; zk5)y>e8@Wox-fNtpyNGAbOTA(0Bo{p}Q!Ae)w5e_M{z+)7x>+Ol#y}k8MpXgYBlr_9QdDGD3UjnP+O% zDkNnU>At-I_!lnG|KW>v6H)0C%iN`0_CUn8nSGlru1^xX%WmsFoBp^w55!Y_khers z&1KHtK*6QRQrGT%^x?N_5?u+YcP?+gZo28lII%Ay!f1$j{e#{CD0fD5ExBz0^bO4W zj{yt20^iyBExNGd+DTvLV&87G?Lgbi9z~C<*p}@=B(hPmG8aKL00m-8BC68?C9l_` zrsN)`7XkL6<@iW>#p^Ml1m2fhU7h;v^_qpxMpPr|)D%OF%O95J#oOyEA{X&_-v@5x z9OnDzY}xHfOzv0bZ;uR1pZ?anQ%m~By(#q}Q2$f#qrMBfll97KTRt2<_H*`+hJ(kn z{zXtOV1pb)#?2}yB4b2UL#zGoK2;XhR7Hf#@8F93%s8@Jr$2^Ds}xjNj2g;sm|=Q+ z3SAC>ycIXhqC8G*`%blK4!w{O{TeY%d6F#OW~6f`+@eF(Uz!} z2+=d)NVSq_VzRnS2mbZO`DXOo&HB@0VtL&1rV|ZkKrpj&o1kp`L++~H@YlYE4{CEy z)jNcxoWOO5`J243A+qo~@=h(Nb>kqZp_H>jjB#DmE>1uR(Ze+c@2 zTXg+D@r7Yp&;lpPh86c_`Zht{FjAqXEIAG-i~kinefVWce^K}BNnZNR`KXANesaoT z@AKJTTJ~lbrkR|-qS!P1L55`@k_)c?L#hPW%mJ`MRjwCgss!wvCL(@%F7pp?_o{d*g6DZ_Tu7=~QvR=TjI4}q}H#Pa{1zIFVsO%%D zP&m&Kb{m*xTdJbu6TGydY5HRvN9Il`Jf64_zuH}73o&_$b?dR!ESq|BdwEt+Meeu_ zM?W(Usu&)ACEz5Y>z=AA4Bz{iyC&Z|m zizy;y@c$!V@KKVMyW_5eb!ExX@R!KuYHGAuXOe|43%+8)waWU2KcCi8rw`r80VRa4 zw=FJ)*tNAI=#2=tv1^WV*L302?zyP5zxQ8@vg1!nR;3G%;~c~fki!oM>PR09WM!eu zmlsSx!d#I$U;CyA{mdPk{HAMiK@NMrK4LztB;WDbP~cM74GS&4>i)VO%sd>HrPJ&> zq}ZLkysE6{ywKvbdOC}eNaUS>f2@$KS_#U~SBS}k0N66gN2W9qJqti3+}D;o6-o0* zZ>HCa)S>IVfqH@Wp0Z>I8g8S}QXm3eS4Dl*^|X$^l}cuMjlT+D-0Wl6_oZH_x+`-R z2V#%WNjMb51yzBdiA%apg-~xz^&vuAG4<4b^JXQ2Y-STm9W9Z?j)EKtC=N|?2~+kq zOLXL=H&3fTsG~qDHlkJsT*qyXeBt*tEMHutl->7rVj^--=YZ53fP@%bf&Vb13;x|F z8APdvz*Iy#Zh&ISggS$9!cRtU;3Ka@vNi$@(|}CauH4LwRatwVpZUi9YA&V_x{6sT zI>3udENinwn8XU+MHcAP5^Pk?nYgH2c(82AT!_Ge+*0NLm!3ni*S{kS zvnbcJf{eF=nL&wcy|O*g?{K)f#R|FXXXkvR)xsacJ|+CeUKfGA7u_OxN8CU_!yxU7 zR`@l-vgyM6>lQXou!NI6IbEgHP07o^>9olZ;} zl+pZvo<7Z`mR6csz&+3-Jrl^*<_-!~M5iEa7UrX!WK}cR+7gH<{22-m<1AUQwUh3h zjoKyRERi`IzDnrQs4z_MmV*DENAC6L4sCOR~ zX)C+PLkXrgJB)M+#L~`XH=59)f`TtqL)B6UC!TT(71|CcQ-V1%TsMwEzqTL)vJ!z7^S}gfC91u? zvh1zMUHq6j{EGS$C~v?lBh))tI02Qhk`HghTCCwEveTR3A9E2>5XPPcXEB?Stm@0n zaC=0U*&joG<}l5$z=4ZK|0cp%qf3koI^zNiS82Oc>5X z@fRjpVfo{Gd>wF8<>mQX3@- zA~Sw@na~_kW)l-}PMDkkW5JLDnC@l!B=9A(}(XvMYP$zN2EhAY>;!Z#BExmJ{ zvXfVl>qPo|)L2Bz6H5R7<$YPJ%OAsO$=8hR27})Wt)?4ozqzo~dDCJ~KJ$pishbt_ zB}?+ir-p6G_co*j#-7=9{3&U0`Q2al!M@y=teO@cX%>RYmij}4^Qb$_lDKFiDuX1r zCr(4G#RXPFBf>p?cs0IK{xis2fa6!(%&m4zP)SZIjgobL37uglZSl{0owi-q2yNGd zQ0gu93H2w9)6Mqr*U5lZw_W(XA{~&^Qpf2)Nqp&+41;D&B7x^dVGOX5&Fw1i{Q;Hb+CJ51DR zgd=I{?fUBX-EqHr#~bhc!x#)PIcJ}J)?RC_Ip@l2XWAdl-brLG9n-IVBG_d+^mLAT zInkD`z}$TmEDU)2PV=#I0t z3Q~&iNBgSTs<7wZHCF0;E>W0@GNQylRuaF;c~QLNUGS7J5zKREG2_Y$-#N;{$Rvlu zooH4wz2z^TYHZz}zo;9{ytEMi1hhlS0Bb)^0lMKL_AJf&J)-J?Q;DG$Mp4FY5n zI*w{uCg*Sy;=pH1gjw1w32{xIk7Q1NwHXG$S4{LwqYGW*N>B?ZhuUP*^aTQ+F>nrIR+0-Fyf`&4)ep$k14m$o z7^&L3Nf6Hv$2cG2LJ<|Q;l2kvD&L-2rOoWr?4{Kmz@B9epcF2!l`??ZPD9czq53Bk zeCTkcJih_8Y>IJn$N*j>CEY?9Nji(B(Tju3UFCVQp;QSD0pI*4F1Ogn3}vz%ql`ih zTo3Q*=sX5#Ey$OZKvs&+ZJfRE^lO^vCF;$DY9&e(O80+mQ#)uN*};(00FQ!{X0ZO_ zi<%}kQr7^67-M`6vQ};8 zTq5V!Ay{nz+>T4MAiFGAl8K+nxsAQ$(O-@lb&P;fVC8fZc*PG3s`Iv1 z|Dz$c+ghCR>4$nP&T_BL@2g4P92ZNCQW?M{Qgkdzn=6v?Q?W}TqAgZ}R7#h73A9?9 z{8n}E2=_J#?se(iHK9Xr39$Z_THF`xwY!95T(f99dTMN73vWeJdHmBQOnCbdbuMQ& z*i-vxqAa}ed38?tgf0QI4~iUjeo3CJ^%n`_SYIGyGdIaAG_!aFZ@3QH+cniPxD>f? z)F$Irp?t>qO-e(?tgFS3*Toj+exA{um=F*pylf0jq1<_`G4WjMJ>bNW-vUGa@VGTtlBovr!Hwu)WB zI9|m%j?4!AXn1paBM^%+D$zWAzp>a{rc`dC)!AT-sVzpx*c@o4nMN;BZH7D=(RWaK zm~}zN$;A|Fc}pF`P<0x#Gj&?T=($00O5^6JCmuE#k1{2T%+d&6eD{uX9-o?K8g>F2dC5?^&h}b zoxd3VOvat~hnRaI9wy2MM8kJ5^I$U{Z!<}&b8V$&g$;hyG=3Ru>O9<8R7BlKrv2VA z-SStl`8{Ha4$J#@dtf`L z@VKc#yJjWXQ5s*oMz~alG1nQnMA~IyRv#6az`hPy`F669<26a;H!h`jj_giPx6S$! zu|J>?0u?(Qv~=Vl`8?|F!CHo2VxuX*=5mqMvS8 z%@=1G)O*Pq;G?=&TvsvW5Hq;lui=Gb(GUO=&EtQ^l)_ocAWfGL1iTf}W?DH@7M80r zgmXYA*T@dF1m42YA$r{rF461`rtX4VQ^oXK8Z@iY#j=^WkY(pW9cVJ$+!k&qP5#!f zzl)!+BV7DSaE1_z+MuGrfCw=k;E6ZGDf%6>P@2G8kpgd1x=?n>Kb6Tx#}w)6M-&_I zl5v+xV3HVVM4ZLlib#hKL6MF<#*L;HJ@z)mF#XsaoMg-{WbenFqafW4BDf1u^J)=7 z5D{4BpzW;D(G}zS!HLXpUp?@Lb+L8LxJ zlI!Cb(c7FiaR+@}!uKw;;h*ijG`UO%vq+sswItHyXRxV^QujQG-F419cpEU)jDa#6 zvJG6c561uOlq{`+c62smWEY~7?lqE=6~UT5YHMt=M0*^JQ=e>r-)LLGaq;l;!_xWm8lJy+G%H?k`l_h0#hh z#S+@Yk{0}}b&=MOZ^X`JZ-ll^N+RRf$l_6sUKuG_XkhR7%CU%S?ge3!DA)pmkRX3o zR2`IV^rwrB2&v_NZl9#??bM!|Kn9SM>cT!Yt-1b@QyT%6c<{aBNYWdliSw>jc5%Z2FpR<0?U z19pFzBbY@k;ni~o5)_f@hZvA=fP~=!4hBJ&Dd6xVOX<0kQ?MRM9#@B2rqNcp$;}gR z$>oFE&74*6UWw3vOr5M7vb^OWrXzxFpZCman1x4XP(huU4L16m&03m!KV%jpS?DEF zaq$G;?td$1m(|4EWqQ|m|0ys|A!c5GD9#=t`${rapO8MXxeyU>ej!4Hly!@^i2Y#G z=70rQM^JE<%USQ@^Zk{;*@fWA6RRykn77kwb+`Vk^{IXIejX@kst&)cwBl_^7CkR9 z{P0(qRt#uG&Y#QJOVNEu&Ej(qLZgqAN#$;e zIQ0waV(I|LP<UaVc9JZWEviK36@H^5Dc7g!h?+Fbk&Q^gt|AXwWxCtXf{KZ65J%|Kk zvBEbN!rB-spLP{a9(K(3Q|_~o>R#UU9a9sD8K_2I|9ZitNX%-`?c*YSM?H)VeR>y? zHy|7}I+TcDP&@z^!|uPjYKt_VxQ3ifzYCXh)@wRB>$=&iArjB%8vO+v+FLK!O_$J8 zy?!tx^l|*+Gv8-*Z$)O%0S{?`%Km3gr|9Mg+r9Mjui3bb4b&}D$pu^eRzQ|5k3Cy0?J1S3YJ-%osYmI5vo?oH2x3KXyPMiBM8gq*95a>eaqy?=U;`lR!f{J zCb!2Os=*6j?_%q|Jf#;UKwU7!0F}aNbrv^}mS~ES`=AUprYeVb(2hb0Y0>xWjU7{F z;+CDSeBefb4}tXR^H5NfHA@J}Cez9nL0)N9JJJIR4=5_Pw~vWw3*bO}16q%A1kzdC z9O!(@>QXxLq4?jnix{_fEPFn*u6r7(>sdae-5Ey?^YYyh z9uwt@^kjFh%~aYrSNh_Wwm*rRBP8Rw^{$)bGv<)@4SP(Jykg~AiO(inlh4LP$uZvU zhHrl;$lH&7z1<4kdt`ZgYu9L7-jV<#!>E$N#75gcgCCxAeKzr4EZO1sr(}B zm$GA<*1vYkcHB}g8WsEad!77N+dkt{;Piga(dYM_oq{L62<6VG1cnL4LV_32dDN}y z7wdaDYhZK5EBIFq<&@ltvRZ!eei&rdG>dth#~N;YtRe)ytf&$buV*MaPvRC3-Ux%L zuZ~!Hc^)ZzHFzXj*kPOqo9(W>j6{AhU45!H@K+_`a^A5_TZ(UnWaLZVF~3cf7*E`m z*EzAxlSiMt#90>Wr8Y*BkLK-qGu1Bw?dd1p5A6r6T2=ewuRIb%*KZ%=%`rvQiwn=I z9|V6&$+m;1y7z3k+N?W}{%}|R77NBLjxC5LbZWm)X9o};p>Ls3VBn=)?W|guwh0W) zo}*a>6PpVqGMxrNsv;quu1|63emreqe!OcMiyS>_z0bzA%9(EK;^Z9b zWB*px&OiU`{sO&?+y#X-QeK&^zbssNLVPLd^hbi|?SU7bH$M6WIL}Eej4$M;73;Y_ zc;$NM$p-0`y)Eg3H^D&;xZCH1f)n5-82t=zfHjZ3TaVTqn;j(@nWxzABbmJ?K8MTd zy;>&{BDkg33x?|m1wI5Y;B2?M8~^&g+i7_r=dN523k%uBS1F}73D)-8AZ=SwQ_8Gt z$(qaLj|=v8o*GW9{YE~zM_}5q`1#*j*W*tI#1+_`RIq-VEPC0QdZdZU7jq49^tX0% z8m%ugPBIe<5*s`kq7Ql8<1DUe=*nPh4}Eo%!8*aNI`!*%=CRoy+#QbJ|Cgv@+2NZYSF*!lIiV%mRIcG7lANJaX|`_ZIP z8k2EMz}krgC+V|nf?qH>DT!`Z-Bf*@JOh*0(K1>gyRePw7z^rp85?|Y}v~_-)Ep%T_|e40Yz){L~WS4V{_=K z*h>5T;IOU-5Yr-(0?-`lZ7YPqzIe^@tZ3O>)c9YNHsl%baeK+>Vs0ZB-i%YN!b@FK zL>JX*Y)?q1fx9@oSACQ1A`&iBS;6^Y+EVhSPZpRlDW9&=dr8JOm@X@0L!kw=xu-e$ufRuyq2G~7AcWsc z)O3TEQypj`h#rB{x9Kxfh)?BaEvI+NZ(J2MBm^67$UVac)ewid&UKAWjB%I3wU$TX= zvS8G}vf#}2DK%C)_^wIz@n_ZX!X*m>>Jjtx56D*kzDBzii5xGqhD048Aq++plk3qgVsB zC;81|_FGCjD#L%p^%K7`ZGI7Ig0w0@u9d5PObcS9^m0qkJmC!#A{;BAxvKx5+Ku8@ zQ8!Rqyn1r;2>Ftp+XZKWt|_7(J(wMJem*p+(RDFCt#2Fc9UOK4y#!ZD$Ur19aEylP zr-)l{w4xn6f$P*kS~-85C&CKui%>Fz5~&$r%*SjbM>jLHrttLag&Y{m4A%VC@h#1c z2DlhJ#e#3VW>cNs!Ep;2AQ89P)K`;Ic6fC<%QcLcP0t=xCu#$>D7-ncQJ5&KwBe!p z#>9a#wQ?hP2G$$^4`loU5Ad5wX-RT=6JwdiN`-^t#7dlj57}EBd4ppKXVz2o==Iq; z?V%Ui*`!yVLw>}lP23IW4fh?GBQ0m=eCL9eO_K5`b%;?Wl$9v4APSXpYbTa!x*4T> zdN^|42*B#Gwdh4KR?4VHCUTJ~rx^1TiUp*75RQI1b^^AX9cvz1CTHHEEPvJ4z-;k< z8f<_XxOSKKYNV5}R{JXxUXQ5d4%jr}<&G1Jg0Y~}5gG$jmbdLA#kizL+_|a^*Z^h% z#`3-*rdwsBbXVu42I$4S(^hz^OYGg`NKv#(PwxAGG2fmhS4vRLYFC^d zAHocu=$>XIU7H4wLfI6QL{&%}_p}L4hn3zlLV`$StCSY&Oini%21CjY{ z%mSDpM$k3JFs7w>_aA)(%@W3Om%xVf8Kcw}cha-XdZ&vIOuD9@>be-`RMipU-&MPa zx{Fo^jvo?3(4eS-2}+cvT?kg(pV>d4u!6?1^Q=)OMAUq6po}#OS7WS3uBAr~?FM~X zdxFJ_`(o_E?vS=iSib4WP`qiEQ7IAouu^@Ns2JH4b;(Gk z$SL|>k-a75Ku7U_1N29KnxwH zc&{!=Znd0{lR+GFG~L$yzJ4Auf$bc9MYPXZ zY3$WLof5#RA+8V5Qs8dT)_`u!a#~#lcA3T&^d?PJ#;+-^Fim>5Xk=zc53HGLgCD4w zCCH?I=v1-g{FM~L`}J6T%C`K`o|z$iIhP*lr|E3=GpuBXxHXa_`_{YQ4!vuO7(A%0 z*rr+Bt~^P(sD6k&H%7W6oX>U%5i=4!P%AleVZ1VU47A^%RmA6HDbLn4MRF$op~No4 z?Wm>SNcv>ms#fCmp0s9SWZLnxrv?BebfS2@0ZYN7SgG&IC=Mip+E$tZ0b!d5z3Ul$ zrY6yu%)}^KGm*d8YqUk;xgD8ww%kbX$?lWi+ee*qKX}M=FYGXN`mFuaU*VyC6N)`M z0dJ}V9RtO^_Nj&T{($_v7(858Y%mrHYuC?AvRE(5q)`cD$8L;1C`iAwyiz&YI?~s-Q7o7ZQXND8^!;7T zh{A=Zi|>6~iySi(FXGkn;~^0eU2D1owYhd3+xo?CQu7yAChmyBwNRf9GnFoy55NNm zJT?Pwg#|)3wrfXMRxYbUuH2 zzWIT}+;e};*V@fJhcl$;0kO1*g#zF#0oP~d5RdM+IiOD44tj>y;B+y5J`uA726T1B z1BT?{L&-k-?^lLKyeukMl46@W|AQ3j4>JTb_FbWAwV$CWyEx(^V7fy+y$tPS2fbQajrAKCfWyarda2kx#$xqFPY_ zA%}%+q74iviq(&%knm=DEgIgm9b3l96`7z!j9ATf)jBvr8WN~TC#@j6*#EBC(5)gs zksc-O;UU^?_eMXM*d2poOlA_z+F34^aFDE!VDxHKgmTgJaVslj0ZM%;$b8BaWzY*$ zf9?Twg$4tX8^-tqK~l&x#+_5{B%{3`3t{4y`%+;_#9(l*b6RihEb2yhG+K|$aAm(O z=?LE!>Hd4VjbK3rszQnl_7e8T1X=zlN>}n9Ikc| zXCZ7QaU36k%$t%faFKzP9hl|tSW{pl9%)TmHe5e^3OeC(z_Chq+x`MtpdeVw#6#w* zysT*hnj|20mm3oS=D?@rQs6kH(T9Z+pwmjgFP{MJ6((Vl-Kh&oidqN~ z>>aP>hawm4{ql;kU7F=7&Lv%d6~2NPRqyMV&npscDkh0*kpeIfQK`sz2hR~>VWN_L ztD4(PbV7%a?9a)a-Kx4cD9V0$TR5YhW81kR2J4z~>}~Hg9m}&9Rcp+ zpgPmuS3h@XaEr)?twewmQx2VyYW&<&m1QYh2l2e%6Ji{l`WrOSgi5BGn4;TN z8^zp(uz-j~j?6Ai&l8N!x^k~}4va8xG#c z;L%}oYLe0%HWoJ*C|xxjn0@N(U5r~O1a%dR2i*BvnoVV}_$9@%LY{tmnz@9W(8O8T z7E&~!+9@Tb?wH-@T`Pz$l&oJ{5wi8eNT@*&LbyWZrY@wN=iUZ6)&X2U*9)Q;nI}^> zk$K|CakcXBh*#SEXK?cH$@X2y+t=K1;)6Y`6qf@;U$=wzaS0Bbo~dnrF*jC~-TR?? zSfcai>(E#XM_tAx(C=Uu(n2S|Ro5Zsk{{`si7RC`;Mnv&0P~(X0aDZnMq@RtfqB~t znM~QJ$0>P5h^%hDq0TJw^Zo3EP9T+Mrc79`f0rFicAq;3m>^C<{043rT6P1>aW$m2 zQMZ)7?Y76t&yOjxTsm@en0S$H?3bByolV*SeBb$pDB?7`{wA-)5#9Ec1jAapGQ z$rWW~@N1dL*-HVHWCe9_lyXQS9I%oE#)fFNl8GXN+t#QAQ$sjTl)6u~?MfsvKGfbp z`X}X3Bq`)2{1TmT>8V_;?&=f}+KEO(v2&*Bs+A2s>e6Ww2T7FbGN4Tc;s(kTVb$dw z*2q{P3tg9jnoo9Usvde)13=ZSa$Fh)McL`%CjPMheEOr(ATM5m$|daT8_%-fKX5y^ zdYqecW*`1v&K4lf{m-cP|Nl1xKu6p!{^)x@&C^zCB9!whV`i|{!*p8R-&%hhUjqTh z^`DCuo87OJsyFY-@BKP^S8q^t#w>sJdrg*IPx(e8@{@f8&Y2U;qt6GKz&bd<{O5^_ zWw!zkv(b@T-BOE*Lo3{WzLU|cCVNk{Q|1)Ifel88M*eNT9S|~+t^Hzb)@qa_SMsQ9 zZxV_8B)@%7>H~M%O0csD!dvdWyQRmVi`iu{-1-@#J6_4c>lwwZW!|2BG;et&u(?|* znM{6+K()18u6pOQbp4CPhEF!(Jx@1W==bwI8L{PCw&9fw#UGF69<^+^Xc&C*>C<7S z?g+H1odH|KOC#evXBM9NcrLwVg*-_*+L^z(n|bp2lU!%iZJbk>*YgdX?~3lWHi>Zk z@|!gAAu?m0HZU&Fl^U#mKa8!6hyhP#=|jz&`haID{#cr==?TRCA;* z3pze^@BpO&$tH&F&VLE>fEbXKpZ9zj`S8J5PuQ>b#C8|QqD>BNsN^(1h-@F=)ZKic|F!3#w)}@MzHYf9&GSLP$AkeGi1THwInPncSY`n?wK()cC5G|8wfTKngf4Yy{Fd3 z2!F)pa-XiMvR8)7@-P2q+h;o}X)s7+{OEzhFs*L0JzW7#I-%yB>Ax3^cyGE!eQ!#Q zP;|j5%JbYin87O$Qsfb@SvaWL3sQ&hfsr0}0V1i`{?I0l^@MCh(?#NZuvqX=9T%bq z8KNm3z&}&HT_#kQom*kO@YOyoz5W0EOWfaD zW?ztf2@2;@^&M^?X`zNMhg&%t2gr_%;5am4CbLjW_doUV@gXytjV6**k2+p-Q*d8t zfdj-!Bd3QEj>?O5QSIJeyf*abzvy9QPEv89H~#xOr=GvMQDY!X>EDl z^8<`ekNbC}910%%8(-#4^0**c{Iz*08BA#SHGj^3E^Y18z5mQ#__7LNAFV;EZpQv+ z8QpM)YX;>1{_(;iCcz`qzoORrH zxD4;C?qZO%)NYR1|6d}Li{CU8zh?i|dh+k3+OD8)fA?e1j)vcN>z{zPbwr&vGW#U# z!S!rzcf4$m#xDW-jx}XPfitLF`=14{{K4DP zw5R3Ktl!tUuRl*dY2Om&?R*AtDs`XH1gUoOvL4^QVZ&GdB~a0({5$&Nw9KB1g0-AH zV~@{q+NId~B=_|@?ujbW56!d3?ZCgwM#MWAV(}^JURuVCdTvH!_tH$Snu$v3)!j>? z!)I2R?7Zxx?B%9U&)z$E)%ozJy&vrP_|dv!b8qJE@E(c2y`i&j%Lm)BfoZejEsXTN zGpjxo?D;S>UHs+!mfeqrEu0)(qBS?1|9$RC_y#cJYD&z2!ztXcin>?!oRhwDa%#8l1%O$&6)vxn+)peqnh`#$fH9$ z{VgJa>Fl-38GdKR(`i6Kaz&+_O1hIL{;_ex^vBWxkcY6G`mfgnQIn|e0ZT_%b{9K! zfV#{df}_P?<~(m0-#WAvjMn%FX=_@Rn*XiU6ZaeTg7{Xt?qx+~h4<~By`x=R6Xdf( zF`xYZp)&d3+pzx=nfkwfv$U4!9EC8cui$9kvV@cE)~!}2+F7YPMx6VDqx^~kFj+6p z_%#;A6TJ(aALl&UH&*2%zEP)zYNd@2izeW$B;aRt48n~U$a59@0BCVDPQ#nU-l2HE z)_fe=D+fB$Ih0Lsx_r_R;wOfxT&XCELkA_0c(v0ZM3PE8(M5`QSzef8ysg;bWY0?c z+c(ijo$qT=KAJ{s30GzzMGNSPTi|1FYJ{^kH`pjBOiHS^qxCn`qRJfODEkrgU8tL& zC@!)ce9eszPb??T;5Z>>O`HvoYfWAgEhaM8bK|X(yIC*2hYnDVYSzf#AcoQPq&}Xa zOPxT~AH#!Go+i4-C^eT&28fGk&HBQ!VHr(I*Vpjd^kZ1jwbr?jC2z+5E>6pq`dzo{_t*j|naU~21wEnO(ZCep;~JyVjx@+-2PJc)?1= zNi`GH;fy=@C0NlDp%zy3TsV(Q#2W*Y-Y{eeZ$M^fkl9;Ps$Tu&xiCF2!GGwepMWPs+6ATZnQH-soiB=KV#D~oQOcW-+IH9SuTqARk&KDn&Apni;524|z@s=T4zdJ?GCooe28 z3!UF|?FiS!)eCq@ltl%^Ys-hMUq6(}5C?nh5e2>tYkFJ)n4d_#l+k|$J+sC2Z#I6F+d5t6?EgbN>%kq;rW~w058gNeDGe3uX9j8aoq@d_YI-6TT5p+Nh8)DLrhY=Lo<_sl6Y9}|iiSD~ zFbBBJJ%=)(tnOi7ws#O4rZOAf`AepIlXp$%(&~3!DQ=QFsniS3Fw@Ec#VrhEQ_c8{ zSGmW!XHSvc|EEp`<|=-{*Fm%6u=)vm|2gF$?v~rSfAWgoa;<)knrr_5yFmSU6RAOtljN04IVVpw_$~Rx^?*x?-g6{+HyMGo0wu z#dfXpzV~W2byFXfuoinvxcp5oaM_ z5T($7XMCTqZ_rn@xx-#ZuJN8g22;1vo4lI%iLZCHP5QvJL%<=mCFx?Od)K80<#%H# zh4R1#R3&me44P5&!(pJ7pX{JrAPqzVg)&Ou-^4JCz%3fmw9O)KQrA)cLK#svvzgKf z1jV;~>Wp>DbNSc!oSgju&*8%e(~X)IIb3ySSL?}{Gv!Z__i5*Zv5aza9vU`hs0@f= z_w;BnKMjk*{6_5sEiQZ^ zaiS0l#}w842zdrh@B465)No=sQyV#6F7K(39;YpToldD(vTJPY#oJQnSRKty^+V0x zQ6Q9TZ7r{PAvxC!T2fTWcj~Q#*>jgEDeCKN4z+oF@!wX+WexvA}rum)FOMz#*% zVe`ObhGr2B)a#pI1En{aS<5KBz}3fwPJniHLj6Am>C36>$@(a5vfI&a&3ejC2wjg{ zO-^a{!X=S*@fQ-P=-w$be1NqlVp|Q`V8lI2)|TL)=}mVnf2;Kir&-(rIcOF?hR~Wt z*CF!;a49nYVF(a{<7HvF3?ceDoJ_T${08$#keQphc-oF(Lbk;%B;XOMbX7Log-tarj)D%147_^h zzTopf&?EO5{j!3;oKvnpySF8GNz>}R*x#Na8)$~A_3A3xc@$s+$h?(a)K38VpH7ff z%AFO0cIvWVQ(O6u`w*=js|%D+CJ?=jyU9<8oH3M6KO+T(?b5?=q^*cw8R=0ngc8<9Sb`+JVE(2$$>p;Drt?3+^ z*P}Y5wDVPY!qJGEoVA)Z>YA$F2=oHgg06^t#PLVfS;8A^W69o)`vacBG+>QWxX<`N z7iGsB^-X}3I?LU}01Y8&7U@WFDYW_6KxF?m7j-rF9M_a`_#b%wrcvZ=&Q2IDMm6$p z7+`kZBepu$V%Akc)Q8vA+-E%6{Brl+jF6h3N9{XuB!NAbNYi!`i$_2x&VuQ z&RxZhP&!iEuod`Z84$f}#+Z}mbBqCnuaw@vH69Tzo1({F`)1(HNXoW=OfxF|3?W?O zK#I}@^OJX?*q=ME67Ag zd8$f)P6oEH@l$n?{tFRBnqICB0MKuFVC5l^^|ag7$hcixfl$P4peI(Z$zBX`SeGap zZSHVZX+F`kLn)DR;c3X`c4&mj)^(C-6ml$k0o}LLdeKyQ%!S~#(Gvs+!wjA?6Tq$K zgE+Yup**Yki>41)K*)X%z)LJ~9G_4ckimOY87L}tmIlUg?BOw~L32BSm`mO<;nIac zS;XJZ0W1=Oy6G6(nd2oZoJe}z^|%6)YsUDcu@v5Qkhb*U=U^|<25`Kqv^qW#s1Gdamwv{pOz0f!d6V z4`Yf)q7Fv+r7(#hyEBpTu}C1d+YRXZC;(j7Eus-=ePzC|%kv>kCw2v9CoF8#ER*9B zQ~`3nBY20BcM*kmgt{sx|Dx}LPBPO~j*ky-b!gC_x&aaEU~dEoIW$tS`vjraE9Awq z9!2HvCc-A>JX+mFjXm{4MxbgXv5`?quSe?kku&T4R>3w8^W8kj&n6`Fy zDZS8hE?GdrbzgV zMh~JT0Hud+@We}Wit$l-#;C^?p94MAJsf#Y{<$yDGj6B8e48A*@4li}os1>m@8IP} zL1#!rs^=qNDqet9T<_re|E;x#*&tj_rtj|vm-&O3Kersa)Qg;7$CW?QJup+hbI@^v zSJAcf$zX7%r~2{F&n0dlhRy$~<*R;<(Fa23ibIvE6%2_G2&V!nVGF4+4pnKMfZ0iH z6E4hy+vPloHt1|ci|rVzz9Sm9Nn4C3mVD2~x;VOm1lg=Zwffvka{Q1kA$+*~Ikz*y zP^=|K35*pRL86S+3}FFOLBz!|-q_Ug;mzDSreGM5KO&@zTiJHq933)3;#kW_8q$)> z3xd_Q|WD)Hm{uZqge~WvO zDZn*n;Krwwi@+&g-rHF0G)<3XETEc@&0VVH>G8X8y4D|u*2sHhCQ@PiM2;urD75=U zgayfw?j>*h?K@{x%E^>QeZ}MuKA5_uOiR@d;m1!ay)?aeaOD^HM&NiohP;IW9`WFa zLU8OTwlEh0Jqb7rDilqBDv*Yt>UDSINl}YnR6Q2aG@Qitz&38nEOeRzwzA8*(j6WR zQqVG-moK2Zr` zP0VI(2(19I@@6Rc=7eTpj))JN(`9!-iFSZ}x|r-HbxdFfK65A}J2%a65IyWe&upEE)z0s;?Z)=R+Ap0@EL2xvgN5+M zrMJO6p-zp7yz(Y3nAyKg!c4HH$C}zg9*JxN$Uw~J6>k$cfA&&shp>qv`OrIwiJQ|K zh;cK*S(xCr31>8-$Tp8Xn7y`p%Db*`G~-mP39_Dki&lYdYlKNWe z{gy%5sYR4%7?NzE1=3Sb!iC4$o_FST@8b4@Fv8F+kFjbT(uX#&pAQ0M0LH4OOGdFN znNquK?3(hePDC)N0~ix^Da8qjmKelg01QyKlN$&G%*^pD=1BD+er>;Z6Js%E4X`(G zVET*{gh;YbJgl5OVf~i5G`INIj4kdC#?+gDaBRO+-p{<4@pGIYIE&!Z7J=f9VLT0H z9hs4un05XC%x2QuX~Vphs=iQ#xdVi?63b{1c^p!ntn4_WruTjx2E&Pn#+ zPnMRIRxui)vbuIx-OAlOdl%t;qF zC#@EByau5WM)6g82q|CIr1YU^0|_7sp*pL+$KENI)^UvFye94f3NE46fP;bngt;SJ z7%%9_%NhM6IAb{3*twlWG8)rt>7;B46uo#0&GXuE|CLMF*|y&h?SSV+>W`E#$H4}e zHzv0kmno0HMgw&k`%(za!@AIU8)+-pjs<|2kxvU@^zoXBkX6&rGKdF!;BqNO>YNbvrALtJ z1nhYc<wDnEEyN;iJ*|I&*bLPf$%(NOx+0g7!0W#8+= zl}4aX=wf+2Vo=}tey+3K=w*;##ZqN$h%Y>uztWNt0zU>j5d&h&DNsV{$iuyOpv}|& zx>r%3AjKy0lk6>Cyce&gZlf5L$QiLc`?NiJitHUFXjv+)7AgsR_-HqFep^&C@ZnO;#EQ0utm_ccA- zN@UZ7AYb7R+bGRd+Ui$;@>PhxWlIB@e;m~k4lD#ZuZoBEy%^J8m2vTVF=5vk7Sc#S zc9vn*L$tJFl^G}uTyqM7W%{W_?}P7o{ys+vsJ%$ls$sGDI8fX7hlyQ_m8(?e)%O9I z(;(?hz?ikw&`q|KEgt)Dl8#E?465(RNAeRz^qTSC6!FWG=$ZSkzhM_nAso~(REYr`IN-BTw=cc2@VT6_%Ndg{&I z@;Aw050AK=4s-wc;b_?HcY^Fex6o(dCo{7g=P&hdpox;PWj1N-NM#_90x;xPVGnU{ ztVWw+2MJ?2yNBTDMnN)}FP%xYzmhkafx4mECS}YY@O=NA_mpB+a+BX!fibJ9>HOAZ z9kR`VRY`YCalEmM^cN?&>dU05cGHFFRp)vGuUrKS9sRejpd!=!&P?!IZ0oRJhnI~`Q8v>19~BcIhJA? zQg!D2p3FNX-B+I^EJ`2lx?=ds@R%zm&$jP#zCnEb;XRZ!TYDLp^?AEKpW8TZAnREs z{vJHgV86e~&-9|F`Oq)fdH2qU^JHoe&hBndNR0dE90u z+h=YF`WS~*IceWgB}(;7z%RWbT>N!t0lB1(%&xy8p>E^9C9S?EdStxZ_RO74zE8gP zu}?cm%v{9ZtI3po*ROUx3AEAEGybrXvNvH#;Pr$g_MFE1EyXw9|1A0t@1GJO*1S(F zesuKCmRC-bU8zTZDuPeAc>A6xkl=xD-886qXBtrSo@^sa)s{BwMfwUAribmKE_=GJ z1iF?Z8FX_m?Vyzebo)cPy_tbgAmC&i6kPJzHnhl7N^klA*ChNlv;aac=xKIcwI)!)0f9AKkSFHWPgtvd%rc^VwI~_9s$<%}s)thYtmL$`zD(@NGG-fy)9^|G)-^-z$M7 zx2Ng~G!rjtX66ueUaM@Ny!`m_aNm#%ZPOM`;o_pYz?b)51V7_>m(&^vLaKH?z5j72|8T8N)so3fDSGQK{9BF0X9EjFw!$=&+kNpM5PLzhz*J1&0S z`|!M+OkG?5&G69CY@6lDSDtJ=G}*><&D;E;J&IssQB}^m7s$gS*m_{gu2!dL41$HF z*m`Wgv{tyrev!D;(qsTxZ?vvp$4#FV7Rs5)P0P+bT;GVGp;PZas}`d>cInc$-$8mro?@u}xU{<&OgT zEZwlX^|I&r`s2J_X3~>a0o`9)(dX9 zFP&AbY$h#7B@L|$wD)@Rv;JI3%l!D3H=((OkoE6qMJ3VfDEkQhJ=GGgLGV*!5yO-bH08CCyFfBm@aa6H1quc&*^$-48ejy}&g`sCb!5PsgTlOY=mi7u|=4D+Vp zs@If8lG8R_cR!KBlWu8x6$W%rmh76%b=7|oj~gHe=nGo>Xm z4z=*LYUe8~u$d=OoFv|zFNvHjUE_;`tIgvtlwnMjF4e&mQLJ}OZxJ;B87X7Pav*^D z=}9Kw&7kq{7zmz$Yg#8JOS$We<|BR)HV_oTD(6zTK(g}LAo&|A(Wo+oV@5e7?{fDu z?A=h-70Sx8I?^fY2|_o?Qr~w@`HR)I6TVvi4}0$&*3{Of566lPV+92vHbhj2g`$*1 zznzm-yi2ME<#v)?X{j~t*6}2{lHv__iUfj1=nQv@RxXZSR%`)5X@Uv z1s?dvih>pp>4Lh5BZ+~aQXX3&Unvq+up*o`180a>$<%{S4Ec&Nl}_6mHN^VKdP#{F zr&S5BzjKc0DhKF4n~wap5M-9i0N8*8Y^?dOz>-+Y>qw%fm~OLSo|Hsg1T)0RWfe8N zWfIr`ywNTBcEnDM37_B#G{n)cO{LlKCgkMHU#D$CeCx<|#Uw^(g;fz?1lx|n9|9oC zc4t9h2ADhz5Du78qCe(p4zs&?ux47A)TBz#Csw}QQ_zO^(6p;^NVL`T@PqTyNb_R@2U8Kjhr;FR0MXZBarTW0FSO+7 zWB_yrw}ldXu2CE#7Z1>r^KYILqQTDG6)~>=`j4PZBXO1wK=^|#EL)^ zeHigc(Lw$>{Q*8vuT-V%)@YE7zU^Fz!X!ZJakEDFK~@)7kM)pqopQI|uvQAK5;GU? z!sD2h)ANb<0OXF>9d(nYiJTI<2yZ;y7{w=+bJ24K-gr#wKNS>|COLW&TeFArNmIHF zXi_XEwV(zBsox?8=afo+kyp|;$mh~JAq<{G59Ymb{Rm3Q7-c-p&|&zhZ+Gr(^#d&c z*1cLl_{a(e7C?y+=60$Wa})4Sg&kv4@vmXO8f&z-0Ig(in{OAIo!hZ!TRz|^Nt!hwaqrAt+lGnl(P zRq#r;joCbWd040`)iy7Yenc;ng@W81cd`rM<_MA)@EAA5K^BkT&ofanK!So^Kx+Ur z7oe{~I$!dE&x^7HRg<>NtwVMSp{L80140u77*qpjYEzux24q0pGTA*dts*_`O}sCU z?!A9uY0a>n)VfxrAYWwE1Fd;s{pdVf}q?k`e!(NEHN-rawl(a?O*gE2+t;h)R>F^q@t(6`@lnS%* z9-zZ?qZDZE&^z)-vGmFiz~v_Z?sv(jKL~veig;D@Ncvpg+$aFK_7#UoF2H<&h2mi~ zKYMXx*51KTc6rjiV_Vy_bvrCK0sbo&cg3`5R~KAxhKGD3>L&<|GsC2(&BY1wr4T5w zZs@8mke(c(E78_*Y(cucNw33I62ySTuA-kc0U%!v#7F?*C>p$vz##^WCT37o=(#YUDnr(g z_^vhB+jicn1Vx@{21xZ_&tM8ty1Vioc1+ug{>?OwhUA5>HW1oF6s{s548j zxzhu5SA+PwT0OIL@h~_L-g$ZE3s-sA#6Njs566D_p0M-$@}a|EXft^ub2s=2T(Yu* z@`Y4ez&~dJaf&5U(6A$llWg~ux+P;ULzM85X81wO2JUKjyh4Q|_H0q;xGc#skdG8j zH{8+oBwu)EIA$x$t-MZCDQunCjovJKi)et;Eg1}clUAFwOhzxU1jq8U$mU~(Xh@)0 z24Kn3%4k{(3lz(|LcEGZ=|x@R$@AQ+=za|4n3?Opx+8;xF2UHdf8C6qfR_3H7s%I&OF;~FHE$UXGQQL|IYM=*YY_7LhxvDmOfVm!YN?)cSt1k{* zkkW-|hAK*T0QivzeRJIL)OXHc06v(yCuLB-`rJ0Di99jcmg97&&)!0>glSoM%B;6c z_l-Hj=ak`!%6VhKAL(yh?*ZRur_D%&)Eqet@8c6!Q5V8tQX^!Eh*-{3f(vLH;Gza= zar$lTENz6~LgIsj*%`4_m|obo9tQnH3xZE>@2p<*j`bn(#dVbIMw3q>_HgrvPolDA z^LXUm&-fk9mQ7jN<0H7HjTVctFK3@J3Z#sgj|q-AJi1zkqS?(xST8k1Lho3^`}o3O zI)|d0dZ&1aYDOkm&<6jD6a-zKpu_|k2Zjq3Gr5m zzjj|FZtRO0MJ(Tp?W}2PTE+HBHa)+&MU+62F$Y5g~k~t?%#DX`%W8 zOYA02QJlqbh)0)YFRfCEUtADKUZ#laI}Hj!=qCyiD(&QjB9G}N%t%BRy4CO>8Cv&& zU5iCP%s*8IJlC#g#DdA;RH+WY|DCaye~#B2v32jxor{iymNFHl;xH<5wSMAqDvmCC zj2v%y{3^stFZ;5Zaz)Zso-9O`0PJsP0Ezm>d!uk4IRg{G;kq9@;0cu=drUQw9+lV3 za;u(i0QIkAz=ESjYwq0LN@ls!7a}w`y?cbnzZ{TV7{|xY|Bh(Aeba2b(>2?6h*O%{ z+Lof-%dmLjd*Kz=q5njG(k9dhZ9B40#=?UK{^7A4kb((=YlIxex-7g+EX=*hRB(4P z5m7PffOi64jag3h7GcV_@aw~_uz4$-V;fG2~vMfkV2op>lv*45ylkRtpS5M{t<_ z=_=lx7xZ5lBCl)#VL8>9UJ0$xHs0j^+CwEsQtUAX`y6?-eIYX$M9f?LSnnp06%qU& z#AO$8dt~<@H*9+XsASI1xkq&r@zE7@MdX0Uu{TaIG~R;e?^H31I2w~tWSfsc3z3tr zi2k>NbQ(?``*vfwP=GI^gL(%wSrO!(3wU1+0$Xm6^b&QAEI*$fYR9T%1wWt?MZ}M} zcj(J#Sn8fe)$({(kOEmjnaVNN6QGw<9x0lhYSlYQ_Qd7tr)HO?a@_5Rp}TT@pD!hf zEYa;1l3`KUh)_zUwSl~A1$q$`4{;L8c&J=N8*|GT;zy~%&@a#;H#TP%aas0{x2@># z-WH(xPTYfEjZFohi$ef53^^${=j&)w-aKgdo4EcUt`&$z4uS?O+~!aj4)4yp3FM_j zr&AYB7NbAL8sdWyogz@0f#X!aAa|pekyhD9x>ng0hVX}0Y3tU8{nWE`s-C+hBqpVO z%?*qRt%Lps69rp86z=iUPp|tg>f?2~ozr%-I0ACH^vq?O~DCbO{|EkgkKt5?5GNs!yVCz&MDa z5M8qha)cAE5zE{}#pQzzUq$DDTAlQ^4nr5@cJGL*hj?*7& zQ@9Q_iJcFI$H_IQhv7P~wjaMT_fRf_8Y#@kgo`My93-o7o6<7)#5Hw+u4&ZeV%M8` zx$8I-`y=AxaM3w-L_-XcTrRgK&tBw_Ad++K^lSf zSI4>XMFX?8lbBTnEpQ8%HPN^=HA!3G)maFp4bgtykrv_#`eP9n)r4TWUGErM1o0yl zt**3w{u-WWPR3?(DW-ct8Sonh6FbQIMB3x5L^*Dqs5jNw-#<_^R9R^EBev*_%C<0m zMD0_R?lVm{aL2&30bZ8AUamy@#sj2zz5-0UUj-y0@Pdg-^7Sx*&%4cXj#5A@Md_7G zRU6g}s3axi5D{1Q2yWIX=NmP8F6a&BvzAk?**mA%Qlcxb1B%TU-F<`VTTwFkzl6B{ zJGkP1Mw&lwj4WTnkp0SUwjn4$fVh}?ll_E;rP!6T=|B|1Fis8wZ-s*LpSNTO&%%s6wx62zNC~Y_Scf#e_ap)oi z*`uU-y!TeHa+`VMx=_ywXpBRb@MH&PP(Q$RzC>R0^A1%0kUXt|AG?E}@-+Lmzs-|k z>NkPH{3EP>H}D$37V0U$aG{BLGpJ~=tLR~9e;A^rG=qAP40b$t1{K=^fh})A%fWSv z!oNiX7*UG7JTwYdik{i~q(t>EL6t zEu>eqXZLg=^l`KQk(WGOo1q>V?J)Y*!Ev$aRj>}uGpJgJQ?}oU$VV))9RKn|#fI0X zqVscG-DO^2)l}u7V2NiPO%uCJDOvs;8iQa37vr?aVyF8vC}`qmKlYz5J^SBp-0Xz@ zZd(^8opfXPrju)d2!w3m%2xr~u?!gXJvsOtM6QKAWCk^52s9+bW#6?&%(ejrf*bms z0H0EvL7AF^uj)Wa*@Sg&%Y$QM3d0m>N ziD>BoaeBcL{R&NyPRc%Drcp$AuO?mgWK`Be%A~ynhw}pn^;>lCi*-cKnbOX4+>fclQ8m9W1k%Oc4#1 z`83#!f_)AdWG`I;4nUw))H$4Pi8w*aQ_tUMrgtMEGj?61eI?)qY zTWdctB!eE%MJWohWntjj;mIbmXHX0q*&Hmgj`e%ga0pKnHG|p)o`#kwDu8bQD>`7h%~ubF33a|;EB}6-{(hR8 z|8FzdoMhEany_i~{DH8~{L}evhW@klAV@v6-{=F$0KN@cs+FC?B#OZ4e-ns%3i#;p z3~H=1YJ@cnKKKNFSCH6`%KPLO{&BXPz%DZ2@%iKU1&6`Ze~^n=4F=ny0HmGRj&EiC zhjqjM+e6S&?McXc1_feTAseB7cRZ|tM;NJp+Zsr;Ko%pjmoNIC-8cM5e&I*1oCjbH zr$2A-?2T^3f0)X7_3y;9UkF}13J_zjv90kNXk)kk=@B$@5)`muuF!|bs z3Rb9-p2|EAO#5taU;t5ef`hXn_eoC=8^(RZeQP_6X6Vp^Bp2o6cGvbE#xyj37(Ze=&rFb&ofo{OA&OOU0^G<2Wt)k}j=NwJxTL_6sbV zb3^Mh1euJmY(wixcKoe^oMGzd>G9y-_fmPf_19Pm-pAK7NuOjHPb$>zo~j-r&Ch5n zvr5!Zis{&2^(pnW9sVVYKZ642Wn;P=U<1)Jr~_i8hEGHRpj4eA)a~<|4e-;0?1eKZ zTPHg7MFI&fi`jXi+Wq%)r%9WST z-jg@=ow9WKcC;n>UW}+^G~V54%7p%O+=RMkyzGCHhv2`+SU@{32gDj?xgebX3{Dqd zA^}yF3Wa_Ie%Kx1mM;vq1NHy_ofB8em1@Lh=8Rha`YODmVsNX(BGt`KEZwlD{re!V zy^y()#WW;H&Q=_m0jP(Vb;t*x*`;4@+7M=XKFn zBl>VOKT^4xi4x~TKztArwy3mTF=(gHO7=MML}y%fxamrx`Lc(3YtO%=Xs+n6t0Q}p z*F2v$23!*!vI6uM%oA~In5)Hdy2!#oe72@y<9 znP>YM~=y`qi^UuUktyU#4l>JRW2(^*;J8?`@*-k#y2- zPSsLe;@ZTPNFS8R>wh5Q|7VWle=J@7+c!b`fs??R01m{h-{9P;fXO>TrUD#n*=T%H zpd=>V!L6mZb}Li~mmtb5)WhA02dTS7lab>*MfbNUk-856-xc%ei|6qcmzp{&6AsUr z{={!s2$RY>SAj}1J_g-SQxZjm>F&fUQpgp!4NW6HWOToZdZM#>VtW6ye&lZtzq!X- zhCJKNX&-32YDOY^s+2#xy)MV&Z6w7i=9g!#>rF}R$92$_Uh$rKlPZm`URfvGEzUTV zvE*)j+tp{T$&vAXcm1s0+q2I$^jb)0Eg*>rTK-(^ZU{E~KIVp>!!&j(XRdA0=up3_ zOJD7=njjiFCj~G(8IC`0VrNMxE4rV$^=Fv}+pzHYXNmq7AOowfgl*doxZlx>VtK%;k!qCp&cCAZDSF8!+s*XI}Ll@LjeIx>fe|Ws=q|=Hu?; zDNU&|^OW$-Tkn*`9$9vKg{jv1`Luk7{S$=Lq#D?J|NG-79`!u_P0-x2zgTY! zbIyb7`DksHsviq9j~*m{zddLN-Eei^BGwrB;`Y*s!kx!Ag zx@qUWC~o~xkl54ojr|j9a=j0=($HaOzQ-APn;`AYwa`hq zfySq^^(i{(3bpb`d7TioNkE9Gt<>34t99|ca>arTY_&U8X0oWY^fSo^de*t^cyMpe zsxnKneVHoz@3d9ahoZTMb>C{S(pgRPdg0Ym_s2v{Bo~QfHderDQ*3k>R`~I!Bl%a=k@g00%zkiP@add+y1Z zFZ+&-y?@WHzIHb9z|U%(aktmHsf)4KuS7@WH&o#g)c2hfGipY$f|A!MLs#1DcWl6x zPiX9~-+wQ2V-wv&Tq%6yLYz^T&t$owP=|eKE6Z?wi(L&4blvm<)|R_1Dy1$1v=c03P~U2dmJ0AINt2x1aAV6HhcdGJZ__!f%t3>< z1BEJHG2~r_UJ1_bUUSCv{%+#`>D&BY@*zfn{k3Bf3N%jg_d}GY7AObtIxCVK!RahN zbOhMEZ~Ee(GU&mn(#h4HqiZ%i%01=i>Gg@mXxUy`sL81VDAh$E;&!@tR4&1~>kQ4H z=0yEDNS&Ls-m{(M_wuJUY+o^rk0=Scz;9UT9#6|nX5FG*$SR0UcP78Gk2JMxLzcR@ z`aEz)T|e5l_guev9EGGwbaKz$y!{P_Q29z zQkLF&z}%_n5%&^OACUjd#n;G$?2=g!8$Xm*+uDDkAZh9QQ-OYH)mIxc)n)JXhME%m z{DKTeKG2OGbX;D5jxDje-boO;s(HM**a2IX~Ka|1JDNzIOWNiPN-fE%4YrOKUu}{MQ0tsmg#y&1LyXdh1h&| zM#&5+QN|PfD#Z6ee#nY}pR8Ih`cT?XkLxH>;=13t7TfW$-rTMi?CuOIZ3dOY9!Wms zsoNQz=~e_jX)S(gc(gbf4kIwyjPbACr+cIP`+}m*Hsxvy$EB>i?-ry3g(dlqNd6@e zPh1KUY9E#q-*LIqcmC3G%ZZ@LAg{GMowT(aM_ko2GRFs44qT%-|8^^N-En+#GNtw~gQ`r-}t-`b-yAItc zYE_Q;@oQ4cby`+74)vcpxzDQu+8V74CKKePma3i_jZQq1>UqU2&OG)&)bW1vY_79+ z^w8v1*4Epbis$0HY~}eM{ve3i$rK7NdB)u_Hp$=(sW?Ro6jiNTsQ9a7_ndR?oFsbS zE4MfU>mgqfIs06Dhr@SwWdrMxKCZpTV$Z84@0Isdwv8RxncplgPF$Y#!QaIwyO3?+ z)jB=J`;gZ4%$YZR>Th%`iD%f_K+Fz3ReKzjtdhKwd+|s|y|5yEJga9Xr*4ATKk#zu zLvD7qr}C4*YKOXPqJ6Qf<5*0M8kl6m2S#ZQY=Edl+;G{ zgUyi8xqT01JN>rilYeUdshwu{S+mZj>MOyUPhJVI@`Vx`wDT(mN}z3XL1v)Zk$qdf zeYZ$&FnD;aP)Ig1y;eB6xNn%Ee5tQm$I@K-xvitri!-%2rHJ>ne~$O>@|e6wb_P>X ze-8djOeE0#w^DOIBD@UxJ!+EP=Slh-iOwePT2>e9_sonz4ld-v)l4|px_Mk%z2TG8 zEBkc^_uGKvmO!xcoMKha_c!*YeGZmuOK`ts_BvQBGgYnCvAIruI$l`J>jN>T(z~Y< z2J?9xQNZyXcKuF?tB|OKMx=TK$iveIlQd(GQMJ=M2RWXpec`_`3Q4uE#&-s0zH)7K zDJ&Qp^;-2=E2K0}_Ie_hCxxs5X4o&ztzepGUA%hxPkZ}w_fxH;=JIVGnSmf+c%x9g> zVsQt9G3dVjfRjwS5&LP=x~^6D20iEKcb<^l!>$L5emwgzKJYQ4FOtK2&2F5STIVz} z^tu2DPW$=AxNiePb-K;p8qGOYQai5Sx`27#`{?O&pDKIuUUk(h^KM=@Fm%Yns>zSj z#(n>M;deb$x5n7;Vcgo|m<&PqlYKDww1%}0>TG2@9r(7DL5Zu0seUOIc| z;I_8%7n%no@_dy;vu&=EpUl3G?pn>?IP!wcCUZu;8=7w(isbqY?%z|fVZ7Qf;HzD9 zexjtHaCG~eP{LLa&MQ7)>eqVbU#FBm*Yoo3M*&|I86R}2K&_qYh&!Md;$z3Q{7C_1 zc9Yh!%)W~dnOsx1HA&fsRm`YnswgzSx-3`Q_j|=ka)8h!FsKb7_6F>?#o3awkwV7Q z1m6DfdB{){b#X`SPnE{%N~Oqk_d{aLF~8oWHJz}tI_Vfq5*_v3e&Tg==Fym=g}z$l zo&g88HDcPkH-t14TJ2aHkl@X2xHfe@CT0gAwKT?rC0c3xWCqoDSMHmcp+OFCiVdJG zq&_GH-0?4lhWm?=54tk5pd_qm4O7dzMGk=;;<>vH_y@)4*mrh*PR#B6UdT%N@qWYA z=2U_;2;ve&wDXV5w?4A?E#D$7eCfgR|F4eAf7{df-~I>mXTWnw9Nx_;=qrn9Mb>({ zD^#;Wc$eFd#XcDuRu6I9&lI(lsCxVLl!Q!dxf~a;X6(}%rGOSCNu)+%Xhx1n^ zyj^nmQ%^+2(KUHr9>=v{`+4ey4_ys`Im^%yQ< zt7nptAiWY#!TR2!c>GH9bV||!I8&bQvWlOxIeVDG+Qd{jBgTA4aycCB!{7h&J#p<( z5T|jE!scILZp!#%O&X;ov3_|%+OEoHl!+d>zmo31i}_ z$Bq9-R;PL8EVo>aDxWc2GuvowEmL#os=J|5i0h`jLhJAe{0h>wsx9tG8@^udJQhEL zI@i*vWm&T1^8>DZ=b-X6z$~X6w;S6ZwktU&_35b@3 zusxG~pmfW+;-mYbJ$6SE)8Hd~tO}*I#ve213hwObeRbXek_=s0lCsXnrmM00_I=rd zo}^q}zAC!ZuKCfmOv7~^CzCW+hozpL8j^(rN;h-hk>8iM7WIwPN)NiR^@&SM7Uys< zVNNSs&c_GsJ6HNur>ZZMicdS@|AX@#xZF)nIR!Zun*uFQ6XPjALM=MXDxCV4bK9cL&&C|jBMzlEc}Gz& z{eE3X?Z+KO$!cL$V)p7T4IMqfuWLHdyFZ?+Zod7tJx!-j&8qmz&#L2;Wrb@7HE))k zw%VH-R^HP>pIExVebtW5A!pB?P&oe_g`ZOexov&<_*DMINB68hX|HlJ#|Y;4X?;Ew z?fKcta_UoueCy*+|J&;MKaqa_r%{xDoji?Av+xW z><T-?Ww(NDolm#X1kE7Z^oS+}jk(uFMYo?qT*xOHb^#QSDR2 zZM|9}IR;ZUD?Tlv^z>FDD=i%j9}=Oxh(T+BZD!&Vf2(VrpE4m|ADe)7qjr0<)QJ+Z za^y?I60Un?)t1qX51%d>o@cr|AsIe&>4d@4r3dNn>NAbIB5$t~99m(GeZO0)$3g&M zf1lPPY5rE)3Vm>r7w2It=mK<cr5P%*rl5ZfDyh+l#@>WFTthC5rPoPLcej z=Gbj4^-X}rnkP8q|Dv#P%&UZ)&a2I+nXhz(%Qf@V&q#CP9ocZjtVgx*M(7x|J!r@2 z;{zTA_QL`WH%%V(qVK(9r!=*>mOVYCnq(xV(Lw5}42Ko>zFk{c1j3Hm0<4lptw)ke zg}Z!1BjAsJpWTgms-wYp`}mg|-eF$XJ-uQ_WZ=p&GqF6+PVc2#NA{B5OcjJ-;f#Dyl~-^=u{;3%e-ar;@s&!dMHCIcab(QN#`#cU)~H@+x@IS>vtM z)W!BBFHbfpOi$N;82CC>QhYU=*WpqyZ8Sw4NjK|_^R&`ff52SJBojKoD2BG(2X-aO3;HRno0d^i*5o`e_q-JFFp z^4Bu#BfZbU?jo+k+Y*3>v{dKSmaK4e-^X=0uH9`rJffpXa@!%dnF5zaHkN0aGHp>q z6oHsx`(*hnw|y{lIdP|aRjvxWQxH-g#b@1?FBNq@(4j)WC=IvkkmtUv5H(vg#`-Ja zR}FCFH**H;zS`zo$PZGmjc<@1J9IHVnwbE_<-|4jOm2`@09#@TfTKQ9L0WUcM)+YG zl?a1VN>U`d#{^7NZ>fIlZ6a0~q&7rf1-gP*l*u*3zrJkD$1kD024YeeTk{d8DMoW> zwdwtwT&@m2-)_v1nh_$1#K>J+8MsJK7Y&hJ}W?co+(qi_({v?Fms((mSzN)2oa z-!?lJuh>*t(9RgBS(Ak8pgTP z()#ts31;sC-P4Lay*bp?f9wc76`VczE{MaDYz56nw^K-xFtJJ0E!+~slug@6!3&PY zWx;Hxb)vXn#Q!D5`g5}_>@0wk9H1BOhTBTlRt-A&zmyvpIU3m&H{}ECvB1->nPAZ_ z9Qe?@#G&44B8l#r4Io$`JxS=oaJ?O2#cme7V_UH(O1{Lr8@~=VlAQR8Q-n{S0MJK+ zS8#BRIvNnK&{YPT`q}EbZ3rQYVm!b$&luno!J*Zk1>JVdyFBw{3zr5FPd77L-P48~ z(Z9$?0+0>~J80UCq-{fLAMk7SiXNNtWuKkKNSDz*13Fqd2)7MYL+^wmYA)TZZ>|DR zcfx{?&=m2JUQC^SP(8%l;?6E4`)9-RYS^8d*tAA|X14MdM`uEO?_f_lt5MGN_gfh4 z-h1IBVn8}7(|6n@A7>rCss+3;rEIR{3`#R7AhpA>zrmyhm~5{*O~l(`05Jm(P>`93 zNs^ngSmyd6b&Y1Kh4f&*laVMa#K!iG2zrvV1yFQFg>qW&$#=jv`5pQK_Q_C3f<h8>KEu+5Y#*Jk9gPw%SfVq@Qy;aD%hO|;i z#ui&8nBO1VMWT;ZrAF);3>P3shg7uWZVkDLY~vj%PzMe%VV;tENaEZo>a zWXA8!5I6I4D@?2$y}NC01IQ?GDQLcXC&CMqg&A8srvz3Q?CF0%A=$_B4z*IzfCq(^ z#R=(o;%KE2duZMe{D{JkudIDJ4Fzi>8tLYO)Bb6&HD^d_ z-F=26y^|z3xVcT|YX*6A=qKV=AZh;c`C8161eSKzaO{ZBICPUw221G=KVmM#=U z4{=7I`9K04hvg_?RN)1wl#v7BwQ zvRt!rKp-&NA9i4mO!vIN|I>O!&Wa2}v4 zQ7tQSt@LNAQW#Y#*!%f}wTMZp?>Zm162~qA2EJI&H523FT(TX%x!a}0N=|4LbbNov ztqt53lT(xWv)r?oYsSocNu!6=w;8VX;?VFS3M&zh=ywby_j}Rqa93gp|9+ahM?4d0^Ht=I`rELm{yr430&(g!;dEUakNbvz& zOVMC~(@8=@kT0+JI{OGajT12NW4yWcot^zX5g>G-ce_?~;04)z!{Fqa{}YZA*UHy~ zRpzQu@o+*=Izkks-=>;?@MO7amPNW55XJfzxs;OybTzou-DKUUv^>b+H zFLa9{d6KH)$mHergQL^7Nr`3vA2LemlA+ggo`?Vmj8Tb2Q#YK z)++h&Nl{tBS#F$5k;Xz#ojSZl^lR;%1Jj;qrOMqo!dK=7o{-~2b0(tO?qkyTkq7#9 zVfuN>G-c`zSuW%ZN)YA0i;!6}paz%$gMj!DQ4J8`}?WywQ^s&#^EV;E)0o<0_X?YIq_3)$&KRpqJj{~oRYL0H0 z1xnF0W;upx#ZdRzzRF09YEe`Gh#gt;DHg}_M4b%%gp|7H zl!PkIf(V#ZowTWGcoaD-M>UQIdncc3cv5XW4X{?q(H7#>f~b38m1jX?^&R*PL-Mr@ST757IwsuG>wwOE5LG?X zG!uh{P}Y*^vyla1cO1_*j{1zZUjFudZq(<5-bVvd_SVwz>r6(mxr4#ag6yCIt6Hl` z8)>0U0Juw7T`zfSb8x!ICHR1JtGr6SPxiV;mZ&qXy`|eG!bZTpMO)F&QNA-#yxw;Y zzd^wk4z>`h=XT5N>f1U;*N^BH8ySVRWTn43Mxdt=UQLu+cFJ~9U{Z&Va;Nv(n_ErC)^|?M2s=XZEJA0>{9U`vwf(eZ%d$YwhRgN2v8F=8+q9*_sB{ zOgk!lh}%F0o?p8ZbY#g5htSDlY&Gj<943!-|Nh&Ia}J1pF&y0`yc?%f6qNo@qGnB4 zL)jR)0R&0>qc47}W+*YugzJ$q#>1ARdi$YwfMw;0!A{%K)@k()$HzFHta$p_2`?+l z;?553g3s5kBT%Z3lG(xKgc3aFhli_(71w(s{)5Z51arCL4Xv`-faP;DO>)h&_4qWx zI-x?R(D1*v68I3dZjRphq<4h@EdM)OZ*$~ zOBAlGzk%q3Lx%m1Xf$^^gCKlBxay$_9(F;lUBO#E!d1@IqByXi938o5jEB4}(a3L|>MJOJ=aB~Y)O zC~O9`>BOABzVp}m{Fi0pA|;|*vnqFS|0Hnc@8ISt;?3TyNT{t4pDv%Ai^>0P>aH-V z?bDvKb+1FiGRl4ZEws@aUl+3fluR!m(#zSwtf}QU0Ldi;&W`?$2Dw_U0yL&JE1B|H z$tw*}v~4hZ(F+ock-_)=c# z4&P0HS}vnGIU;q5*I25qSm#sK*=x^0{Tlv7Zu4nv{+HPF8%ZYh#+G~~KZRJAr}wW~ z3No%Rm6fduRaeIex`&4dYL9Gu1sNx64*QH1Tcx+*(wFR~V!fpRCx0Hm67Kk^5I)YJ z?qimZckJx$ed?$Uu4 zq}}}%t#X~+PEb=#KRQYzTwqg0oOgBY{-N@F<$LQiL(5xiV+}&ztova2gq(Tt%2?$^ z@8N>O?x!kE(Z)v=7B4VnuXlQ#9ZnxALd@VFU3+Qu{MOL3aROoRy4@4=?N*q*-)b{{ z_v%$E9dY5KesUG^ZgG4rfRlV*wJ1{GzuI1ivjb$JuT?(W@Rw;v$OO1*ivo~ z`U&10;!Z)o0p1}Hx*>=mzGG;x$*?yFt?y?kAsUc?ywWLU@3FV;Mcbab1X3jz4=wXE z%m}}n^{Xi2)27(o&#Dc#yXmU{xBT}s%JAggd*bEz;d3g-(JQ0qyHb+ZnZ>8>&(zq# z{Cp*nz0c|-d6JHzMX7IGE1-!fLzSnLBiQU$tIA%$lfZ={dmGi`!vGbq21eC3F@DS!@|}fu8|>HxE#}#XSvNFXTzz-{#X?F}RZ=AX8!LLu3)4+V30q|v{yu}C z*>x{{^*WcQXN}5ZmYk;Rxt)03_1bx7+ld*JTUC+Xmc`P?$-~Zs1eu%QzOKksa*cBJ zsYp5WX{U$jPkEdw;)d$jAxAs{D{SEYVx}{-`MiaBaiLW$9CP)}fz>tna)Z_*vCPPa8!4 zVSclah(nuzjlQ}&Os4wj4;!5)KQe2h|NAe^Y98S}W}K|~hvNWEDa|?#^bPp_P6F^7 zX7x^cR_}28p~jL~zhPGG?10~JkqV+($^Nr`!>ron1HYjX<^#1GoAn!j+C6le^&7&) z74pa*fA|gHG}!!y-|*L*{#vKMbYEl^nTFI7c8C!~->IOuJdli>TRO1!zkit(P+GC^$5>@JK>caPO)D;LEkL$svD zw>~!z-W1#=MQ}4Cp04UtwfA{67#QAlcae*$kuhRc&Z<)4S!|m@sReLNnYX>TtlI07 zg>)0?Glfte3$EgkK9)!`qE#{LL2?ImmAE2jKz&mPz&icbuqJr0DPpPjs!$@sw0Ah6 z!J{dlQzB=rZo1ZMZaXkEo%$^`dEim|km0QcQLR81FE(m*z1uqkg7x>jd=7NI|KM6! z(wwa-ab(Hs8S&rktF-fJYI%%Dy_~=Z%hg8;W3_Q6FSCQl&`|N-gi;1#)A!Q^OK2kJ z_sdmm2leBME+wba>Y#Z(iKZ4U!@X}>@}-&c#n1d!5YK&||30rMw5!3@B<9Oi2d)Fh za>Lu4IobWXA378DN7;xX^rifzU!>H2l#Gmw?LbULPIR&AM<+ee^4IdC^loSooKVJ| zbjLisN=k>5O<7-a)AD6M?7dcXPIahK>YJWAO4(oUJrh#KI31@uCkJE>{Dj+{{^TFR zG2Zk9{u#DCP?7;S<6L;{VU?hy1q<(RdYXmoZDFdIceBDIlZL!drUoVWBT)^vYLK>x zZA?fZsjp)*)!n>3^ox8>co5PCnoM;s4p|2OD&6*m(-NO^^JV5v9;6@NYA+m08{q|g zDNTw!RanTa>(7}SA9>LNl>s;H50zL#9G)zkNx8Pmt>?POWlLAF2 z%sO`!VHI{YC8E-B+Xq3^T|>3F`@Wzj(!2`E3irt50Y7DBE$4tqJ0EZRb8u*bO=wfW zL?IKx5@A&neK{+|TnbD}K-vlXBtY=>TPEh4P?FeK64XTikEFCRx5L+)`HE2$`1KwE zQPmbQ(`xlCpofzVZUZIwNMiwh+29-a`OwL8_Ct2DnP~&f4!h(V<0(G&TvF_sSf+hD zj@Q)IQM7Vo6KgM<-P||mf0*`#u1*6+YMCzUJSLpE2?Q?c$W@qklOw?|XlzJXzSvE& z*^*SjTBe8IK&h?r+vBFb_R%3q=SI} zgBCM!2vOV-cB90Z@2T7cRR}}&40^+%eRi$XtI3oLS;&Qr;$;s8lw$XE?sOWcvD^o_ zdvGihJG?brxxEE>HUT^3i-&@C5q9P|N~cWhY*-DDwpBd&9!Oz|tkCdwgOSYcT+Wt{ z&}xWpMq?MU=2HVjecgVyki`Px9TlB~9C&GkVS1<@Jv3Zz^ALbNAMfgJHW@A`Mf*%=w*~-qUh%*?a@fzZf*48Jh3m6p0P_=!tu&; z-5@sH>KAtwA|w<_-CbFU^arf$K#WP1=rnNb0IK`{u=nQiP{04)I7y0_N>R3HlSnmQP8t4kKm}vP@>gcr#1))j8*T z?%z50?>z4Naqhoy`Jf|lNepp3(vb4;O4tjW6)(~}{p8Y)H04YCv~-hB~O z)Y*JbdGeEA@a7;UlFgjP43>OaT-?_i6C_?n=%B09K{_IqzLJhYLOT)sJHt{p9{pbJ zRnp23(9-@}Zq=L=&LNa@YZy`RM*4%l02yCu26tMm54ZnpB-z-dJ6Kz4>xTBNOK^BN zZfbNepMZ9V@E1*G^}5*?G5@y8qE(Z{6?KCdKd8SDwxG^CJrKt+XHb%D%%v}goNT&0 zem@8m?zpiG;sEk#|FCfqK@Wt1>u8#ibJg#=f_Qb>E`S(Uy~hYp^I?|Bgwz9k^5*Vr zPtV9UTaW5aZg=q7cgDQ~1r*0R?@WG3e!^$h@u>7JierK|vz+Pn9q%Gmfb78xBCyD0 z8Zg&)BRz2~AJ}ix?j!uXY#Z3CDiU-Jnk<0$!7ABTi>!*v=(WU^qlAA|R?4g-Kt@)}g(v1fdkMxnvDgAUt|ppp;DL;bGh^eBDh` z!9^YwloWBE2UB#%StFI=Bu~$Zj*8^fXie70$RI7|&A_+JT`6>3xPx0>?OZ1-6J^}m zik+ObnUm%cw1FZGR-!&F1AJ%{c}SbrejC396sQ%KNT1I|Db*vi17|%c4`dsmzkk}z;Joyu@#7ihaNNUBM{jM=+Z4wLwFph7)S^YFOr}>isWqJNI5(d= z9m$#)DkKj~(t3YZ7`As{dd!KFfz^L7KW;p15_>hB!*Pn%TON;WhOgGlM-g$Gek47o5^kPrAvhYQypgiLB(yqg3bHh51{>7h*d3n@M zQP1Nv2WzbvFXNnuxnAagGYPEWG{_7C7g3~t(b1HL9zdbMKw!XmSRhav=8QGb^$4H6 zErj}M39=>7u=BfaJSOibPxn@R#MVVx0T;2#YqI=DdVXm>>Mz@fEV$-OJu0|Y%XGYR zFtyHtJU7%@O&iEwm@Mj|*jAS%p}yPgBNuHrcEfh9m>KINAeG*QsdJy8ECmKG{Z8Ue_dIe_R&nEsfbuuI2SLz^XfP9NAT>{F1P#Ufa@EU#Pujk6Ony$4qO$+G^9aij$vGHJxc zJjZpY{bLBg22;<|J;TQf=427{HmBHP9{>dhlZCnvD%8ABI3Rb6iJ)4HF}nuHE(=fT zoD=587-E(bvy(3jo)4F(ZL_`$NZXl8! zMnodtNu$BKK_g>5+WB5QL?5fwQP_%i6ObBeURWOYM$j%ThYVzq-C)4>txf`pPXKe`!dlXT~+LnQV2kB zmI9p2-9!Qqb=9~hcE?*uUrk#b6%4Vx0A|eJSXW{rqyxy?ULh=wwk@j0xnq`$Wq7z2 za*b5He@T3}_DOI@S$9>B`spe!M5DLf>Tjz@%Th6mw8@eox}eRQS8ZRCP(DsCkXVG4 zHbQ_`b1xR!0{SGThvyUV21SyCU37FZ%eIkDwPmy`Ko9#drWj)`Gm)?te;}C=5nGU3 zzje&M$COg$?RB!OEYsFL*|yin)xq*iS(ab$6ORCLWp57DNV z_-(;lL)^t88uu$Bu4*J@Z|5IPVuCnUbI(HHKv*cO2o+V&^c ztvp@No?Qlq;DsQOjsc1E|Ns6Er~(`c`Y-zI|CQhS|M#DL3Fw%@2`)KTs&>8a7R-p=Asw?OiEKAMD;69@+tQHiTX4{&0T*G2oh} z5z$lZDnf6qPDx20Plf=sxbjsUqTPiTJ0G6PIQ5@w`Od&%V4R^NAeYQm`WfYgayyL_=K+n^GJY6FzSOTOEK`tH5)d*2K3){vaI z)^cT2PnzC~6dSy0fSdD3LF>WGrFNz{p9<-|mN{ZlJnbRzczeF=lv^W04wqrbfvw#X zOHStLZD?#+{^HllV#W=(clou_H38W3+i5^Ksiw;+}Q*!M(Jy#2?o#*ty*JOY|f(=cxMJb+3~Zh$7qcok$M~ zV|v-XLa#O7?tDslU$^B+79BMvq}0&8<2Ym!_CC~{gFEH?+~I$64W!v6pp3i3n7*(x zg&8uRtt2s|C<2C9Wte0+4b)lRTmlZGRudT3?FhkU@o%}uum99kLpbzBc`(8qO|~Qj z6mb9Dhd^=G3ui35eTK+6J`WD;Xa4x1$$H}dycj6)x_JX;+m~zM(CR2aXL=q~Z>t4J zsoYCITbeK}vjc_Vbw*3%a*@vqz-G}FA>RMl>1$2R;-I~1=Z z^<8;aGG?7396`AVfJ^Sag`7Ql z(*Qr&4ngH_IbK1dQQ*X|Q)g}9V&MC*{G)_NCsQBeJR3e52Iy_>_DOZB=s#5qI9mi> z?zWl67t5=!AxBEA79AbSiWmfq%Rw7P!=GC`^Lu6sbMEK9@oG?S;7VWk#b;nX?aRnJ zp=MPc`sGEz}{Z1KEsx7P=}{?nEf&xUbu*jj{z^4~E2yF9jxq`9fIIligv>BB3bWEoBxrne zcxBMb!xe`3BY>?*~FDjZ3zn&;qV7noA zxj8X^S&i&4>}QGljiQ3Pu@b}SH$_)GwDh>7CD7Znk* zm2+5`Q#StG0^umwKSQg*{sAy5PP;4Esf#cF*I$8sh{V~-?l^(i*4h&=vj6zAdH3n$yg1b@}8z-vU&me3O?%!Qdhz7jjl#Nr>}G)*h&ls1G>>3VTqhS+1+su$48>>ZUYCubG6~Y z@zg07^I&q0x05G}W$7_sIaQ~slRr0B?&^BB3*$9ZUFSV8K4N~?<{$(=Da4G{@URaE z`+KH9VMScG#UTOcrUquO{R{2DHT!DNZF0&A=96t&`AC|{dxkMG3Z|E#QZ3pNm&`kN zU(f3`&@~e!47Hym>n*;=lEw3#Qyu4-UMAI;$|tU6WyswhL;9^V!$Ad7U`?-6*tyC?`Rt)+(aBqi<$aIkgTaFXe z5D4jxjLiquEe(3re0%lV?agYqhM0@DzRFo}R`T+ZDhmYvLW%Ln!Ygu9UT)s$x5dwX z9+Djknw|uFgnmy)w*6#(BQFqP4J zyDI)+(k#}{z-LCg2p3KCe|PZL?t*&DpWBAp2=c6VE@P(pXe@*ZWD!5im?YGRBq8)D zB4>e=MWVu{s>B!2bgdAlM0!~jKY@bZ3G{F?8q9|Dga-Aax(C#~E$ znF`LrwW}Z%S5QSTD_b;64zVeZw5qDo{CesZE-iGn6HsDx4n`R1(R02{%IXmL!H81I zl*?<`7mM~Lz%#RsU^>aB8uK;9hbC!SJp@C^`ED!oTxd;0)c$%4Le4A5l0jH42u#xF zr^Qm+ww&m`N_|HDJUVe9`>{4!1-G&Me))9oC)h5f8q_!h762N)>~pOVKl`pWsC8m6Jg?HjOHn#!Z{LbO=Hjwp zO!=k4*RZ^G#ZP*B0qfz%aSdu6z_()i`Hov3clLTd`z7-HxLNgef0ogg?4g1CI#x zc8rYCFYW3k-Mr~|t~wGti@a2f>FYE@W9S@8O_cb_Q=J#WalppdW@`Rwk}Z>ap+PCY zLfe8vdwZK6cN&*_s%sZ0N?_f33W+Q=3-YVd#JNuN8Ng3WzZYYLJ|91UzO!^5kL%u}h#!M>dkN zinZFZb_^CXdU;H2bp=7asI!pf%*mWr4;n?t@h|TDm7ZQvB|)?b2L8Tp$(F$urpM^d zue~fEPVQF{9qaln=WD!Fa$FE5+17;zA#U_#LDu?RrJHu*HeR`nNOtP8{1YVKi$QQ+ zBFaXM+bY>Dn2xSJ%=1Dvun=(}mji z6pqk3sp7#Pj&x){^00N?5IJ|_nosg`#M>Z9DkJI6B>z#G*@Gt3Q zdFn?ij13x#z{vMvtW3qKKj?z9lg2D_ku6j&cp_UnMbtH=L~G4A3`D6nRSwB(9i8;3 z=;^|tfgmdnOdTV2PkUrx|M-y2Th}iBv_a{+?!cV8&1Ya8e}v`*o>*l_Ted<~z?3P2 zkXTvNjT;zNNS1??xW|81>|$+#n6UU-Kh7Z1zB^ugxdqtak9Na-IgbMq}LN3 z+a9Sst1{EHsMQqS#+&Ye_gG!QN_sj{kL((l67vP z4- zdT14tuqv+6BQ~vgB1@$MkKiV)2@#Y$OrK7~BQJ*oOyl}9us8I}lmTOzvJuC4V1E-r z;K+uykHyyN55slPHgdH>=7)Ax5tkSuB$~OcOAM4e1842?1K6k4lhz z&t~aL6A^kzt(Um-XgB4pqf3%FYfcqBeayc@@AA4W7; zBe>>qd>S0DEof>Q%_y00y*X4*EVAVx?y{Ds8u`R@+Lk^RP1*UJ4LJH!4o)Y%MKS=S zF!{E`UZ^%KQ-+C865821R)&TCTF2mOy9lb#F39J+VE+Eg?%l`>v|cdfF@Bu2HKny( zxs|cYy`xU%HEO47hxmmbLOA^RcjOTN?^1`bwbEC_?@6FS*ak9^=P(+#txNvXNBnrf)MCi);0CzwYK^btOj& z$B&*%pBQlLBn-Z8*DaKr!Sq2&Vx=rx0DeE~RPYshh=6+_Id!MrP`#`O76nsh8BS!&u2Wz)UnI zJ~%;KWr9d#Q^)SruH(UChW3;SG?QvggI+;nu0k6UFZ1Z33ZaPwA&pz7(2!nP!MkrX z>nSz+<I8$z z#fD8;n(tD1Y$u^cOwPq2X`J)h+Spd-PSYeCZ0W^|D6P88hdFCC&2D`R{L8C;>uvZ0 zQaPKiAav$|6em`;;=M3qSP4LhhGG2_URvXCIhJPw%dAG|Mbj&2%=8(ikrB{n>&qIeZDL9Y z;CP{pHxRsGHo>oBSB@`6Tgd1<;u_n0)AWFHTx9)_T8EV_j~t+CT4A&o8)zck9Eo00irz~z=x9V-6>%MCdrbs1ayc9?vk4xe@V02w*?oP4=+tV7}!i7h@ARnU_6 zF+^XQ{#pK4J0Bc?6iXnOc#~|12xPaA>wt!ghwW`|Sp1BvkG7qO-y#HB=ZN|OY&1<* zI6o!I+JIFZpU$87C{($?%2dp3^{qXk(3F zjQ_p}f-~r=ZD4p;p<|4AOCR2pM(aSJ+Ez=pEjCdePSZAddkohnb0X3F{octZdsdqk zJ;|@XoSR`@%WUgY@)g?yTT8q|>=U=RB39D<+gY~tY?#ePwysg~y)*|QHqlhNZNTGB zARy0C?}IcMv~9!{eM78jZ_goI5_Q1uZ8{5b5TWmXyB%o&K$zE)`=8X4$}h4j)hdMd z82boqXZ#mW(7^dxH+tbv=(&( zLY{(>BDs;+SP#m5tf@n_H|f>*(7x*K3SGxYU5f_R=!~paNlt3;64nO59teS(6J+2t z1tgfYA@gBlz9rX55!b?PPbikC@IZg4J(qGnof$u6~_ROMp&aE)N%j5tHrQ4E&ygHv_Uju($H{Kj~v3J*XYFTgB&uZj0hnMgp zkhUlm(ia+XMhf^U9OMHVB_ZO&K>NxG!k%Pa$rGOThFW!4T(D^khUiS|9l;q6~{Yfn6qArcRjx05#1Ik703I=UMFd&qEua z6u(haB~zpo($f-S!{j^zTqFseNp`*Vc~JPD>0tFOEao*d<$HYdYLuVX9|LA*A7faF z0lyvQZB2DbAZ@^_kO8X}n$wXB-6_GJQ4}{OdG2s-rgF34N#*xtJt6kGj+grH zesXc!DIYK?N`lON#D`FbvYxR-K3`@vNmQ98>>p>t*r%BegDnhQM58n0IN6lr;k6yQ zW_e7gTD%z0=RiJA{`;fo^=y9WVDL-$5<)AT%5G@C120$NTMDO#+xZKx0p-z3+6F=w zNj;djUUEff(2z;2KP9+8kFV9`8amw(LO#bkE3A=?W<#n%^ZUV&dL!#Z#EMF!MP(nvQpaYQhfF}wTi|JX*FE08dkNd|XEGHD-~@IZe*tPj31D0{ zA1ml;WUmczxW;6p>pfaZ*j^?8bgNc}BX3kzro&@o8w0#`sZbOz%6o##tD<(*TJxeD zf6k2ZSghV11@B_bF;{l#7dFEcT?P@DMA}t3BB6gO!hXx&{v21V*?o z-iY=w9JA{s`~b231pcsj99~^))uzcOkqJ$H?$TnKD()J5jXxb`0410=d-4OL0<968 zt)kTXT~H`Y_gh1iDi2LZ94eDFi8b$2`SuRoTPrrgSIU6n*g)sJWUCW7MXlnMvQNM% zfXb~OOkte#b~Hom5a2mGA-LHL8}$ zn^g5SVo3OMB|q^&uw*LdKNt@%>yd8_`2EAMdq~|&kW}!biKq@nr?V8ePWMV|)}xu# z?TkmSk+{ivo>FKQ%P8Qk^}ugp8`X+8+aKaCxf(vwg)L$0Tlv3rWs(K zuhTw@fj3(0x8-H}I0-6Cm&4JWwO%}++s_$UAQgBFR;oj zm7p!Cilq)>n`|~^eHuFHTj!v8f@YQw6tEkgUtPK8wwLrdpeXJy7kv~MF&jz!Pk7TY zwB0yMr|uKUZzh0LrbZZR+Z)WQS}*fP8(rr0V8Ch+y1>77ibrLdB-!vTR9OX8Z&@WT z#Kt2y@7Mx6_6pRHdiNZAK%sus;o%FEk*|+i8%XO+6P__o3qdSo`4NBAHwRiGJ|pmY z&6HRcvpfc&&Mt-!Ip9u2yKkT-WLS!C!^)=-XnKDqqnTbl##oT;z!9)(2tC!d_pJ_# zEzF*!XH@_noDPr0Tcdbwo@WIGNx@Mz^Yvx6nz13e<`*iG&oGPidp34o_vutWlQq+O z@V1!*B|eQ`1BDB7xUebVFihugp2QdW1RyJDGiVkjz<7;n)WlaIIVF=;iPs(Bw`*amB4WzsUS+Fo9* zy7{};E40d15$i7l3=vz8X5=nWgPg<{BnY8fW1HLAdndnAZQlyR;(`I$!bFv4Q^|9# z@j6@)BOM-H>qZRiIHj9X5Es(s$XmRuTk+!7w{NVb14?gYU*Uo?#J&NMn=poXo9OTK zP^JmF@FtyN&)_eE1{)SJzSBNAj_JJ@>xpf5=2Wz*gdY-8f1_oy!RZwAJSw`=7 z&Q~t3O}}Z)x*b6HNUHLidM>`@ueU>JFhv#?Fz6bS7Q_S!BWe{A#I^%?Cy|f zfukJ{=|Ga7QcgCBNN5t@)mV$}oynsg+2Aym&i0j@ewMNh-8h{pX1@a}a zK~-8Vz67md$TT+5^mO*&u)OnkO}p^6#W+XNSmUViQiNoq>)y#BcrRu%O(+mFRgBc7 zPgEM;%Jp_fev=DjQ6%f;Wh=<9BsZzj7a@Q^ocmbfUe}AkTQ7Tl70`s^H>dOG8Z|1@ zjo3{N`x#Y8ea35}tzDE_6p*FFcV76MaBFGDOQmuBKZsc+gJJkGoLdV^cRogf z;kGF?d2i_1_?YeT6@MycoF#ff44gRAa;qTVhFAaTceffVXD+=c>3WQx3RG8pkX+Vu zSpdBWQBNGda$~lrAt2AxVB32^+*9Np1#xM$49Bx6DB|i)y-Okz{T_>%I z8==#x1*g-a9Yh1@A_tElHz77=i%-+X_fJ|} z&Dtht%YCslS?ql1RLJ-}9g=D7j+LvovCZ&r2j|^ko%e3X71tuD3){YvHWYIm zv)qp5QKF~A_lhdEsF>ovmkjXyrpkoFaR%{?P~=098ee;}`bNl}vesKVW~ZL>H1`D} z&VHWgs&{^TulC%RopvbuG|%HQlEg&%n(mjJ@OA*fASSZatURqbpFKj;c+z!qdCfNV zb;_RaLXvFoFSOAE>kZal^7-_FFrOk!Tj_Tr&#D~Jy7v>+Ilqwi+WAeF+o`XaCwmgm z=kpW|N;2uOPo{e11r!k*UM=HX{gZTrR_94Wl+r?g@Gg-(RtQ~4Ph z9b(z>b8D)6=Tl9Lli11w+q-yC zy(3ZD@?ne3*?>re?!Rn{H&J?>FnEqQ|_Do{FcMeVrB@}kp zs@`ujdkaO(eG5Ck<2-1#aBxbb$(=)%o#!i^(hxWA=C&}e^&=i?UAzRx!$X7LqP1hw%4pX^<{nkA+E zA5D8(avlrD)&%W7II>`@8l>TufK=5nvrX^LwC!=WUm@3&`fE9hUcY#fnch8CS!Rb{-lZEfSw)?-JmmW|OMMZ6g z7M})na4s6aMk>~%San%`xq(}$eeR}fFt2D-XIy{BP2XQJdD`c1Vr;pj^~CxszvTkp zEEVJv?${Iv3WoaFUa)PTHKQ^kd>F3&>HE&6*8}eEi~`7+5x?@%i8k_ap02fWb6aRe zKWw-!IoDiA_@aDe4x?mc(T1M81wc{U&bjf(j2l^NUAAKkP@v8}=o;$Kdg6)f@4xAO zVRy1tjyxx7NcFA!8;18}b-I*>Yao~V;?(G_{jKxbB9t@>9OC<*a3$%}^+*^l zwB=-F=lA4BniYCQ1!==XQDEwkd2yu6<6cbQ_H<8e&yObB_PUl1mDSE6e)+5wBkuHk zoH=7?1!saNO!!W{;r!xY0I#48xz2s2DWZrY9gJ^IC^;p6rhsp)~Ie#<@6+b7*z zdqK!Pkc#5L*ZY)f?Rh(df?bG9W{@hppA>jr81H~+y{%u; z0D{I?-oLjMbvfKe7;f{CJFV>DA0&JZ$PEzM~rY+=@#zWIjM z^dLRR?e zxwq|%n!?~dyc<_)>GiPL^AQgnbQ5Fqt@qW)rP~)5mJv5AY`VKgtw{7sT0{@{h`_-5 z{bVaj#oO?wp%8%qFS(f=YqJw-8K$$$d9ZuC@I>P{i7q!o1g*~m|v6A1Mlsf5>0{l!=iO_ z4UeQgslNWY3EAx1s|`9Q$}V2~_N{%ZSwv{2uj-eaHv#5m>46#Ou-9G#o_6xkI?%AtomR?i@7EOF5$-0vL6zd3xC?r#mfd;XCIkwmAqTC@ z)t>XLPmHcbv(>Is1wzu$55mfq~65?ekC{?Bb1w`tMgve1uFP|~=mPLmB`n9R1CdMPI zNAJd&2!(sAKOjCmc@R;t@M5QfKk56Xt#jEYm{p$sPObw(?7MHDe%NkO;FPt<>K%`o z9<5OX(rLqw4y)yEo*GP_A%55YX9|~PPse|;J%MI!orHPmy6hzi2E(KF0f90+H39+Zp;#>!B-sYOTF5@qwdN=T&OCS%vhQ9?mOA8+gFhzC!YgqoFlfm%*OuX=4tjzkt&z=V zq9|v9f{!@!ge78mGIWYp+UZD-;$E%om|NF<+Ux^7moD&_?w{tC02tQNW762U-*SDQ zTFwc>rdkCCEpQb)G4IqHX@*Bl8n>kpwjB3rXrM`E@{rX#)aihAhVJmlhEBq(XKnLs zFO#7b*K&L9lRUFf4*YBA6OdDIk;Y8ZebGqPs1r+_809gGW4AB7&OCV8_#x1*F(H zzV;*G{qOTo)MB5Aa>qq{HLp5 zr4e9O`H>B0B|9LB*cp_Ll;Ze&>>N>bVqVXXD#%LMLD%|{YNB6O*`4$77`3tot5CQm z<`V1^8#1R18#9vo#KSPjTDS-%&B0&hl49UGvqYA$tI#j*B@{>Y#9?I`%QEt#Y8V~> zZnKf8>DV=gF2eCmkm{(=x2Na5H-5#RHI5HnZ>qYReLkyEVcxJFE^uLk5-o{8U@!#} zJYY7FG_AsNA-IdMJ;`Pl-u#^a5l>r=Thn#yZEbZ=a3-wV9x^pL-eHZA#( zfL88znMYjbzo;)AA%C|hL%oEj&;`L;Um>DNZ%>>!N?>KJ=V!SwJhF9L2!xkfa5IFwT=^R(zj>EtNrDKN4*f!Q+&4kV;&TF=7#WD zGY2;6GYp&R0ZYePnn~mUhX3-GdzYjSXlju9X>frcsK!A`p|&RxHb}FlByK`gD`$=h zU0rfqIDOyLcu9T=N`Ef-{#K#e{hwB6x%X>rqqb_Ky8h+q6uvA0eF%;QHp;y2 zk5_tceJ4%H5s><9Hmio1yx&NFC#axBr#BVcYtGXi|JttkfIPb`L95zMeheXSkeYKa z?GlX~naY+R9vZ1^FI;3d5m&@9j&;Xo7~hX$Y!h4;O2D0YNo7yy} zLlQhZesdCQX}d>}-lqqP6Va=%5>5I^NL3>RD?Y$#6Sx%IYuM!3@E87i8bAp>OdHmv zM{lZJjXL|SWq3Q@4b5xyvU>K!xvFd9GS-mgg{KO?h8aNvBxqBCWYstG0cC&>`%L#6 z%-#8XKk%B0;v-`>(>~|~#f~j~^h16zQt)M~cXTVCCzo0TYtmvIH0SwMwCtp2j<#mypn=!i_0N#7MT7)f7q&6IVh6 zal0Uel5m=t8u5aEQx0*Rh*9;{wUns$_T8aj_io~~ zX;oBc=$mGTqFZm+6QQY8e?mJ& zPbop^z=w&57mHt&(unn%#WcMDJ@6Xtz8#dfRS7c3_>RC-o?)}#ju2a;X02w{cBkll z-YB7Dcj<)?6Rl|WvN50G1GU=fhfFLhlFwDdc&HfqUzU^HV{Q_RP$a8WWGV%|f|%KH zx^E5O#4@-Krsx_f7_~tHuA;n%ct|h*x(X+^^~&E8)2gEd2GM?9e($L@K1CPz*9{L| zyeLP=CDsSfl!5+T5P14f2%~h@3dY5%nSa1)%04;cx4!Q(QQh4;`Js!X1HjTubFHOc zJ(^kg#fMJ{1NKfl_FV9DuBmwp2!8mQimkVar`F1Y^A4B>Q<)Y{2}CD%bHNY(HU<+z zs|B)xVX4wE@m8MnZVZVxw zF+BZiUi*OEZTw-e5lc46VoKH)$doxYasecPQwT%{M`>(6^rlr*Euc38;V-Xu&<6dO zwz!7-5*1?xeJvCf%#LO1t$1>b+B4SKJ_fq+36i*d29Hfc4r;(?1lwCK?lbQS2Am+&ElOIGK_ z)`YDDeFn`r%bpX9CfbO@*860v;j^^r^bZQNVImTwD16dHssug56c$W$ObWKrRfx!W zMN|Rb=$e1XGL^odfy^%twj6&9a*pDK*B*Y2w-tPj8WCw-TqzBmGcAX#TJ#|#|kHxhSj$n)x8Yyos1}uIdnesD5<;AUUCe72Y zJ(h1J)`xy+kEXx1dU+KbvlK5#69#^D*WR?Y#h+371l;Fz3>ZFH6Wjz*zmtB|I03Fo zP?gw$r@iYo9#K*U5E(;CG$@9fFfH#%=<0HxsMe?5yZjneewf@&nb6bhF0QzB!>6pg zb8fqyndjgq`FZ9PxSypzp)qbU>p23`K0p*@zXcg`e=iko=2!zMCe>yYw`8__BOHdGxL&FfLFhPkNiLs zoP%kiy_X7T?|DcaaO>cdjdofB)wuVXL|UJlZ?swQ6tFF-;F9Zv7wZy?IQA<5p^d+jy6>v^B&d0jTiA@&#=;hlI`$bv0;EkNG-)Q@VWt(TVL1HpmXR_MEx z&m`cgp4)8TNORNw_@&MEkG;#AKz^~!`uD8Z^W&xFrh1Rr*o_L)3KDgggY^C^arExB zX~cR%g7%>2)ImabE&0{mr-CoG)^nLM&^&@00=8tIcdka>gll~k@2Sw*XAoUx^972v zb@|4tquueju0m-e!sZ&|z;Ikoc*h~N<-&eqOPoecAYJVa62CT+*?GFB3Y8i~+%7rK z8_Xp-+{Im0+qc-v55)y#rF?co>$bXQhQ~kK#@V5aT?@s@Hkv>t$hl|=exG1GiPz-R zP8T?l*GrByRI#c$;}Jg#E!zwbcicv{2}Dh0O(h$R`k#wxM46jMe$E&k8Z_tT82qX% zM*xQTCU`|LS^`KrH@%<^2Pm?X*u2+>rikmavuYE&4iS3owm{!3+lyhKH?^GR>j`U$ zLAlDL*+e7bGNx`nDSclC>7 z$!J2P?dBDO<8e49`UqkdA_PZ7hkDDDh6V3CMn7|BQxxv{OK*-gNgsF5r4`^Egz)PV zO$b$+llb^JK|3tTs{Ph;Pke~li{dv-Z{Hy@RW0uF2RrQd$*O6^A@6P;Vn^;|w|~F_vIu zOu8Lu8|U0>9_rwe`PIX257Q*n=-K&3I!*2i0@}II47<%)mTU@d|1yJsH5$DHjX2$l z2v(w}ynPwu74;O1@%Z*MK2ZxooRWRCjM~8NulGyK_c&hQ>C<6bbMIP)FZ%6jR)ZYu zSDQ7XCYm5f7GU*f<;559w%11_S3%nnaQzda53I+ zdH`|Yme0BO_g+rdx2J=Wen(FwQEbpErtol^mW~V+3cP>;OMK+-%rx!ed-zV%( zZUYm9A~@6U{{G+SqXqD7E~|0d34P?s4!^olf%V1%N8m3I0*{4N=%R-*=8|1y>0bS10u0#V=qCwgA!je2x#lskPQ?h*;3c@ zXdXNN84AL?uq{?F-8M8G(%B~5RcyYxocs$RiZMgfAvU*=D{AtEfya74h_@Mn$rK&J z#vtl=RYh+^s5(EF+yUqSQ4^@1{5-9M#CS7Yj-RG3Kjxs9Q<(PW$K0Sqi)8s)$eP!! zf-{h*Y>`ro@VZ6l5qO1gS)!T*kP4Hnpd@vO*JWD6mnee|M0IdI~Pu z#sI+=M4FnNyl_pM*o)fS+qe_Ub6y9A+xQ>^ZI@Qo2+QJ4NM-&9$=gY zZ<_akVyEwD&_|j5lT4-EYV9;CJcgN)wgMNrZrP0?fU_sHx0f`e7AM--8x8|mp zpP7puL%@8v5{vSB*44-yZ@SI^gTU6=cyr95>UH16jMf8FZ}oClFPB#i9=p6l8+N9Z&eGMwo*uKG$@%G*(n%rpuF=8p!X~_?cy&u^%)lIZ?W!F zDo#VMf92?nexhF?0P5tmfiqRftySSK8 zLI)+NMwG3RrCgd3;EzG)dYvmic5dcug4Zuh*B9&FZ}xqBDVu0MiA`wbUo%Iun=cyp z8!$5-?*ABE`PA)kcICAfr%pfc_Oetft%`*!;#x?(_6x5*dhUnfR6nrl&CK))O-!RW05%4v zkDJ_RUxrtS=AnKF+x?*Ok6TK2GWuN7GS?O!4j$VddF}24K7V+*s-!Oe8RCiL@QRmo zm(Bi_`q72Wl_6XAt2QwBX#ep2Tc<1@zqq*fN`&yi{*+Z^Je0c1wQDbSkSVyj!;R-k7aU*K+=*%b|g=+e;pA&mnC4>tf&TRLKwi zZBS^pV`cxf_x^{vlfK^RNSr(Dl*O@WS6Mibzt8`%_Ji|%PQ^isY_Zb~5NRl+4tV97 zY=mI9Uw^st;@F+Q1W}`Pifd}6=wab@PP!kahTV7Z;o=ll0}1IVNVd>NTecAt2?JT0 znK!P&2F!K}mH601%b0-A@<%i+ih0F&tiO2fd^AyIAtw+ZIvWGqb>Ib40#fo)zKh~> z|B0pFPPnh{*{x(#aDUQ=L{TMas+$3l%eI@QKK?KVJn;|eeGkq5^|oB2*R zpXk{Ps4!iIHV=HUD_g96yZLnMxvt4G4futmu=UT}!m2K>-_}1;d*=Bp_1y^NL+4iU z?$__neYT2(!nJ)7!BYTiKK^c>Kga3ev0QcUz0XD(hsskQ#6&*K_9~ZsL$Ur#L-l7bk{ZG&A&D+BvvP|K7BqLye9x*(eJZ4{xKq%?ilN66PUE0Zs3&5 z8*|8=3JlTPe=W55b?wWhtg{mb$PPfyQkdg@?VTiwnt8&98G+h(;oH9Fluq^SouHEM z+Ja%^$WhxZ^}k5^o&jo^;OvXW!=aQQVnuDMHA(qkmnf);n@ET235KA?y2OduC<~oE z8TMJ7jj252pQD=lKb^euN3llPF>-32om;*JQ_#8fjIq&)lHji=+^!n4(hu+3``*Yl zq#(NiT}e@2JSQc8v|18Cbe%(3CBFv`D7VUf^PlX0GU2inUH>}vt?)$s68PRuq{TYGV&)hUR2shueE5Lfl$0g5RXg?+IuB59Xe?Qo5QA0cV<{`&N4bpU#K5C)fn8NerD4P z&En;V7cF;q&@G{sOi6tVD<7nXO0?4gv`iyTAKpxe!@jBCPjC`paWx{-{J2CgR2n)z+3Glh9SqS)ICvjot1?8oUe7oIe;_825JAGm`gO zN#rbOo$gFKl$}YK>b-NN{B@o#_1GQ$*xok(UpTnnh=NZ~b#*+<*L4o;&w6~hFkXCs z*z7I)QF5dQe?W*5C9-Hb(D+xzvRC3g^Nv<0;7-sSMu}Mg$WY>Mbfu~;duOsoZB53R z7{j^rdLwFsPghjxZpCT@jBu|`wp+Fpm-~s>ATxNVK|NoPZ@6aPbI0~GVXmJkn2~70 zQh?n(L?x2(4nL&8yTzY2ZaU<&YP;TkQ*!y~ur`%;A=s_Szlf1(0#_5nkiYE32v6TRW9s;(HAB_IPLugIKV@ES-yV%J|K<7TvkESE^|oT(vzNop7Xwzs_`~}Y z6^!{imb(xliON33*g3iH2l~G|l{+Zw4^nP)1Q?9!BbC>Kfoh|J(o_j;Ip|7RqI4Ob z-?!&e7L%|ZbT_o@U7j+ussw+WWv2yKhsFne@4;JXhx_!|`mb1vWt;4;eDRv>KOH1f zJ80hEydh(FQr-Q8;;ESDc2I-Huf zTP)mb@vZKxSN=EEJH((QCbHGX{O8SMSqu#`o>$J>3JJxKGMDdG_ze?)_Rqgtwd=*p zYn0T&|5A`^*xb9We&$LMmRLZ zIFhOmdZ_80clVY|^hJDM(7U%9$qLf@nF?zXPaVRmsj55;YB&3_7rnROLBu)Uma@x) zg>fQ0(32LPHxB1$%tz*4*(Sq|oNFJ)&7MD%c{i{ByiiqCo*K#^ld~SZZaB5Tid@(f z%>GkOy?RcSw~&CB59O1UC$skn)$d3m%wg3&=;dF#V%FRxT`oLUe_NDk@%8EJ-nQAO zu5fEWbv3}q4=+|n2ELqKa=8EPjPLNm<*#$m&_^M4{kRB~M65Oo*FHGf_Hro6cUAta zBi;+I_C$X{zxrePLkV;6+3&w}?!0MR62){hy6=~$sIL*lLIMPRcMnYuiaYsA`tWmA zWe@d4wJk7Ib; zQ_o4!uR~tQCzG{Na`0y;fzKp|D^oNOUp4$$%>+8n`8n)_y3`FAV?#%`Ck?{x zXHJYY%@y{T9#{tL?$0TaXh8e;AVOPX2s&^>5XcoFlnENR4B4i11<_ES8Fw9;h!(uR z@lsjdp@+y@lQZk5SuKZl^K$2065A!-Lyv$G;Nfy{usNi9Y`0)HgS^qs5b9_luaRxTO`H`{TDx!CY1RaR z;Q#JUYDBeQB#SyDn9+=9Cw3&xmtb41(y58%k$O3N+bHEjLG>)O-!A5LTT>B9noJBV z_RQi@3zSX{QGyihCug&`-b}9dB#qPiIiT;C3 z+28VJkR9#%w`)(Bxpr|g81KSmdiLxV?Hgc3oo6kSRG-}Qnzay8#!FmwWfkVN%qxAo zNMn{=HJdx}&U0tfCclp;uOZK1HB!nf_DSA*-Wl8;*HyvS*T1ilKGduZB?h{L*Ah_J{IZT6dV)n!;*XSKXKBb+>Lz zoLtLqxI5e>!-cWu0PKGHb*Cjy181_~i>LF+qvK!rx(T?_h+!GE6ZgyD!{IWJZm7FN zQ*IpFPsw&l-G5=s%W|daV4vS6FO%3>vyi3wVZz$X+%adnQ70XWan7^hw$F97jeVm( z-Pfr7cCgvJ)h+LuzgA4@J=x^!hK|^5X+tx&5I}O(nE~O3^M_EduiKR$akwlgNmd}-Pl?QA*QZ8(j>BRG zMmn7aeP=zZ*i~^ex2voBsxZYVrk@8n!7KRX%>fG`$u0@ke}Avyuzh=tql?#9%WW^Srz9`F<%Lw}>?(SBstA>wU`96ktg*M)b}$U>sZW)~ zixAyDvV2k}DI68)+?i?VWkz;3E@Q*sD?qeG z`!vaXsru$E&42N0a-=ZbzEm8_j@QK+>?ryXuvnfY4gM)tOLToQeJ7@jTC!y`I6Q`T zw8wr9%!Kskt`UX#@l+^5VJnL7^!ZP@f+tUy|H~u(I?4a*7q2?nafYm0-L$|Q^zK^z zcO01i`)eoHt5`kwW<*^eWO7EZuU*mq@fZKG*J^J(T^zl%Ugbd*wwk{23BOq4h^H?; z*rJi}FK$zXsegO(FMinfl=xYlU)DeSD^I4J+$uxe|M4$B*WX8yiNWM=JN#^cw@w~_ zU3&)^)wkKEm?rwMd|J*7wvJpf#hS!)=FTp$svE_5Ll%nxQ*j6cL#F8OCFi=v$ibzu zucXXu?%1aA0AgUIf6Udkdx2Grq_=em1$PSGRkV6)b>36l5dQm_CvYp-J97E*?3{Qr z-n2K4$C3uC9Q5YOsChBN~tKuqAXQL^TR>Lku>o}P)gC@l%I*9L&QzNTSQ{4 zZCx0iRmqqLJjN|;mM*asE^YVyuRFp zSuUJWOib8_H|wqL-Z~xi0aAI-RI=9AwQ-8)D@ua1RxWxo>@xTs5+`^{RWW2_?xgLf z?DCE?|KmED65)3Mv&~8cYq=tCC_pgM(kUX=R0)l<;4MH+JVP*o@_7?I_<;E5C@AMx zJ#f+5DJ&|Cdpe`8Sz4$&k{12kxd7X1f-hdjug_MKlYGpPDffe=`9#;)ZQ*O_Z-KY< zo=0ZzwgG~KAE|jW>Y?2H2O{rKC}7fW)=S#j8@t`0o~dkMba>?Lb%f`F-8%dZI^+;0 zSUi0tVXS-UT3ly8=)lhYnnDr8;PQ4B2l6 zSB4teHE9o}#YH2@k;Sm3MQUK|{nc3*Z!1ou)+uz$+M zebTC_y}KSC<9D0_3Y{(oe`(vH zP%Qf$Bup0u~-e=CX>XQuU|6~%I}i|jA^4mZk?pM#e;5rVI|D{G1LcI02zuJG?S_?omDjvzO-6wBgCI(G0l8ApWSp zaCf^70yyHR-!U>8VRGFMLJDn!EwB5IdH*iVwe%#rGA}DXn$8znwhX9&u75p>+59fGu+Wu2AR@krs_a-l+N%1emv>=thr zq`s2Ny=BZ{ijg^t{#e5O{x|R_!aI;5a6)`^5*Z5psACHQ-J?2bqutum{g$y#P=}{b z|1Mz{F3qLKq_8?JSLs+EVKZVWYw$ zPhzt*P@d1gZXo1|SBkN>38-e^1H?xq+5HF{b+8hBy6R(`0UvRDX<-xac@kLA6AVGbWBQG~ngo&AIL;1@$>VL4*pExwjN3xD(`!E%POg zb%MY_FAH8Cbhy8odVtyu)9QIDO&^wwoPJi<(WEtz8S0jr zHrL@-WPRjUq*;piD$c2euwF_bY(|qeFJe~(Ba3l*V`6NZ-)5nD0#?sy-GWNeUv781 z@I)^5Md`yLWxp1-dm6HjUKzoA&KZtR{Mf##k3O3rMsx}tMw8l88rMwVou!X$6!^dy zV2#90wpaL~P7r-Va`u@QFo4qBlTDQDA%CRl%04hdMyoYRsf%4$w~C$fh9+~RpYKP@ zeVY;GfF%Khwao}(h)FVoKQXsPY#o$$0J>+CnNt*;XUxQV3YB;=D&N+`F>SWrD>_XV z3g>ebDXDV-mELh1a4F`8*XCXhpcJG8qBrbaH9N9bnvA$i-X`nJB9^;U3y2H>p))$$ zID;xT4N>(KWs5(Yf$r!k<;?X(2n<3)M=_R|ik`EoqosHP2}} zTKK)0%PrZrptG{gNOfFDd}Xs{VPZ8eCd)@~ zm;MBou9Ed)D${bOs)xsd4N2eC>A7z9J~`Vj*KG`V(X(s;YP7o*nGV)*P%rR+&0(Ru zh$Mt3HTnwkQO{$rmg@K z6vHo5@|&sOP(I>2kZbLUnS4^&)OeRQ`^Coe$f|jS68#c)fIUii^I4iL)4=Z#SSHBU zSlpvdTGExD^jvKGV4iE*8jH{NYk()WKVxT&>}_J3ecMyRjwEjy39f%%zMZ7KBq`sT zE{6bWwyR`l2X;0~VfLQ*l&6dVuOKDnOP}N80aBn0Kmz3xRN?McmiOdER0=_{UxHG< zbyc<>Cz@&T`yuZu!z(a3JJjAOe%CDe>qwAQ$cxLkY@avqVlJG10Wm-p^+3A?ojk-G zMv&nQC80;P)sJT!&k~2X>Szf~ZrdD%CzVuDy-+H+&NrO-l+usKBaI5ndqb$z=qlSQ z&Za+;PnXj}tz9xd%3F#eKt~LaF}M|hqzDAS_ba>K#B1?7ND(Hh0s1>j*k2(;w%P`G z^x2s5y9nKFIy;b?oq?cc`W3Fsr+2Bzt~~~So?je_X%%=33{2KoRp+H)lyAy~bc5kM zF1>3^1niePbJV$IB@l# zAHKHfY!%2#B8cl}R@4%%t`G-8%{t=@8pN0g|}N}F^Vy7^}Ia;Zr~3_%xF{%8_zhGS2n&% z9KUWmD0&4NEu7FnuW7I5A-BkS;Ojyp?qkRwKIWP>b2mo7RG~2*yA=VOB1J~xR-7s6 z1Z^C-rGDvsvOcZXc*ln&gNC_XBMYZ{jq@wMnv_aLVdtff0AHsYxEomsR+Bd%uFw+* zI*{k+VD6bQpWc$iN0Gkn9_;Gkvdqu`;DakP&Zj~RZT01MbQ@#IDb-zGD@uoWFm_qh6#)fCP-_+CFt3tTH|2!%sDe)Y5F0=et!4TUPPtKOn9E zzd%IgiS#k5{Ak&&?pqP`6ylafe_?(**t38e(-(1D={mVKP+4mcQGG_Xvw?NDSo)B1 zs{jqkUn*w}e5IhH2q7aE6l?{zMD_rP1sfS5sTq-oP>ztQ^W0mFh#ez(!rGhWp{Q1x zd5?{AvBWjd&N|)=u07+YpE-jRYC7&w=WNN)R+wdWg|2<1+{kQw12@0}rpHY)FejT6 zkO5JA9F3|@XWzV!<;Wk09Kr<#&cemK9YWN+ z-PU2~8CJ847bU2`yd7=0IkGp;*%edkx1HR2Zz1kbWb&-{>>IgCX*OZK2jK&4hxFwf zUQ;NE6FRianU2!x#^{h^qaXh(uZYCo+vrKbq47p~G?`MB7?He_NPgjeRv&lN@BzVE*x-1timn4 z){~%-ErO&3vrtn;o|>RG$*j{zogv#UkfmK-o0C5ot3xVk4)rgbvhq!+Qi~;!16Nzr zM7?UmVz*ptPnNU01|(h=;R6^ES3tYLgK>yFoiriBN$^ni^d;_;Xza8QmIxB#&i3bO zZn96m7O?Nwz)Ju-(`$dQBAW8{`M^ia#*fqPnr`>Po_h^D6?&MzUJb86%^nc%mof4* zg(iSkb_I4@6V5O|X$41Rcic5ku7-nfs!e9myU4?v&Ct~#ZhLHZa-(k<_-O7~x2&Hl zd(B@|4eO10^j~2bhNw{SmDi()@`%gy8z?Z?W{B4jYb3Bg<<>>F7@%!@4eekVt$D^m zE5khNzJ;ZQtr?{_21=-q^2j{Y`&{qUJb7w--bY_EwQGZeZP+bG6a{3ky-^k*MlBwS zf0P^)tfAc!z)uLeQyaAd1oL7ap=D~-R~}t+I+j+>4>ewP7baGh;d0L2IzwkyKiW2J zHQbvioHiZgRH=1taJ_CSx+Hx_lP7c_)<u$E{{KY(rlLzzlJJ$AaZx> zIrRh{;3w-stO1+kAgY0=yiRb&S$rgjzHXkj22HceXw@;0cC<9mw>Xb^N{mO;oMUX% zuX(qrcD_`Onqg!>_iYyfRm!!~;(wDvAf-8k4QL>xsS~?-Le}pfF&~v6g0D5F>yS6% zULtEGW-J?fh13%KL7IAo4{`0F5v>WUyfWQCqLYS-FXDu{d3);KJfdRBtDW@}o8fm! zvjL~)qnNkAz(OF^9EjY4Bk~;*K)6E`{D%8_PMrg5YiFbQTa$%XD*5sD9Tw!liPn1d z%K5AmYMEIX;7_(@j=5NfiZ-rm#E4bDOBFT|FKZz`CbgrK-&czdctDnK$gnv(4f-8C z@!~E4iDB!+sIR@Tcxz1Cv@Hs?aeGj-OjWSRUj%xX6QDY#&GF|WzDL6&x4h8=h9iKg zInX(#-%7s@G8cO!COwj~Lb%Ak&s;ljG&*I$9Ja}87^el04dz%~o`JKeS2@ePXM4R) zdW=6TH6-$PvmB|Nt^KLgcQQxg-{eWJq&J9{(oI|8)reF>nQ~D147sNL!HW8vZPW@o zZGIQ@G#~jaxPHw%**u{mxsW9>(#iKP1u-w@3}nn^u&ok4FJ?cSWldk>_zhl?>26j+H$v#>77Co2NWS zp+->CoZKa8UtcfF$LHO=vs~r4^t{?`A`AMn3UJnLU05D1T%u^2!3=u|CKfd-Am;jcZ&zebzK1m%0;m?AzPYW;Fz1;n(fo=GV6=AY@%FFKY zs+E)@Yt)=BUsx}f!cR{+useL%eI?bW7-JB->%n-WbI7b+sHK~%z<)wW^R1WFe+ zLsapfaxCY_Z;Q4sZPT@-4-KgFXf3Je!$ia&p6lDuHX`zn_~tY%P_IKL280yFqr(oyU*wFBd)|2Kx>}MzB%K7NT;nD0V(+ zRBT{-*5x-J^w+m>B_qxL*XU6gEv2qA7^TB&34yiM>BE_NSBy4X@;bG@$IUl0O&LO)(@{Fc0{Cr7GzPSKlN#H-wkk%q`m5&n$asH@4VB69^BnRX z8dTe4^4soTV-j{5hUsVwFB9WTU2pasGhiC9YA?dpNUQ}(j6v^W_`0CXY+LHoP48w^ zUmu?lpJP{A+0nIZ_h|QRUvu7h?y+-3pS<$*TFMNKRxi8k85(M>9$~T;hh@ZW&(rK# z{5ZFG_%c1u+0OH-Nx*$)7ruAHm|+&n2e~&drZCD=_kt4s^&3ib)37*YPmN>jp1W`d zNKue+q;EE|$)GvY6*cu$DNQX~?AcUPQFr=_kLMJ-{$YC-X8#?DV89@A)9Y(JM!SY` z8sZuVI`uNWq&s$-@Ycfde6=z@NxAv?beK2w3GMDQFfpsk9I?2PYW>J;u-N{WorbcL zqBf6Q~@zF{cwON-^^04 zH8tMWxM!)HFRLz=d+j>rk{7BO{|r;}I=3M6$j8Y@_}U=N+C(A`)@ztK!JtwG(D$dh z%!ize^2j28j7D8;T_Uv2ZNP%gNmFB-y41X3)7yzb$~kKM`|Q2_drq=$r=Q;xcKv0( z9E|b9&HM4bGPgZX{QphnS>d+C>3a+&xd0Uk48|NOo=TYIp+*V)>McQX;tY2PU}wc&#CYDo}Yh{j~gSuSxDek zkz0tGconFRM}(a1)baMLCrrFQk2qJh5rpXh$eP}e>L8;(jvNa<&95V$rF1rE_O;+>YVJ@7f?f|Pq#Y32z0s;mzsKw<%lN7OIq zNRa4@9VO}?WIH^et>_L_ zRNew)|D=LFzhppH$)C2EDfXNJVk}T?xGUgPliasT5irWXIVjmuD}6*z!;Oht9PJJg zn8d28Xq_#PhCuC5LA@|3Q4+Za)F&z8Zj~4ncInCh8nP~`+}gW2-@JD-u77Gr1|y4! zyXfoGR=-VQ+I=>wfbfB%KD!{ObdnY~x<7?jqJ$(ydYI4>CFmy=1jQO=)AEahV-pe| ztsy0qL~vm_-71q=R)L92m|>N7tW$l}w!0=gURBjp_3pTP-R{nRtF^!9lLb?(Pqf;m zdT-1(8t>>!r{daoydyV(NL}_5-d%hiA13{c9zx=Hw*qA|%C?9c4ZxXzEDwPTMO~D1 z1ApWd-kyC^8N*x>pw-;#=fr&(<`SQ zr?>j;UY8l$PC;LNW_0CCZ!*=tQSHOc52kRvy%pZd4Hv74T}bBDm|nuKK5^ULoh~T$ z58cAK>5|d(kU5T-AU={^$3?qrJ!EQl^?~+DR#m}h-O#xl$9G*-bp^BB{f%U|E7b|( zBE(>xu1tr>+tFA56-UZ+r|0x$UTg(P#*M5%eQ?aJA(uW#)x%)$- zKBba|-?6?C^6i=lVdD0+SdS`&s@!EzOwwdCk-pJx7v|R#d)5uJ0ZdWza1wu+6#?vu)R6UR-4 zISo!3sQP$~eOE{wBo*G-A3N%QX${am*{$x|fqM^;+2ukxRNPn#5!QH~j{xaO7?BqYjh$ra)(g0dZpdlT#|5r|9atv42J6}sQ*yY~J%c%1Y&9JSb%aNh%euxakted7MG8FnCbuCG!uS_bF3 z6Bk#a7ALZ>S)YKG7TU8ghZX;Xs~s(CBdHO33G0L^xq@3fQMnLkzgL#$oW>UJ61E8| zrc@!V*367)`g)4Mol_+o16@nWvinO92U6W#oUbLV^QNji z%Nl`gTUF0=O*U7Q#+kPGBdzEyPQN;Hl)f~`u8j|Uf?BWxnjHWTY8#B&%eqH4L6-&H zzS3s|Q$jBr)S}+oouso>sCR>BYuaYzkQm`>(i#iM1WO2=nf3|C4-wYds-CQcGfP$C zPkD!1sh>D|mak?2}f}Y;nuZ5N~urO~ycNmTf06>Fe<3{`^p-(IpV} zBiCVo0gIt`aF$zte-uqY`YfNd$W3DU493jqRn=P9iwy$ruNi*lXMYK`5*rF?V4shR z=OipFfBcpsTgMh32aCyeJ8fL%;8-97u{GEahSZT<&SQyg3!^(=8*uXysPdGMmQgf_ zSFIK7Xru}M&?F{Ah?@du{R~y|HmPOrv8a#muEuzJq9nALrNJ*w?4RhovSpcm2S6px zlHd{y)FyVvJ3}Nf0(a{?QkmGii>3}N;5zv6#_cOHv%otF*`aet(4CIA=NX;y)&gaB zNGc!kFu};v=hJGeHc()dwx!?3G%_$$jUH)RM<;iM#`o1zjb#4IGHprq;NmoaFF7qO z!S5W!ep~<+=QXH=#TT?4IIUBVPFK?OM&uY6e1Q7 zdYHs!JHjFI$C2sIpL-)wq#oQvGYccqv{`;NWmTJIXs6V10q_4Dg1PiL_f!fa=R_&! z7eTL@sm`HAx}BUsb?#e~gnrgr=KiOgaUT6s{MPSjtW%B3;)8yKw=6VS1@A1ZWDu)A z*WS4T+_Lf3^wT8(0C7)jR4;*47>qoP-l_*Vty!qekq9^xc%1dq3b1iJes|s(b!Hf& ze!opd{KVzfI?frmk^$(7~is-4tNpQWLw?L9@?3`S_yU>BS zEe%3mG{FaQ!FrHb5d*QU6V;Onse zzr8R2wQ`ItQ8g9$111F;o&>MfZ^PcG2nOcfaFd5G(ET(6W@zIk;pvDd1D>idoMA-y z+2(=__BvIciJGgA>5G`8HXay*LynT&0hAz%3-D*fpp#a9@1$V7{7Wb0{-aU;52u0u z{s$bS|7VYjRsVbM&++f3Rr6}{mQnOT$Ue$Ym>Z9@nhCT?{|_Gm^UzOBEGuto%a&jkd|Hj6C?Ow=YsFe!m3U&sWQ-O;;~ zXin%v>LR9l4c@@&iAN(?*4L*o(hA?$Y{UCB26LzCQ>S9XeQ=oOu@;#st=CNH6|4vQ z_tBU<@$Uixc`>RDu?PaL&&?E~@TJ_$-^I`WJOn5|y0RkQ8TR>3b<^Cp1ceO~dwa7C zs=r~M#T}16dbAg8CKSGC^A`rf$B=WDVt*M+Q@@3{ZU|Jzqs(atv$>wa#OKBlBn4bJ zu@%0tG0=y7xjJ*iAjPQX3dw=hUdUIZ$JVU;)S`B=erd24Ba5$k?-zd%d z^h$_KZ=|Pjw;JJ#ANEx@9rA+Q8K$I%09M_HGj<(P`luVg*G4ZX9~o}eoli7Vyj=J7 zTn&w`|3yl;)a^mf8Yi(*$6C?H8vc}{m?IWbbmDaaQ=bg72hY@3OdZPqk|DY!%&QyK z4tO)NyXUIPC17iZ@s`^8g;pzJuo_vq1;sdM?4MUMjnl#x@*ju=W;USj0oOJ5qXXT1%q7ck4!WfLoT`O+I2pWdyqb$EcB z88?yLH29FEcm{w=Cz#9mp=L77<9mGXqYhbaR6_kX)Kj&wU7)BH6lb)%q~Y zbQ{Ed6_ITIz@1AIHsN9*?@M?J*TCtxK90#xZu4Tg6ZqJ`=x1?8-PvRKP|s_bL3y&Dh4CzCf;`@yX?6=u|u@5Br03k$Y6m)DT7)U#Pr4nhdBtgdRBW;mzo@x21f{# zujXRyX%3)wd`uE8f`=VA#m;6Y5<{E-nUyo+lf;XvE|}5T-e+Q#8+ST&@M!M^p^@|s zLDd&_UT9JG6hfVGVB3utEuEvqt)iUDsF|A5UPQ-EvR%3f{fky=DJEGHG8F5>H`V45 zV`eh%Tt8Wo;qA$d>$=v#+C5XtFCsYuI3EI+h zJ8g-YG>xD}=%a&k1a-?p^35_;rp;l&vWOzcE8izX%og*>>u|^xO>9yXcRMu5V-Fh7 zO6>XGan1&gcW00SN($bZ@9c0Q{^TB|XU&mC}32&x_CkOcaoyR#y@oE;|4bU2BBLDQ%%n9z7tNX{X~UIocng z4Lbv66xl!RE*lD7UhV-!z%~XYwsag}MaGnxXG~mWvk2Ki3tutUYL~vUJ6C8En*a}? zL0UpkC3M4A6EU#s^sVOFXIto+^eZShp%eZ3LJPgnKmvD+QY=_<-n9-;7?!(W;w z){Sy!XT(Nkx=pl4lwga@9(%p^yk9sn>sU#>h#sY|RRF|&y99tLUo2aHS*(md+RJqp zmd)DHRcYE&E0l+O&diV%@u4qVj=#doJ?<;``cDqIhY>?J?7_l(Wa6+0rM^J~l zmb&bHKy|DcSmKI)T2;gEjYcN77w`%%(aZfb8^L0~-OjoOnxJp!$D{HXb@YXz;?PhQ z(!i)8R`eCQAhDsB(W!UJI5qH%vNlb+WMi<27Ua-Muw{cpdUOYnJ#EID@~jnYyi2D* zx!2ot1r~p`OtZ3FWhE6-I+^6lHl)4V^Fs%tCMSE?>+sQ9!bk&V221NdHb~=UO~;kB zk~smq=+=HeYbPzE44(64Y)vq0A|X)jBi8s)0t5G^BXd#b3K93$)IuQNI( zJrUj=y-VV517!bVTD+C#9;ci`{_60+K5u6tC6C1Z5V*L3+F%o~yx5wT+|HNWtV3lh}e46V*Mtm?Z{gL_|XDa$$ zaM+cq{QpR9{d;7}XGzu}ZCcU%jzl5*BPI#eV|jNh2>CNx9_NILrldqvdV-HuG(Bs2 zl^a0GzN2QVj;syq2f64H=Ymp>Q$y6TOR=Os&Q{LK#*tMN37E~_znE`|9V@0 zJ?3wR{^!4NlsVNu<@R9PQS(8lm5iXORdW&lb$RDn{S>^zGsvF7Sx%KW64f5^xEq4% z%aW_5XCfbtvdnxpx5qo3@6|iGJ2N`*eLE*EMQvN*ZzY!;w90?DuFA;M1^1G+7zfNq z+%poqBAggx za*JEB+%iWTbMGK)eZ+&}Z9McMCY0Eg{V=ogg*SRxXJ>zjjcxu!?tP`2%O1V6 zRE2>My)XEMD&%LcHXETF9x3RMDFOUp^&6;p%ofI52E~CwunDy^W5B-*ESS{vYf?{Z zR8}i{IjydU2`Ky+oM$cQNUTcBJtG@GNewakSe7Reje9()O&D&IBjo*y!Lvf=isf9K zAkYs$(3iz(Q|yu5#Jhg0A*Xx^TDUgXGGQsm#uR=tvgwy@M*n?Jh{}`w-q;6d#pjqC zMEed>9==#NT9+qw=?|&;0DJzI{%IF3EdUB=6hKreNJ%nnh|CAeo_~SF6=IAcZV*&6 zPV~%2zL+QMkT|?{a_H*2z80!e%d=ebhhl$4@tp;6Lw>pL{2`SAK$Y162)b zB6AE{;o6O+f^OHog=!R_^sH?XnDT!KjoX?yc1bXPwki19 zuI9ttnd>y3z@ARZJ%QOm)j|Z&=h~@Deu5ZdZKpf2OXM6=Hnl?)&$O#(H0VPv3UObuH`-?5@sQX(3?)-V*vMc<+1> zC5JyJppp5&d8)H)N7?eW5)R~ZCgM{#~}@NxHLvwJ@ptuCmD{q^V**kS2YP_7H`VbxRVf!wwDb2OoOX_MGl;>85+ zmiueL_b-)gJ{muk8~D4EQhe~&pKCJ*kFh@G&A(sUM7tLyeL646r+5Uj>v3zWiGv2C z3El0W1ox;{aNZ7(Spyk=4=5h2A6)g2j>Jgx?BaqV)WLA~Gh!M?I5l_}BX~O+l(8udC37zMP9u;blwtBoRn96W`-jr7sZkx<9F3nu&E0Ajv`w>7=U@hVz z?ABL&7$l70rL-f_N&!G)i(rfAtDjKsT9Xw#151 z$ZvQX0rCffKWCKpmhJq%hef2#7Q(krI%W2%&66q=O_v3Mx`URz$**l>K`><&N*%``vTy8RL%o z`v)10kgUA#TJxRrna_M4zpMD|k9NOEFh$(9X9cfpKvXLh{FmVWoC+>+Or;4f zAwjztP%*(IDcX;)jPsYaE#> zc(IhAFk~`uGaCkNPi(KyU$=Lnk6`a*Fq>HVt^ZvM$GLCTX=T~hhRR2$W~iPf&h!(* zvqg%1AlUrFN&A0rWdHy55=GvfMa7O)3RG~M@7{DMXNA8}*}*d@F4b9<-L_Fv;syKq z*!H2ZK|`ARS)S0?{lXXj=XbpZjBO{cH4UJyJ2x~nWVmJ4O}u{i<;LJ?KQ9>lT`%JZ zc)BirmjN%y;S#)s$)P(9re6XPrAK4r~q%t^j} zio4^{(!!s${Nb57qJChFU;6_Q4H_0dQ7$~mWn!J^HUa>L!4Dc<{y8L z#|5L8ldg_+ZZ5DB$zC!YV~=T}a#4f82e8cC|pVxwGBq z;k}4+7>|(jnGaomFurWPKE%4oWXPW^)>cd~kXydIf30IZ)->c9?nlMImM_F;72;k@ zvCjoOxs8ZSKV3QaBg>V~wyqlJ`ZDglm|Rn$RPXNY+gJ9$ujG)+hX-A?-Uh2P9WiX! z?Z=WfygwhICYlqq7p^fxW^co7BUl3ACc)%)W5K74#ANF8usb(`CM?bRKYYK@u@`9b zd#1m;c~1j1?VIN_Ewyy_rwMCnT`6bp{iS?J+<_Tl^qGZh-*|lG+^v@VUk8J3wdo7; z1>wOT<>46<&kDnX-d&*8eD!CO_J?{t_;@76j7aMVQBGT-))6d_*Ie>^-!ZCv>l8c9 zqAFr0bZ4aM)1N!c1#DUHp^m5IhPkVEBVBHlEmZE0+PI{*W4%)kt3Ap*JVJh=kz~-g zL_E8uHSBhHjiK<**_Mgfs0;mz63%&$4yaAz-wa#^;m!zK^V3{Sf)SXb(E9RJjqX1c zD`9u&dp9qRi2$U1wQcp}i>bU?CT9f!o!EN8CDFXeW4Ogbw?B9z&ST)ySmxFcv1YwS z)OXuYGd{>E5-PxeeEuB{<1OevYyju_WlHgU$w`- zA29zTtN#zFxy@SxZE5T0v}E~}GgtmS@Ba_4_+S2$Ad@(d-YSZO5;;iX2Zou0%y<|? zfdKh=og)*|m^t*t)ZE44baafAVRYxg$RhdWzJH8?mIzrbP32y{g-U@e?>rfkg1n!- zi%#pOan`_usail`yT}*dPQGelK<#C@(~21K#mY*0T@=SYT7dRC^|4%$+#@x6=j26h z-Ia>j^n_Q=&%c(`&U{=3hM`XgndrQ`w9N5ye$>#qX#z)-n-yWcP! z1?rGkDHsG;k&;?Ay{_Xn|8@2KYE>22SD6kCDJp^GHEFCyaqU9!dei7LwY7A=J#F;7 zP)29=Z;-Bii^b9J(u}M-gTCinicdZQ73WvT36_%nZMm4IM~&^w{A


QB;*+Nka2r;Q1vKOS8NCJ>Z8NAI0tie-gFEUFw9yiljZd*h+Bs!#vtb4S{ z7^UF1dtq$(z|aA?7ppq-iS7{JJ8N9t-#hyw%fq@M+1{pdR5mW=sbLQ)Ny&A-f$~vN!)~Jg4YdfyFcLIJy_{_XZcEsB#8Ka3}7gv>zI3%TV*fN zzUU-?DaVq$I4VH$^*Zp*l-l!ocBYdg^EEVq5j-b!XZoX&WxMG$%S@A=*D?K}n% z8BBU*DqZi@9xd*GQzh!sTe4SRl!?sFWQKAS;smN-;HXAM!SaUU0)o3&P4$1nuAyrK z!*8#aGHmOZO0U$vV5CKEP+8kUbMQyEutJ*VKWkE;RMxQ^h1-QQ<06t=MOku(fE-}p zaCb?Y<;qf3_>_4o|zto-zLTTVaEAZ7%`mFYQ}GVvY>=C@-Oh)HLD6;J z!nq6|Aa2p|Y_Ye@kno4??fQbLrWd zR8n%16%c_fhvf}i^F)5~Rf-Z5!V1yAg6s0T{3R~|(=49g1**#HF{?ec z^wV|+vy)GGi2+)lacp#rVP z)`SVtMRQC}#c-5`Ua9W|4{#rQwTDyI;^SI?e9L@av&DiYUDZXZhlu~-T|lSH-_(F? zu-rIP;B~qmMX^`-sUlzH0|DN)E#xsQR)iJ=S0r`>b6L534J?$eGLY=~)WH|1aARYD zQyr+p_k3f0Z3xVRo!$*M*FPD0I!=kB?}FNflkU-X43$=M)_t7P)$QB(;sPf#`~hNm zF%q36TqeB=g1|E%4nf>c9JDl$JpgPaYAmv1Vy07aKuQof&j_F?RZp(hJ-QjtIE)l= zT0ZhHy1sHly2x(+F&zP!R74a{I^VI(=UI~-qR$R)?axqYa6lm47x7bqE<~| z)p6X4e&H^yf?Qp4#Cl#xXOX|0wWJv+&8;F!+@(ulV=jk{0V2^3-LRgQ0OhNK zMevJVN4*Pyao2+Yu+dB#^>>sV{-;Nr(R84A{#6FoKFvj zIFQsodXs%h6o?%diL2BDa+Yqe=7lw**26>Ht=LMmAXj4Gt7|5Es)10$`wq=9DVr@f zS$Xo&o4=_~*JK3iZW{_7_2VUX)uuR0!p;wP)(jXYo1W?O7d&4Zt02N5e&Gw%!{DF= zbVDDx0erAsTyH%il5BuA`CcvPk(y@0CZ4t^NbLqd;N5%$FL(uni^`O}}jjRIGxavLo5R`nMo{y7aR%}(lr|z}h z;##Ojxsq@IB1tu(#U%JAgq3U5wle_0Qad~|DMGpo7?Dzdhx9HuP;v-AA-)+qxesY0 zB1Ltj-`{7?54%?#UejRb^e)`rt9>yoeSMD)@KES&s2MbRg@|s%fCp0#sB&VYcv*3& zr6!orU3LQGqWIHTBoPF_=3NZ%Y_B1Xkt!dP)-~Q%j>?70 zpgBG&350If*RW5CY7h^|c~j!%T;A#>f_6aZu(~_mtzB1lNQ&m$?Jt`RC|l}#Hds

vS;Pf>e+XBasYlE@w43S;!>yMnGazIxC9=iYpPGZ_+&s zhAoxk%ph0k8qp9*X7XVMlOjNsS1os<=nGPr*-APfae+l4~nm^>*K2ylC&M*5qx4dL)zskoPT=eF^- zdQ|JiMlVQcTPIp(Rzu|p5N+~<5JAh3%s1b}ZgVxc8=*RwU3>)A3{VgzaW;XlS`0YS zc3sw79LN-0hrwJA856&SX*I zE}DpwqNv)}))J0p7+{>!XIvd#U92f(eMnj|kCv`i>_FCNq>8+lCc0`e2Kp)m-c>l$ z?8Ecf)daIezWqEbS-zKW8vavn6m_qfp+xW>AROeXB3jJcb5iyQ%Pg!=@k5`nXFcmu z|1{5qkW$^?+6;*mT09G2k zl;MqxBvpsKVZ;FM4m$~&Z3~2)E(}^O_W{058-X+p$GY*A8PF9-GNYF*XYe>{;RU(+ z^r$n_3=v(OsAKk_)2XMFmTZ5vF~Zh9QgKGOiPUUI-z{~4t-!_q0Z&4q3m8Z(QF22L zMw*Bl2{)iZ@!9+Q1|K8yA`8bH>2WADvt-)!(r`v#mB>1d=B9GQ@3j2w5I14NlWdca zb4$FqUunfK$e2L;QYmN1=sx{z@i&0gQ)bf3CTmZe;dAW!hzQ@|&~=%&6J5JLe^N@l z@v6>0|A6`zX9a0HSiVTY30V=^j|!WjxC?^AQC(Yf#!<0^LaB5UTZ>mePYcq&%H25Q^-@-M_NW zXQp!VA(F4^!STWlf$4Z$OO`s_kP^vIlWX}5>#i0tTDw)fYkvi&7%wl=B!a;@*U7aW zlOVsiZWFR6W+YpqvMy@RQRSWB`+*llMFWlb4nZmx@ll^E6xc})6I((T(93W{GpYA4 zlNxU}bqThaH>&42jBC{6{;d#)UPS=%B_2?1w8b&et|@U3oH30Vo=^IOzkV^q{M3v< ziY~Hzu>_>!0`M7|;4(fZ1xrKCgp0Jto!2Rre8^cMA_I+7KT@+b z=>|gywjS?j#=^T7W_(^s2?Nrgmz{hPypuvEu7OQ?w1T_5QFOa=T7CLGEMI3(Tp>A; zg*yX%O%Ez^n@-E{$S*h*@CWb?pBY+fTckj8sp)I%dGV<2^J#10R?gSkc8^x2vob4E z8k{HF6fplwLI3Xb$Pe9Xgb-7;KYcv@^3;*+4ZRH~q1^F$4F}S0fWK2Al8E;#t^Jq0;if2N#6w$n-|2*_(Wa@*nWLH*$Va( zePCbc)5ZWV!{Vt>vm`lEM2VYK|NQC^ZtaLSNK>n>ys!<*Wp^1Dl=0Z<&XUbu|Po-XK>Z}2gZ>p~ue7V)!E=X`f+{Jf-y|Bz{Yq)|k_H{O-y zF~)CkIF&K-yiP%k+aSF#SRl({^T{z(&+4H7Bed%133Ikdt3u^jSzh59`?v1_NmqqE7$5GK<5-E|Xyk zd@k0MIx6N`h-o{!w%tJMC%1Bo}KcPtTIYk8bH2%M`1n!(^21^DbnY?O_Ko& z;2qxSuY7J^0t$Rhaq+pd*v0pk&K3o%7&P#TZ{9p-wj*(G>pIV$Ia+irQ2_OqqtfBt z86leg2s#m)TF{9Y5nOfa-r$>rGu)Z-{gmtXtpy|OORjdf^f~?M>gC|0L4Vhylcw`y`+W;j7po z#PM2c`KB||VdIHM?Br`Z?$Ii6>mb@ z+(P@3#ZCX)$ogM^u>a5h4yiKSqkHI_(jCwjE2gx_u^CI-ZlAu;FdQCyxTWFSzlhiV zD>r4i=fyD3XMe=(J}LM<{q^AivN4So=V%`o=A1}Rs}CDn3^9pw9AkxjO6>fsGkUPy zOil~<&1qq~f51#>8ON%QaNsA=b1-z`+1JYSDtdxS*RAOV-QaYFUicX2!PI%%km2F^ zHO@Bw!i>2j=SV0&O{I!xpD#eZ>&>cfU}8!?n*rv@YZ+F*h%Y(L2%`qMiZrREq39nj zGFVF~Xjp<2FMRW|FYNxYYU1FkZ@B<+7jOppDA@F=4L#ofe#ZTioj4=c{4VW12xB|v zj=B7~V|Kniw6bP&ewy?~-^D~oLJhD~8#tZwt14UmPlm*P8C;V--^DM;>+#lLFaoDG ze1uf-%iB8k7f;82J_8J*$IVkW|Micjeg5yE1A?_+}Pizhz9a*U3KW!WTxgPcl=kOZ9g4}KmEbovn|MXq5et2 zRH*2puVw{4$j;2+AeJ-bnqLF#YcBcJEHT!DK0M^R+hRiM`kJXi&bqm0UaB|0Y9k)J z{P;|Aq}WzD-CA+8&YeFUvUU%347xl$8MDt|)f4Y4L)+B}X6<~)LH|X?O6r_#i+pW! zVEQ_~uh&Q4>eqe-)P&+^7AN-p@btJmb<|K+LR#z{w;b1CNgyM7Zcqa~554r;-h29rHboe0O3NSxO< zwe7Td=erjtGlhbTy7a-?@9C;i&cL9Wuee(fiY15nTU{UTZ8uz5yXk`C`W@^5rv_J~ zD*+1>^^i&g6H#0OQG>7_y@|fXJ7ecqE)N&e3-=#`!_mnhF021gRYPuspYO3S&oTZW z*1IsY>f)Pq6QA5q5U*%|FZni8-Y6(uC0 z$(jr;aQFDDL9vg-TR^LqN)=xa2VKFa*1B-<-5v%v`_ACkXJQ8J*%%s99lkGU++KoD z;2i6x@0cQ0MKsmHF`kfEuFp1bWwu&7J~BAo{?()+mTT+1a2e?@2XO;BucI&aM^;%! z%Mk>?))2Ufy2b4SA#B_TgXaZwGfLalv%_H<753|ZUTYES- z`K+DC_?dyVr>OjlQ-UAgj8%{SrI-Xx(+GJV=-n6r)-G_={DlOC07rNmiIa3Kl$|=R zqs&dK5P^;!hlxnK6Hqhs))T=LveHyF&%js%LDh$oG+cz2df(fW)uUKu$%u~vQWxa3 z$|T=zw)wb_iO`y)Ab&|_12xG)Pzq0)WJ%5gNbepL*6Myj>iz=1VDpO1Js?HL+A=n? zSn%m~i5vNh=x!E4=SX4P^P2v=lY^xhM-gBoo?DIvrJy$|nNouTiFX3B$}}FA&O}1L zqwY~w$<6V#r~1l;XP=Ivl88s(yP!ad&o+X}D}#mAE4#oI-_y-xwzYu%1vTeTon8CNjtIoLAd)FXY)A@eUr|arp4G84@rs9*&Z{)AtTJvY_GQ~Nq3Asv)=y*5p2H@MmQ zWI2c#&9H)Rt_5`x+cpvM4H`cF(@YibyU_xYD+eAAf|BF*tMVETaJE-x!5oB>E0ML}wp&eT{ltwoOAB}%_*)Mb7K z>PYE7`IuwN^P>oMRX%g`agELOd+E#4DJWX9DEUvaf&a@w&v-q7|RivIrCP}%^R$U`uZAo#AV zt&!D`JUQ|8n(f#TrhUfrX&@QCK~^^VEZZ3NDVoyyT9WUb=Bi1q?$lOEglQ3HyKM$g zQq#Oiv%&eAyWu6~k%VrEKk+Ygbyzzxfl>iHBdwb`mFN~!3UFgX5_IYS+<2PU!r4qX z0ac1Sogv130j2GNkH=~__vI&i2`>_e17J4$Y6-;}bvIeD=`Y)g-KJ{#I@X8XG0Xvm z;;(=&CW58dj@Be@2X?!|U`xIOrR2+;yP6C&DnXemjFGGN(KX>=agr#ugnzOo?$R*9 zN`&FIdWrvlkWvk0`O107N%HHb zr}#8b2s#RDGqr@R{wT4Rj5d#BsWf{mg-CZTl*Xy+eC6BwLMVwGWnt+<9?38a0ny zi}ee_hcWkf*T+;~RlL_>-6r=>*T*Zr<5YyrB#NxWjXmVjmB!^6V>|ji2dcBoY=4gTaR;e4Vhba@u86Zv zep38KVa0)<=7NHEYfATzrH_+8DmQbg!lKY#3^rO!fV)K(KFa&itB5=BwH^IHkBFY= zDDsLaEv30@+VseEVQs4hkojt$uLqd9xaZ2j){7!?YkRl( zeHj#59Kq$DZP-#fxU1ocqJkaRvr9m-&shHUm-c)t7Rcy(qm)l@(f2`xOlh~Xb$~vb zEyOmSsaXW}1Ntzdm5ywX4?}59d^;rEG+!#UbznAG1-a2m$OJ@d7_&GoO5rCv1}; z`0eC~vZ)#mMT%glfhV)RAk&|;)V6SPL8F_0#IXN_!eXuXE_lP+!~uZsldh0PuEP4( zvNTH_V3t!^D_Fwiu*R8Vt6_caM!FWUTMIB=8xI#xYu3lLblRQ@@V{C^1Ktj!+YB&m zVL_8M@|_}N?3IhVdV)ZfTZs;Kkko02ReqWp&bo(ta6cprHE-f(IE0H<#o}Ast(a9)^}{I^7hl3;W}#JY zh^@bFI88yGyIb++2z(prmano0>pui{OI-2#U@SVN5h?Ko^0U>o0@ZOW%a(VNsw_|h z`7+m}0>ZR&G`95Ti*V5dzZdYhAYE%A+Q_YGyWOiE4%3Nz(@3zD=FEt|wXO3WQrL`` zDFbg^Eh_}#?_dR*9noHB_HlO0mb&XQS85%9nzWfChG(zq9>I@${Lx?eLz)!(M@oB!+WVS6(S~|@dg)-UBmDsse0Fw1=l3HQZHc8kj_<(%V~tV zqm3wQnEBnx_Xr`-h>&1c;!W4-A!zcE%Y4I3Sp^Rb8PD4yG-Ik|8agLU>X!oEvN%E( z-xv<*%U8^eBS!WIw}}vf?IIPiGc3>}-zXR+92%DE%bv^4VPso9C1D>8wZW#CjmMo! zm#?F!BUZZMYo;BetzY;3NK~0_I>~BBAJ~GR5VwJqH3ywj6nM^>Q6z4*haw!|&%?xF zYc*$7QJ`Da|Hfl8@a%Zum#x(ZKZU}XRg)PDOw}MPRM7C!`@m$qi2mdx^-A#+QI`&a z%7J$i=i^QcplB+W5&ke%1U!>hN{#`lwYeX-S`SEbMjKLoqt(jdbg%_}eU%FF^tZNIV9A&Ym(@)&{2<)<+THJWNs{+`(h4 zbDy?c-YYaPaAx+wx29}W&9wbw0Y6_15-tW7eB&ak!L5M-EF$Da;s$wls8(1Dh7Z$S0 zJ0rM0J2l5=akg~H9BA8+#7?q23wIGkd_?vdw6U`ETXYY~av7csb?NcSOzuK5t;k|~ z9>EvJh!T%hKnyZr46(KKe@8E(D&6U!2Pvn13Gu_!^b5E(z zNXHPl-owSWek^TBe5a<6zeSbI_TnN0OQ7xY6;0r2e=2)MW2+!y8P()_qyW@NShKhX zI}L11jL6HSztfxGkw9LumHklTRua`GY%$?zs@_mTaE0uY2Z7$w3r$h4KpGUvBZ12K3=Bs82juZ<5`D&JN=ApG&?*IwQL&B#ox!mB*elQ@K~=mu>~3cQC5Y613A z;6f*Yz+~7%sA?S1f{7hdg0Jw<_emRw>+#!2Bem|3@so1OOCOVZ({_J7*PgR+{N!5( z_N{BD>-FM7+_KDY>X$~rvE{R1@0WH5UOo(3vk2k{cC~yNsrgDZGKsRBs70^@+ZyIG z-sQ|?L=n}diAqRSRDcB*P$)7^6y76j)rqYrWZ`jk5GR3f!jsFW#*cNh7?1+51eSm5 z4lMLgy%1^9$yK`#R;Cg7om~e15}9V2GqzB7d$wUFZwGx9gcEFLR8yEpH6NtXkM2#A z>uhfGguoGd$Lqlmy2rKIGy zfZd9p-2nB%RB(PA2b*RxIj=xze$R-kL>zF^T?=Q}dv4~6f z&X&cYCfyKEfIkS~is;~35h8k@g-_u@Ca>v&s?}*)9r&Jpwsr?T*g3!{e4LuX zosJnRC|z7mQYZFcHKcA5bvf8D2=iEkU^b8yK)$9XRpH^5;w9s|o|f3G4;#+j0#Ar+ zxr_MlmJCKD%EIni-c%>VX2x>PWpTspj*r{Yp)WNw{$)fbn$<5hm(fW9B!$8jOaccw zO&VbWwM>#}QX?wx*JHXL4i|Ov(qpAMxmG-iCJW1G(?J}EV7e@qc8bP8c=vlh#Ot*= zo6%|c1^F_%fdDmLQ4^`S*ai(f49tPUkM|nR+m?k2PxS^j8452AC`-?TWR|EL0ut&# zl6=>6)9I_>Y)Y0W(4sJWwo4)4e^2JUZ4LSkDM%HP7a~@74@h=P+R}bK%-qay70P;i z`S%Xz!7Y9LPD4PraneTi6kyrFp58LIbZU{9<%cWu84g=JdWosk8unQs)KX299z)!U z$1>%nkY!T=zNA^M-wO_xH88HVe&;9WMU&b*-&ZP`Dl#+ia_{mjukWTEb(pnlzUn|I zQuxle$EX&*A*Ikw;ATk3(`!veba)uTE6cs*+HggIccAa1W4t4NSobT{C7Oe?M$-}N zF8Z*Ui-V7ykFVK#Gk+d4bm{nr_CIbYoBhm**X99{%tS+&9w)fM2#H|*s=2K`>Dv~mtD3i zEcpQ2x6}{THh1Ya_jeiI=kK;a=-%BYt~Hsn%b!;Fp1xek4DvA=n)RREaCLO^`;EaN z-3myJHIo4fx!@I*x- z(cbFixp&Pf?Z5{cA1EA&`sdg=+Jf-ef(&BV>3!n;y`o`IRp4giY}HU@b`6m;d`qwNlU@=dG190evj z1}>gxt5)~XxG=@l*~eKM-0US2DrgT?a%cB2id5r(+ zUT-aIN@LLG3}md-nvXsZKC+DwCow-(QI(}NS~iQL&fJJJC3#b$up2CJl1+e)X3N8@ z{H3?{x581hLVInlPB=4ErO*@rly}pFC=@z)$!@I0q7@yYden>-tPDO#)-TyTol$7txQ-RZaA)K#}4Z%yPV` zb@t_{D+5AQ>AFj_xCN?V=CZzhTTS0bB6ENIleW-5Z#4fWeWd>vf3O5o@uIO z)FhsN^*W=&q5t}$v6J78RrSx;)Kv`Z`?@mFCr~~1>!AP*mu;{6ol_fz*#5Na*mSVtS?6~x(e%L8C@54Cq>mzKq^)nCr z_pkbI%Vw%i1qjCL>T6S`{5@x)a8;MO{2Q%hnTNHL+!AKZ!yLb zGcE^?HiGYdS({`@ho4-|MzM~)MFVzs+}pC*+1aO(0&DK$prq$1KJtozHx5*l4&}|O zs2hJ=8oZr)eyTLPSdd?B)VhLrv)dsD_>e%Fe-ryGe+H|;26!(^+k*yUcLhO|{xcB7U~S(J3clBzokSH<*gy{PhSw8|kP zzs~z%H)^W~4Fbxw0}fW|ho&Ct79H@axf$3SCqgkxXR8koGSP1ayRP=#+r!`UF2p4D zOG434%3hpZW6~5f7Jho|W605A8+Fg=wYEC(zS8!sxY( zYzf7P?VQ-xRZ#tHUV6OVE~%j_oVgf~m-lV4pefHMqa%LS(12i`?`u|&?Nz;xgy26uD^U&ZCmTgTld9@VK&bVByHqu#>lS*uekqTqz&>eeZAto z-jXA0Sj_k(R&cyp4DyalDE;S#ZqOo${##*7*{TEcs^Dsk+f#kYrdgJWfz&BQ>mL7k zJ21#vZrpWEFj1dq)3=RLPm}i!T&=Bn{aPcmY-h)aVB*O(63T~r8aM;UR$pLrzWdt# z=8g%ed+6cTFA_OLcISs$y`4)6T$J=_p80*G+sLBEwJAaU|hncc50Zm#?C zyZ`p;b5q9+yGE#b^5eH`PyVg&Tgk>>DccSju8FZ^XGw$rR@xr}0)>OwgT$&(Kal%A zc=o85@qTanzXg^JUG4>aQ&dt`sh4S`fWh5x_fO{&2yny&$p2O6p*;F%`5jPw%g1D^ zr-FaV@BYv0Rj<0VuB4jf?kJq2C4CjU*GiYZ`ltPH%P-x>>&>%cG*6f1Kq)gWH~)x9+wXCh}}gm^VrH z=;3B}N)@&3>0Hl*<=Oom)I-g(g*U!LHqt|bD2`|`8cml<`DbbnLkpE?q$uS3myg!@ z5Lj+dcp28_O4~^EQ@-FjijNYgL9%w5gO!dC0u4C=2-~JbeA|^7FDP z?9|3$hZutMnsc4kQaX3@_m4Q4E?I4`dFNin#n#KaCY@YhjAF)|L$S3|Qi*g)hou=8 z@8Pn#P!XftdN@tP*y&ny-q|#@!<%28HZDe$_Jy{0u6Z<3O|>iT@6SHxMAs#bnp*CI zCdmB`{d8SCwv81^xmGq=pEW2O%JS#?;Sk^I->>mzRlCyWIq?L4zHL*6M`FGkI-yKH z92j!t<&;@y4Z+mM(-gT@rW<%s4HY-Vot}95!O=|{tLm&0#~dtnLuH$*M_*{|!@G1W zdBWSe(Yf^xQOK>Siu}{YK3Ar=`3YGzi_Z|_S!Z{}Ua{Vk`sL&5I}W$^yJWoft@v{K zbZ?=f=^obU{YkqrpS&11U7sge0xI5#fvt3ab&@w8R@F^}HU{hIqi5!!`kBq13RKD~ zwX+BCn-M$?ax#2%x1yc>`EwuOzO3pdUfZS@f7F$gJq_jtmi!OiZ z)vsUAt{TyAkXuhaA(2PhbI(ygsTT3K>%BZ9cab{2ugR4BF z1lfz+^7e`&>JxaPkIX2YnxKv7xNOho9^RIzHC$P2B80>6P(h z^qKx2-t#J?rTD6rdT}j?tv{Ste&00G#b7uTvgVMHnijVu7`u3W{EedmFc>98&0x}o7%P0(g>`2G>*?dr-i0{fC$#)PxQmVsR88KQ5 zaTeBjzQf2BjpqDBoeLxlJjrPwxR)n$Rq2#@+VvPo^!**@!`YJQl>(!>9}l5H3L{k8(+wD6~+A?f|g&Uvz!x&c2X6gn0@UM)GC$7ev@*(uQ}b75FW~WzR)d%?z{K7*&nNFT6ub zjG*|_3b;$)LNAf7%SiH-I#(pBlO71TI9w8lFA?wVL0@g!EV@tqyO6&}ZPh2%fFK@h*_(#&US&*~YTa zzdr7_sb;9USzKsabDOKMsK~Ds_(S3HRb7%hq-JBOjznz?U&yCMk*;Br&C)@W=cv>_ z`VHL#!rUWn{${2Y?dAU*ztrEe9k5mBM?2yPp2cS}Jj!z1M)s#2Hu%HFOQZg6p8~qj z^*<52wy+o92ddVlV=OfpQ?aJjxxVa5&o^ox^4ZG80Tl5y^d+qza+}fH` zymN>f|D_az2$u}1f#z-&3Ii>FBFb#Oi66#*!rrz8t<|WE3j`krSX%eO`EijSa)2}K zU%Q~$vKN=!KYe4c>d8+Erw)vM8^-$LYA1(1E?K%LSNHt$IqH8*7XA^W2}G;YH-md~ z;;!^O#O7mStGhSCn(cRt7vexX%et!e21SJu}#>FDHhBO5IoCzw>JLE;&>un3=Na}>eBeZ-1&;Uf}7samgG zRl2)c;{Pd%?Fh$>O8~SXLbg)1BAyrs8*NMP28Qk{JBqFHwnWy}Wp^_dUGtw`!g{1xbvuI-e8gfe;OTxF5uC(vx_~)g_6EO(sKrqsO(E1l{sadNk(38a?J$ z>@V4I{7}fo^0M*eXRMxXe4sYsc>Z|Ns+UV&7AYt!S5UaAuvuaE67PR1x1snr{f&HW zW?L^T2J{Rx^wcWHhUZNw-f}*C#n!YKl~+6&}6iG1P6;viwv(R~cDJ z5DqEb=j#u$na{HV@DnbJvrRZ!Jy33myU^Wl*0Dh@04jRa4Wu8R5(}lL0VP=em>f^T z2{z4B*L2IMFRj1gQ(G_Za7_ck87o3crg5KK*;Bu<-DZDF4_tOWcAsLv$5PVQpvlAg zPA?wE-`)73@rvM8+WBV#j^B)CsP8hJocnX-cOj)!xTst8j|w#p+527yOez@v@Y6oE z!N+vh6V{NMX^`HGYwp7r{y3Lw*BnP=C1sJTCbF0gvxqaqT?`fZhxdEjd)vo%7dLc{ z@GI7TY6!aZ&SGe;soq7RWUGP>b(l2XUGuoOoweA;k&kkmBNEkpGVXRfDfQd0@j(bb z^TRc463Cu69iFE2>!p=zA3AH=b?^xCOz6QA1?eFMIHMo4i7uBYj(gXar%@WPv1zzU zSIz3b00kRJH7;h!Ms&CIRBRZ^FS+CW`qVTX{-aBLDN|)JI?a@C(mrV2_A*C=;rrg#^a@ zcd9&%`0GSQ7?)W&gQFcQf4{I;HrOW5Jq))S;sRz34QCB4yG3*SCyy4C0ZA~~M1zR`Z1k<5Ye zD3b5Q>0;kZD0wnuRi@#R>vqte~_^D!sl@Ii`qIOkgX?zMI~=iKMsv+sGH{TDpsOY$+s_(pku zZ$T=b_g*wLPmK~?_GMQe>OaQcrg024A6oDspnqyxN!kxs#wirHsFKmvHrwIWmfSWX z-X|jfi{8Ea_%q_yzqJ!KgI#2CV!crmy2K-Y$bzNphQIxjI4VETWEN{&DHjq5;#M5M z8l7eKK;)gJbuKV|>v4VpNj}@WU}C##nCi8vgwN(=a#hh-SW#JPNCG%t>xl$Hnr9qv z-e23mC)HTP!FJXQu1>7kPumY&7Fc!$et3-~m_TtH_&o|Tx+iU=WM_D-K(dQ2&M39A z?r$^?O7}Nz36$wK`NB@pz1uKEDUV!uxBn%JhyLb?O%0uw(AkMuL=afGBPCvFfT6z~ zjbpRIX?vjsB=;=MD(Za-0$%EH3~y_g`wSOc%gnty&ow&wjxp;SSOlF|z;5tb_HF%E z(G%~>b~h+Anb35dV>qN%BqX?3_g8Z1`Pr&Pa}t{EeNh0En*;R>OJvy`B2e~fyyK-d zAlFO!(qtlOs<^$w!waNnKLQ-e2~Z~}Lof4uB(PEj#Ym&?L`u-@__4btzb89J&VB4N zn$Z=STfXZb3!1L%uP$P>IQqqmP+h0|n1up5$=9U9iZR^Fo#M={7Tp4Lu4{>Xae_;H zIv2|?ct5DtiNDIXubynTAth!vP=PNtcu#}=@)_mpaWM?O*B`nz2I#gS>f=qed>BRfMC^o~|9FGIk zPnI@*OAq~;99?moNP*WBDPC}yL@QRwa9UUBroa`LVQCmE-FgE~@^Vxsu2il#L zt4I1=SV1|P-2-xW`ukfjdpZne`!s5(p#UH{gPtb#v!1>B_W&Ep-#+K;PaOjIoZHPo zrL^SOvOGWP@4`RFedgPYxy4zox2 z;82Cvzfwu4{^QC#?KR)Tbhyn*HD)Eec7y+H<^n@5?lqz`~`==PhngD!9zTJfu zfzOvLaT3FxoFnZE9;G&`+VrGkT<&e{pAn&Yt^gC!yOVXElh$ufb{BB{GQixvxAxVa zVhLEm-?weg?=E$NgPRmDD%#REM`X|i>eQG)3&wR5M2tBqW*!YcC_nJk1sNxS11A%Q zz`$z~J)TvoBvtz*$JeUV!eC#+pjNl%n}iYLfz!BRn9IGE=1ACMHvNb_URY=+PQm;1J^BF~ zO@>657ZVeg=);*%EAeX4%LbDZ>wmyFhHRq~yG#?1JBVu?f`?SFzKgg0h`Y`$>+!g^ zyKkym{z^Vw>iscrmu1uXk^S~39O=-xFxR(z9v`02udv`D;Plg|4>1;PxyU(tOT1aw z)0AOP5ovrY@kvQAZ)PB}aUK0-gW-iH$(9BLVQ&O5Gq~lT^Xo^00i3k@i{zj_X6u(% z=%cUi-5)-k7P?0^>${h>+zfu4OTU@2iORVu&`G`w-&iMh;a-Zng0suJYJrja7QmjeX2`dBR z*)o>f$K##EjkvmoJ{eV~X5^a^k!fgbtyA00kVZ4P6K``DUJw7;FnZFDe7r>WT&_7T zVizMf_2SOg$BVT;-uIr{Pdp7_A6^SlK&Uz(Qd$f>+T`u;Uv)CkjM#N5Cu`<&Ztb%q zzgs~ix3I(xa}i$r>y8yFSh)`+cFLBoDi1$ddG`yVPw` z;~Rc?9&^Z6<6A~vT*SF%OPGu?xM021cTaA((7d0}LoYFEr1#OjH>6sxDubGa3@*Q) zgJ^B`lKu+b++?kiI9DxMT=0VEmF};&{nKR6itBd;d9mRKw4->Q?08Zw{64U#C#csE zDuf~<$a@GI$;TyOR=%n1F{n~ulP&6sec--=^s!>~+M2@F#Qxc%`R}|4-8U(ph7kJ! z|ETy$QBxZ;OQ0>z-3~Sh`jS{{ zjJGuQTG-)-EUr2#e&LzKXlC#QIWXaAISUNdY?{{q%k(UNr+9e%7S5zQ&9_T(dUFcL zyAjO(SCofPpQ z6|3ygt@?*9JlDUNwx6@*{I=M$JM~Y!+qoslS!UO=+I!Cz!VdMp_b#j_E~+jr^*>{|s4$@YMd zk~;u9znhl$1E$js@XNJ}H6S}`HA=Lui@0QX2M#&Y;NW}q5{Is3{q1|Ic|@^PGEilk zAS4a|t$|l*?~C8Ke@gN+k2vQJ18vQ_u`PaM$o~D+T}0G8&Ac6;&$a*fE@_GCET}+? zuOmSl^FXwfI}E`q!XrRM;0oYpwSrAm(m0SW{_pu0{)=yh_7Cm(Z*OJ?L}W`bY<_kL z5_E~8$eI_bc;dkyM8;^=xUEPmY?n@~172r}QXTDg8RC5>7lD@~-5+%L|6q*#_XU4F zEB}9J2L4)y??f>6p;<%C5ojOKVT~se)fj6L=nCQEFM}&p3%v_Egt`U#ecWQe~*v< zej5J0*5Sn}FH&Je>5mVi@uv3;0eEHR#^-eigx!4r>*h&DdE67wJWR zz{6PY?p7PN;{``qwnckvPTE?CdCP3^OWo`GqE$Qfr9ArlyH7Efa|gpRueonoaz>9X zc^55wZ|^ZTY8uHMSi+JMzZ&)JlgNew@I2IUYeS~-Jr-xIVZ+wQ2@~$69#vjZl;H){ zLF8Jg~i$MTb1gMnyZd2@TXz^YV%I2&5*i;)OjlIUh2MY5D@#$DdnSj_0~*#PO&o zC(^3+oG#~*mq-1m1v`z7`WjU(4QTiBiW)sOLRr~%`Qy$7@*`=r6=hMkPWq&sOH(0=>`Ws;gq`ZzSYfm1krun=F;IfA;D6 zsDsP3=qq#%>kWK0;#hsg>9(0C)-|y%`4@|07b7<(Y8EFy(EfdFZp;ePh2I&~V>#d7 zV_w>e>iWL9UfyPp;8w3=rRa%-7}*#&nru>)X8BxtgXrSWbwe8k{MF~rYYg7Qc(ARR zbw!hO+Y_o6Pzir1{d!{WC^^Qb^E7oPz4J55X<)vyKbZgP*zP~xq4p)r3Dj>_W{;?P z=2R9eh4{`pM@L$kao|{mDX>l0IoB(eZT|raehFOFCx{a=JS}&O;}6*FT*+giF_LGG zgmw|9<%RnQ@4*}foG`9KfaJHvvz{d5z(0sT%5H$1`MLE!8CAT8A~b*YLBOrRL>Z9< z;OH09etMxQd#isb?w+Yiq%5gxpR2!BpRuP?IMs*dJ5Ra=xG#^VixSB|R0WSC!D;&? zeMsI>Y#i{*I$(K@H``=wA6gW@^v zhfng-tIMgsigHm%uy5dYrUp7_=e=O>77p<)z=c#}2)m(bSfzP@rGIUFsER2NFt5#?4fKBBhu%TfsV}43)T1ypz&~Y-=)g+L5(Vd7kS>Cr)3bpbV z*=>!)FR4xD)OupSkzfjH7J5UZ8neqB&uNyRNDC)DM6DCHsyh{z^Gll&2%Ee;R&>x1 z;}RKOWa?G(wjDiwXxDDW@ltag3TJ8F;~b!i;1@hX$?hrXd(~}ANk@|G7J7TTCvwjS z%s8T+P6>m^J8(JXAX*OZ12S(fd~ciX<>e9Ej1C~z7W9=p5edPcjZK$sV+!el@5Nj? z@9ag=12oU!q&ca7mfem>Acb6bO749nYWqxQs(`~doahN~;3h5_AW1++aYy_HkaLXg zvnVf%YU!Iq+EASk3G5b=htMmaf>R*N#x|nr%n&L@9W8GRS4KM)LY^+=Jcs^A*w zOXenO_07^MyBymvCv4zVS{x{UD|--f;w|W;qehj~+|k0`PU73(DB`trL|?980pbtA z?<1+U+&#QX&fAG)vxL;)cv0qd=q_OGoT)X{klcL*6|miDxki!rKw|Duc9F^;YCD;O zc#BItSN4|5p!~`;VXbw{J={mASZ4NPN@sJZv(!h#-T^VbEx}qHkLJnLA!8A5d%>1> z=m{FQQ|j_h&vHBH2dtvJrX$_q`_Y`l7Dsx)#F(!l5#7rno?o!;A$=zRo7*iR!z>>0n`*{i zUNZN)CccYTlz*zN*zvCr-k&}=|08Dbv-VwD$By<@ntb~K`*6a}i#4ixd2Q5br69l7 z5agUnl8f0=#LW$VIlz0|ZC7pk6S@9d;?zIG#?A+y{ZBC?RTZ+gOb?{Z5x?nfqhPGnK`747=kbJ2(_* z-%iA8e81hq^Cgkjnmz~|eV6E=_rx{q=(CIenxJvo+p05&IrZB*xV_s$$uZD5P01dS zWj9D?vS42;$@TH&?5r|l3q!r}_KRte8CS#Dp%&y7p^Vpj9pz6on9ME*e2;qL=okhRH@Ob zlnH&E-ZSSs>v`u}eI_hG02p6JB6kpg^bOF3^#;RqW^av#PS@Z*e()WZ4O$*=-(6*Q zl>=XaxrGaE@O0vp#SFze)TbFny_`Df?p*+QlJ;+TkmTCc#r1IRs)k-aQ+qrfSmY~OhM zVNM%lQwmpe8^|HSBLj+J_ThZsk<84p<>YvifPR#k9X?R82XRgPQQOL25P;`MDh&qN zg$O(n9gCz;8|bp4%{)uyA1*oxMV!!rMCAFN+|URDnps?UO`h!lpjFA(a>j3CnP)2uNjYBHx_c&;2^6MH+%xyrar%T`s>@;w&r8p5 z6=Z>KNtM(gi-|Gw*p-A%76o}9D5`qVZz$aXtTn`IP)P%AyZN=}Hv_#dzw*&Q+^w?W z_@a(<78$-S+FaIM+Tv^B_?Y>*cJ}(|y?4U)@EF6+wWJ3`g#e>Cz=y>X*(fc%0pI$O zY4tNmSeMqF`5Y*jkCmix`cKg`Ui%sNW_1=$7fqL*FWN?}U|=c2DT}Gl(DVygC*ci6 z{kjsli$Xi+P)rrr-7njhG^ew9MIB(9J-#t^S@={?jT)=mjUk;7u5t-{OOuumilC>`BN4=@zJrRm1T$h3!o^#V6ZePm@@xkYTb?g?8W6L3j^OcgKI8*&%O2N75jipTc!$M zwI1x0<rHs$lyO&b^&&0yHn795KD$tS-Gp3-Nxp<1oe*33&w3RYs1!=`IY6VNTVN zpD|Smz@V_XLaXrAJJ9j^8EkG=nOJj+IP@5#o{DxBOp(fT?-`J*Fyfcu@Ri!iP;S0Y zxKOwLcH8|~gnRouUCLvMpb`-{3!fCcapaIKY#drb&vi}H7%#svL4;g0vBrrw^x9*E zI2?H;Q9*JjLdW z(^f%uu^e~PQDKAmagF}gi`uEC&uS;zVPQa_*54vH3OyHE0B`wXo@bMhtUKW|O^M`M z%11Q#-qH%Kp=op$T3Yrz@+k)FoZ8D-UM^2}e?@;`zHguC1boBbRfTC-!|Y?{rK82a z(}!}=Z;0GS!;Y8PZPP5_F`N;{HeueuVc^hI?WqZgAup#oG}pUG!^b=~iZZ(i!q%y4 z>vigjzGV8k*2xx3Ovs6!7plRoJX3HOMv7EhB(mK?D=58jP!{YF9dX#2!F^CLXTak9 zpdl|Da^N^oIT^@$W@aje?Amt$3a%rp?Je1S}+&Ff+hazWyI^03)_g-C;fBx&& zI=MRpb7IXY|W?5Y$_hrsr;Pvg6#9 zZpy&zw$s$&ZoEbQM0+bHFeC?)78aR>y&QTu&(24`XnO1q>0#n(u=IN(hkhq267>7< zO1vm;6pwx$ihDI#Jbv3Cwt>?RUpIBTp(XmYakVCAJDHt(C)Od?1{eelpQP|6F>0GCKBhQ6rSG_j^zEh=R)BVD$kirzldAfxk zT+33o+??w}evVO>X#3iC3J>oL)rYTjI0!U$+N z5?UZ^iMd2AEwfF#py~{~$C}tOB30mYRLq~^kP~YV_gSSybwpJ>s>fu+(S_9#AR}M<@!uG-z;JNSNy4~9OJTXOB1$chIyNNRY})$fWyER*Gdf8sj-K3 zRO3!>sYPW0#!=USUjFpbGx)=*6s!CP_6gq|_;sJ9q;f2VcgdY5=w zT!D?$Jdt}8EKB<0Ncv^C%J`tH_$AScD2q4a=g=>Ezw)Ljnqy-{uAIv+C)L%RQp^jV zKLuprL-0lUIl zj~jk(9()%&E!p*z@Wn&7w`w1M-x)FiR!FsQN%HVdbhkhz94&-g~+sbDjCf6BJX)pg3@ z17)ghT~1cuMgP^$F`ibB`6q@DBqYzV4bmH{LqR*DYFV)ac(+6cXTM^Y4tZB%Fp&ufkg~BUG!#JR6rMn7Lv|E z8DRUS%+wP`<2UpW^my24lXTy0`f23Zh}V`xcH7#PVR>9nin)j^dqDFwa^SB4I z$9uh$HCPZ%(|^PEks1)nRZ9F`K_alRFWMm5LR?`xJS#U@VH95!*t!=TL(rh}qwaA! zjR#a}mtV3Tpq+r}dgv<@=pQ$a%^Lcrwz*7z@X^=LfbsWi-*>@JcM>0Z#9q9gm_#tb z9p>29PGQKWo6hi^Nd95jb?hmz8bf&a>>EBIm7^!W)t%?djr>EfoH39a8&JJ{RNiou zb;gTO1H`zuq~@CHSdf0INCm~oZIss>a=rr;HZ18Wl9I@loG1_Zbx=^+6V~hb+iATM zxrehL49A1YmN#RkMlWdgHv&O%1~fT>i;@ks!JyieOH z+RNXb0md&38awiq509v_d+9LR=X3k&oS)6w8bbrD!4>5TlWD%wrpuAZ`TYYEx1W@j zJ@*XsT_Y3n*GV3j$ZaI-1%Xx82A!`(#xH!~walyZ80#%+Z>iN0^I^_thOvW%*Qgg0 z6Z(OjG&&3{i8P803>~4gZ>E-1B%f4rbKg=&)K_$Q z7x{VP%q9nePitsrQIa<*cVuCkXvzFg_Fxqg>cBhrzA}oS%yQict`3eTj_K&hqw=X6ysmB0|2_ALa z*GH~?U4RYs-By-*x-LX2^<(CmF}q6#)_tK_;&qbGn(yEjJ{3PR=g1%X65MFw|69eW ziMC}=L_TbW&em^7vbTc_{G6yJaiuePaSsJN{qBF#u zWv;+O$E(vJciiP_m2>>dR?pCz7EHM>gPbAh&$^v-Eb)O0y&kpR3!!EV@59zs=th^4 z5p4RMQc?s^{>_wds<$3}#9>r{TtK3G$^}cS9EcPHDDRlykgJabw zpy?7doI$S-vD6J6+JCjI_+4r0aY^%$%2QA_{k{gx@(7+( z=~VzBE9CQXfD?RB@^Jjt3y^D$H+8vmF^=Nz|LTJ4g^4p(w3nmIKG)WKo$f#KPWxKD zPCevgf73v0Kw^k}Q$vQu7eRZ* zg385w;yMiT@s>H(;d^!U*4uh6F@ArQ^D=M3L$xEYlB?a&B2P`LQZw~?&a`-HNnI<| zBnpKh@_=jZ6~1~Ss*k~ukMC}aFy6;MQ_Gx*6;z}=;)D`cx@$SR@iOz*wKwmf_5@^D zxV9Tnl2XjGZ@+%TY|+VR$Y`y+6WUb!ldak?8)+>CrM`$rXll|{1lbZ=xxa5qMumAa zZ!c%$T*_-TO~+Gj2Xuz`B%!>GQqJ#uFO&8EkW}}d5$^s!cnxplarZm>ubFkV-;-?b z3WL`vY3}ivq;-p_6&YPYrYSu)2PP{r>IQu($n`-TN0QK!z%?c`&uzC+V6Z-Q?@Xrm z%ZCzr(NtSre|0K$YFW6P*0Cr;l5em6_GDk|AG)ijbJgVpqi*!PVM99`*IUiV@~q)R zH4w+Ux|)mz7Es!y&vOc1Pu?~tiVIj{l7VuN40Ppoo2*%v?Di&V3`G4R6wBporjaQOz&u7Z*S@2=FZ*li?S1>E=Ihr7y<>E~!-KPk8Og)sL_J1om>Jx(Ef{nD$8|`@AUdF@W3qhbZ587kl@vzOffsX7j7|(jpl#-S+v6 zUDz*^7c7X)`zjW0mGzcYBuO4BJ|Vy7C6aoFL&+Ir&A?guWwayYz&}-LunVh#E2(=s zVX8rURDi-}F?}3Ef&$`g`p-o68Tti=IDN3{&R+TX(Q#+L<9mJ26*2He%PY?D`s=l| zhMAfB9ip8M?wSkP%AUB`v$Hp6qJXn$?T*|x z<&(S1DcN4uu-S{`#QoIvlDM1LNbg9y;r7Vh*-nSxihklEpk<)OCXSvs;Vn9W@|zLY z=KST@fAH+j8pXSi5f)bG`O{5;l*OJo=0MX}e>0`oZ_IS=$pH0p^aFc!U9W9Y$&;9h zDCQEnjc7qw{Seqb9N8mXQ=_%p1}Cy>8+Pdm3ZJ5mKJx8zyIsg4GDMgb-{!J`S-+Go z4VB9aSCJ*I23?DfnEgln0~Foe8q`|S>3YN`g7RR5#mDbDb8lZ={(fbn@3(~5y|+dy ztI5zn+QGpeFrzNU;YW$6sbe2P#=_g%S1R{6Syh#lymG|uIb%@u;jL>6HHc-poh_L0 zEk_y-C*&F+rx-^^Ao;(3$ZpxRZj*NCm7oPniOHa!^Sz!y`MGV1FF*AYI*dqcLl0nU+ z=)m~Dk!ZX$$1nEuP#tE8CSUTJ(w3Pu?y7%@58`$I?I--5asek1eMn2c{8jM*6ymP_ zI*JxWD+^8gUz3sSO8uz2~1onf1vqbUdak1Ti$lC>K<4FZxeEF|H&TvhqvSbYVUnrfZ@!`p+#$HfKT=c zkdgmOK12$BS7bO4P~0T8ViD&Y0h3Y@D@SbCCl0v-8tt}r=_v4ewQ+IVU$0Ar`u+12 zQs4+<7C|3ZL-GuNHj}q|Fd7FarGsjKH+>#7LFKH(?!{Dv5VX^39#y=eNwVtaSM7#F z2dfM~GZh22UocCQ{FAWz4{!R}ZvSvI|NK>6Kig5WmNhSjfYiePJ=+-2z~$N4e0T05@M7HfI1z)hzx^%+D&0T;{+dp3<*M#^>BmZ}~M@7NL_GSkv{0GU?= zZ6BNN1!6`8UTq6Mixb$87;Y3WEKcNYA997#hzei7-l<(CuD248^Xdf;UXyt7IKMd| z>W|~S8rg3qV}7{-2Y|&r;1niKB4`mlS?iPr@ z)!&vElnrhuBf0QKa!BO9FN5cCv|0zvHU->0Ej3Bgsp2lR&e7fQ8Z>iJu&b9oluRl? z!~hiO2Mp4+6|FZLRPhId(yOlx&jP|4jRsm?n!@7!Mf zd>Af=BS{p@c+@D0)wTX}-Il9BEf3rPTCL_{9(kyJVE{E;fqUCx({uMLN&ZY5g zVfBL%Kb!O-@6<@0vT91&kaR75=#IJV^jO|Ff_J*--5VY#a5t6%^B;6#$`6?OFkdV4 zNgxLSopm<9j~XiQJ?^t@77E**ZAo0aEz)X#X$xBEC;>6uGYvzUyhO|Q6KiCFUw*qt zC#43UZy;YTHz8Tz6LwPbv4AP;CG-tI~_k3v^UGat#V2@h1DDdy1uppb>lc?CaqA1sc=?C83RXJ4& zCFlDDxl}-61It;(K}|GpW~n`vY*O~-z-rr=A<_l#k*@)ow~0)=9v$G?auBrBe0QM; zetEbu8W^Mp3%%`LdQA-Xnhx%ung_DtE;Fun^w-XPY5^75)5hLpZetNPt9gS=sptel zv@w@h1199R&mmp)NCSLmKH&pV3n8f1)^sBG%oSJz_HQrsn&tXNXMn+mR^l z0O;PGAOv?v(zYBWQu!vjgko;dGHVE;mo`NZOmGF9d6v|R4um6Q=Q|Vvyd?_i!cRcn z$a~JmO1q~$2IoGGxg~X4#Ppxg(15Lzn++$b(7;%%*@zq}u28>2FeZFtskt_wH{e5t zGY;2*z8$4=Tv-w5mBV~%GH(*WgtM)mUM!G8-k;~nuorS(nx+qZ33NQsf4mcW#F@I! z)!lv@Y#D?BYdw?HZeal)KT9j_FIC`h`8AzS?Y^N=DLP$kX>S zwMZo+KM+;ej#hBNqbpel zAaisRSpj|Dl(dTS0~Sw$OZJIeps;-tE@t)E``R*KL7lC))+^&*ODw=yi+!&fYwCeS z!IExl0HuP)m^P7%HacLHE|Dek>fSR!iQ7UVhvGY&=Osp!8flLcH3_S6wskZ;dZ&Tm zLbY_=a#UUXnF~DuT$R(6)TF87r9BIBVS9(qB{X{VEKxFcf5i$nt%L=mHv;l~yin2* zz5$>?O5$fH_Du|1dZ=p%ehcatD@E&} z0Fnm4vYDf3EqUkDyr_CTc{6l}L>6+Dq`g^E8+O8(VPfI9 zf2h4kbVv$f^TwQ^5;KuXFPM14YY4g!st{r#<9EKoC7%*!uzM)mhhgGxeD!eTP;x5ZSSH>@^V%ysYvItv z0wYj#U9%0O2UKR*G`fNi%6?qP^+JGeiS}eRake3q4e^J4EwxRp*QXdMPnst~kw{e= z{jGeBXEL?K(rEFESx~j8M#}*C$6aRAbU9}DSKw5i=H52Vq?geW`4;uo%HBCpE=Ptx zC9+Pev)Ih!2MOtC>g$&C)Z|m~9XuOMdNg38^o~B1aDyeHvvQTJ-3OzB=L+Pm%l}q#-uHPNXN-%F zS$FgG%`Nb|gBoieHEF!sQnYw>hxAJrAwcp;4M8PE6Nj={Jm(mqX8{Y+trT616U0(F zMXugL4;*F~6+O|`5@B+nL9xF12f zHP%|Z@A$PKn}lRk>sqa6)2SZ_mqwEiI3xS=t^mys`f3hxt@a-!BA?FwH3|8Fx3EU| ziF5bwX!i>JeJTi#Ku3bf^WNr`R~}4n!FML8KIuPCo4Ke+I@OKzVOX)5~CE4VIB3Y_hiV>eCHJ^9iu z;(Q_|Muf&(9HK`ssSie|aqp4x#w6GTb~uc1wUTe|(_0Z4PIftOEZN*WUoh;Gay!lq zhEo?Q*(^5R0+wR*A&Lg7ULHMUL+1Qmbxx?$HhfCBmx-xxeou!`S9#b53%Dk+c4HQl z?$lFSDQ|;R>_>YKnq#=9mq(|XTnKbMw_O{qa}QVn`~LjAFRfsZHH&kvbE-?y#_Yt; z=)URh_Ds#+zX88Wzd)uUm+0!Y#0!p)b6#Oo{0U1BqjVErkPtoHs@VB#Y<)wC8i!Z3#;J#_3 zo!<--JAwDNdz01~)3u2;+h?pbyfYOUM4y|W0auAhuW74tqqZ{iMGm^PSIVofF+Ep} zqdoW%xc7|Zn!(+37kw25JUfOnj~N$`&wPS?6+f}og7oSUJP$gg2d~${*14FH0b0L8 zq$7SXk6nYQNJ#e#C9?Ywn?x#|XBt3&-q$*PWc7V1r&U7SnJxyF?${;Rt2g`Uxrsb6I%dZQfE%t!;~D+C~^5+yM`y^_Heydfe3EAu9(LJ~AdV z%n7B4;|!R9OV;2>f+TT14; zWe1JVR5sV#_wwdl7&#BA771a}!j+aegIP!<<%ih>} zhGMMfg22Lf`P8U@DOX38;|zUYm?d4XPJD-w_(cPhFEk(`9}DIQNRMyUnx*O;BJpeQGpSoY6W zh~#iI&%ey%9F1IaDJdl9Avbo%3#p8ZwzVt1w{2V9c*9GY4VUc`o#fA?^BwA$;GkoG z1{;qJp7fH)vGaUg!O?n+)hW!(@a%)CNfW^q5w9I|YM$gcW!kBtM`Gk*u3e&o!LKAA ztqs}(t@u#X`&5nKdnR9Ix~d9pKEstb+#A5nX&mcm-5jyKR?k7cHo80OH<t3)$XI5Bt1((Cb78Qh0|dRd2E@d41o${jsxoEU$UPTB%PW!?;7dsP~TQ=Or!Z zH;0E*I0ilpRN3}0yKf!+XS@Gc^-D__acfJ;wv8KJMM&L(S;{n0GfjG}S9|z44QfHC zAut)<&Lrgyj9Y6{!#uvDUCRUYPF-E8u9iHpyk32pEjTEj(R0OCp@VW6Cqssyuj9aG zkN&{%7T2FmpY}Ct2tEVfQ)Fo}tZ8B4eke45ubfHBOa0TXHi{#&S2quj{h|q;&=*9N zDWbBq-lqm`)n$%ON0qV0enq2*s!fS6m~G0(SQU=;%X$U*7wh2GTlao!*?ktatnlv> zihq)5|G3DNXp4x9!VeNAgO0%_oW$f$yb{xGzW+Y_tAgr*Z=}blOxEUhg1U5s&N@S%3w+!I_}c@tKOvI|dL;MUm_)?|WnCs!Dg;2u}KVUj(I; zsk?#@sWhhtQplk{Xy)A_XP!m9#|Bz4?`EepTy%z?Sc{c~3f`L=P^0h$!+^B}UGb)x z4(@&1c|C&y&6uRepC08b&mNaP(Pg-?@Woy?tFMJpsY0;JX+A8z4Y~^FoGW&roz^n@tDg@PjJ3kY&7G9zE8{b&2aLQvfq-t74(}sM9 zzf3P+&>9oH%oCNPj?dht99PGOfY^&dKk^K>bnCCwQjDC}dvhaZB|G=tFJPL!L1;^J zBt_1r>$z)83Gn5NRpb{nIxlBqeT}E!N`nnIWfP{|r%qv9?pHkNWfHoHf%_|}GdcJV z2dr8I6+oK>NHuf;tczl$V&A#FL-Ok&4s$}oiR7J2&W)P2w7!~rtW2>XTHm&B^I2-N z{>h>=gVSFfcidPuvt)^i=j#Ld#B6!hh5ug zs$PiI>qV=nU2B3-a10i+-87Y9XbB>c#IT8kSpAgkOyZAWE%H=d8C|N|fG^7x&IzE^#0b8&;X&*aE zo@Dj4pvvhF%XRa&zbV=vEITzh@9>e8zwa@HLTWD7+i}p|t;}wrQ?S7O65Y_;hyGTm zIv5y=MAk{x{40CtfqxNe=tXmW>JYM1$cxk=spJ2$!u_v^6aFrs_-DDnOU=g9^g3UQ zfiF9@fotS|Z^|t93_z0Qn&=CRTI6y%E+|cm_|`gJQ1%1%q$s27(eit8rR8PSG3~0W ztziZiyFdMTUniaTi3SVR?|0qd5Vnbq@;qx1FdTyeEKqL&6ESHvD`J7Afn(GMJM}IG zEyE)%O>*3(GzN>T3RAtq@=)@T>7M@n+f0K})lWx@DskJNcACOObRZc6_C__^=;Pn< zV9vd7)QFG-pOq3sO&19pbLpxA1yn0v$E&`8Ej^C(2Dq zJdR$rqQ+9RR?i&PdGr0nyRv(s7hpF^{0{AqRsp+H8vP1_DXeEH;kAUn;&1TU8j#BP z9j0SV6@GCSIj*bQ*_B!owPj1VbrQrE z9tNROzgufhB2?*K@R&hm=oC-r_>THEy*|^hE2(jC>PH97UtyKHKFQ#$=OP&?7`+r?A1_&DxrWimyP_YSN>F(gtSl4fh0~)G^3@!JuZkW4K%BWf0DasbvXG z9X;)o<7VH6ypR~ZU6QyrC3Rx2uyV4^A3FKnu;Yg45FM&fJD`nVx&GOtwb;0!9bocFEWOPkMs;fE~2JpVbK8p4In4yszYv*1ztd?Zw zPHTGV!{WIoLfa(a`IF|RCBn-%!=^KxftuW{r^>9?LFK=ebsJYc)nCv=S;M0ev3f28 zHXZxw^kY#-Lz|G1-$!^5|I4odi^XTRQeU^{|Mp#Drt8*&$&yNRMe}#_bPM#?+7?@S zsNbV$B7j+jz<Ue&T{!3PEu+(U zye+RqWI0^*F^+tPt-ZZTS7$?Gc{v zt7{24@TBp+QDdUob@|zuS&rX2LSyeGBuI4ck-0`yTst=7iR* zr=DQdfBub?QRG+VtDC~&orgoZ_$wiFifOVoN-WD#&YsAmp~Df3h1ZBq^%`b8wILAu z19s^+mmJ7QmNKwxosfKP%Q=JUgZ5o0n0ZGHAI`NEex1?i&;5z+!lS?q2YN~iVi~gI zFc3>8A&~e-+G!67@S_7a-6SD~_>|0Y9}_^`2@Kn34(*9{kbIn3L!f^@Nqkxi7pVd; za`DCq7IW)?Ghl8f^TraMeV)Ec{miQhUG^^t8Z^7S)uL%amc1?`t6|>UhqwQ}6P;71 zJC&1x+Dj~1oCuctjx%{`;g9Yc`)cC!wUX60I_J<_mOK%vRYn32`VMhasa;h%mbs5T zxf_;PHtFx39;a;@Z!^fa8(!5q;`yZT7sZK+ zh=@p&8Wj-{Au3I3tRNsnK|pB{kuF4~1qq3Qh*HcH1Qdj*l!%llgd!yoLYaz))JP3U zq!UO4!Urkyd~>gT$GLm$ea||3pLOoIW8Cu>kYPUG@2$`KJiqb>!Kqx|&wTaeK7Ufr z+UWXA#CPhf$vw{jfd;dfW@32j$K4aNXR_;?2P;-*KX+9%mEE;^!4JlKb|+mj%4TbG zbi1GL&Z>ne2xNV4$w;jIJ|1!uzQ^c7>gE#=nuOLNqjOH9HD7PN9A7OP z4e&C|8z4@x3#`PAHediNy}#7{7$>)Nhee4;4*Wq~d;~t$r6{XEwLAdheWNzRwm5d@ zeXcX3HaSb1L&G&HF}FPPH}0`;c^!OzgR3$`@6=p@MOn3zP7ew%mY ztC4+iMft+qXY+EG+~p6Pb^I1?miSr~9JN0{(%@?PUR)W;u zjSrEH$3~3rhURMua%!(6?*>AgvWw2czSwj(TJ47^YBXZo>_V0wo7J0)`61V?Kz@dt z?He$pMJ%l=*L{J>`#~<#rp#XKI};Sfp8F4^k^gxjWPf3z)F5rp-Q10YOd9Ugr2yd8QDX69xq+605fb)YU!=Dz~sN3K>lNe)#0mEssxH zbqR?uAKXv?Z-L{VGyxyRF~D26$yrVfA-WvpI2C6PLW4jIZe;BI<*J6J?-rLBmWb2b zop|*HS&s@raYu=|wp)m$>8ibIN8im0Vrmi#pwiFgc3~3sMz`7wc$)-8-6{9Y5L6^2 zFn=2jqu~J%E^x7}ad0OJhmvez z#esH`tx&ljcTjN+?1NqNkZtHVUt#&1IXRnm2r2`wINDu`x--Xj${DAfukZKExg|q_ zO%zhzPfn-&RaaJlU5EZCWoReeghCrFIrCulLlPr5W0rM)qHF6R5M|aRRaYvi7@&@U z(gyso1*}A`sFgQ0Z#_^}n5ARq=y&ei#hse}(wi93AF%gA!efT;IYw#*FO3w0sz38S z&NUqnTmmzLs;FX1WBV6n`v(O`R(W{qxNc*0Rb5l#$C^HnL1SN=&-fYNe*DAwHH~tP z94{1r@{fTm)Ny$L0y;LG1~~zO^IU9Ox55={%PA&KHqV)8$@ip?tGHa;=pGYCCwZY;y{F}H-6W>Z1alVYT z)-m%|kr@Z~$gq>RWxfZ%Q)PooC%WZP;izar=OeecDyo7aBg2 zo{6Uk!T4t)8}^>UE@iSoZEipY{fRvPuJA*-)?z^sAJ+BG?WmKzN5z_*u5u_`2K{rn73Xr-f@#-ZJnPD?!~lc^GyWGJ%6!P zWHAHA8Zt)(vD^TvC3Ir#5gH71B$bkXsw7d%RXyRdvt)G*g!@281|~vgqpun52qiAQDtS%(wTUj4RpRAjPtK7tqN(n1MZ5Yn0hFn&bi` zFkx~)x@7s{%DmK=Mo3(+PK4CFd5BP&G(V5hzYfwqhX^7`UGT9Y;ZyPf4}lk;z_*+k zR|9Z_A7iuiN+|-675xY+8;RR~g?>t_XrMMh3&4SEPSFE6??4#!o=x`-bRBeWn2lZ= z4gqb_Vj_`8B?hoNDE^??6+!}|iM|C?ah94{R1r*A&}hS0QbhaGIv!cLy~FPb8JF+X z{!Wr&6@}#RN?y-MzONnGt)T8>Ehm%H@E(Lgj9`wS+QorSMKCvO< zhG)g6@WVurq#J*$XgJ@Z&+3q<2eN4a?ZJiE_xNx|F~;A~AzTQf8mGY{!~>>EIr=b>w_liz4JAs=SnUSMnY(8w zawPh8?>Uw12gI;Qh%73+HD8W05Xxq+>f)t=s^$$^QlmowHc&6?<#1YcR=Ijs;c!?! zjYre-4g4;4S(t(KfexMFse`;P3n(8d(CD#J{sGi4N`W|^VBgDJlN7WEv$O$0QZ-=8 zr~q^iu6Bx%y}b@JQhC9!v;4XP)S<4wTA4I&ZbNP`5R0>9LU+!1>wmAtOQ8y^d%=l< zlbtooN?<}|KxQbpv|zqopBSX~kWe^RA35g`5Jw1BG#GV9Tpeq+P>Sla-Tc-!+Eq+2 z3c$eb3j(_@1T6v7z5!>SFCPj7oCVSt4nY>DCdS}STu^REVMZi1=xpg`u9J&@g^eF^B{giyVY zgGNbM5IO)J8x01GE^(%GZjk8c2QP6rtxWJ2o+D)F*#obT9F3A#Lgw+=Y~%0@9Wgu; zzA(b^U@n2w?fVpE@;=}wD(SD!%1{j;p^tfn2~h~bauVl2R$QosC9|}-V5WX5?-lC7 zT#jX0IX;6~uIpL*;a8*3Sl9f8R?bP8JZx|`ptZJejDHhFu;J3!`#2C=F7Zi(m;T79 zS}tg+N_hm^*?1|OF&|TuEs|xsxdWlhB}qg`&XE+$u6I8|GJdJdBBqKVp8mS1JR=*wx^X?HiD-zy;Xl{-Dy`TsU zaTG{7)m!c5+!_w#RgVRS7~-zj3o`3-Xh{~i42QZ`rTY<3&7cQ~oF%+%y z)+ABlk-&rTn%BKKI7@|=IOTf^7z`CU9o2%@ii zutOfapPY^)v^M`DTC30MU=Vp{KhX%gZ5-5tAW8x$EgKKt+}v59pUCVMpC_wut#gs@ z)O9b22K(5Nk5<@Mf(FH%NcDULLi(nkpd_`MU^jucQ&_qm2&1cEwzvaCH^6p6sLNQp z*XTk3rkRL%fo~BCa?Sz}F2L*80u%7I=y<;jsF-%784@4lIF`HtWIfIf zMzZ1O`c|clJKP66Tn1OltvcMfQAOCu3ZUa6ZFP34|EJhb449v4Hl|#sCs0%|P*9k8 zhn3{)_;#R(%c5cqgWCRH&ZoJERw)PZHWit)ReSaDwp+MOI7R%X!1{+(WwV2{<#{Uz z=Ue8xPwjK&=A}0%Wd2EsSEvx4jxbxG%|CWk)b5UG(fe(Q=kuP!D`B9lWPzMzZ*G2a zM5qU%fqSl1NrjlQ8W-N0oqcqEjb>K;kPut$IaeRb1?3Z#%KfXVQTHrhJP=wF@9~kQCa8>P_@|ge7gx1y{76d6 zF?-+eXo4YGBMDv?r_aCG`!jO^x>){GYy;PfuL@{JCec;N$3;El-JGCa@R#q#8k_p8 z^ij=?=a^k5Q578w%tMhX$54_n=IqtP!6#8ZMA#U^p@}PcyW>2hZkKnKcP27i@)ijGwUd_j$25f+LV*8T)q0tZ2cE2&h`R?v356!E>$fv+#v z0}53giCjv8Nh#7?!m&*CP|}#m74A0fOC>Ud+*ctuvwKd-Dd=wYqq4FUtPGHQt|x*c z)Bi6HU_00dyAQO8t~1vC3==c|QorcpIpgu0-&1l`XEcWAMmv!QOk^c}p7wo>zfyc* zQr$t!;A~Gs_s+l#|NC!-^`1N}xH1w{ADZ*oux0#PuhzqDskGe=x6O|Pnsnbbtoq6? z%DJi)b!Srt9es$ivj~#RX#Ae~J21|=P|vlHEDgDJs>Cz!SJ~k1GR2K&mx314-^P4< zo`ncCCy()dU)&>JIS`Qs^XRLV)^@%(I=fMk7h6dGbTD6r6ts~l6B>h@8nNBMRrZNG zWw`s?ZCUfzS;kZMbZ5OadJVmH(x`VMpC_EHeD9?{*j!v!cYb9hwWX%rzJ!o}PWD(T zDZMeZZbyf>n1+YU0-J+TMrt9pS!2d_@OsY)iOfx*@+Nxqh)Va0GQ9=D%|l92Pn#oh zZL$yF__+zMv;vh2#%xPsbjLSp@2mo=`<5i#JXg?b`2*=a=V6}zk^MFO0m-YPkrK~G zokrJlr5Lq#3Ca8L#o%NUsx(KK3^NS%0Dd#0j2R4Z-!aPqeH8|HzG@doarPL%0seV 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 z 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 Zp(p + + + + + +``` diff --git a/docs/dynamic-links/apple-integration.mdx b/docs/dynamic-links/apple-integration.mdx index 10c8fe67b4c8..8fb433a68e9c 100644 --- a/docs/dynamic-links/apple-integration.mdx +++ b/docs/dynamic-links/apple-integration.mdx @@ -13,36 +13,52 @@ To setup Dynamic Links on iOS, it is a prerequisite that you have an Apple devel Add an `App Store ID` & `Team ID` to your app in your Firebase console. If you do not have an `App Store ID` yet, you can put any number in here for now. Your `Team ID` can be found in your Apple developer console. -TODO - image +Apple Configuration -Test the domain (e.g. `https://your-dynamic-link-domain`) you have created in your Firebase console. Go to the following location in your browser ``[your domain]/apple-app-site-association`'. -The response will have a details array property containing an object that has the property `appID`'. That will be your app's app ID (It may take some time for +Test the domain (e.g. `https://your-dynamic-link-domain`) you have created in your Firebase console. Go to the following location in your browser `[your domain]/apple-app-site-association`. +The response will have a details array property containing an object that has the property `appID`. That will be your app's app ID (It may take some time for your domain to register). Please ensure it is registered before proceeding. -TODO - image - ## Apple Developer Console Create a provisioning profile for your app. Please ensure you've enabled the `Associated Domain` capability which you should check before proceeding. -TODO - image +Apple Provisioning Profile -## Project Opened on Xcode +## Signing & Capabilities -Open your app under the `TARGETS` header. Click the `Signing & Capabilities` tab. You will need to ensure your `Team` is registered, and your `Provisioning Profile` field is completed. +Open your app under the `TARGETS` header using XCode. Click the `Signing & Capabilities` tab. You will need to ensure your `Team` is registered, and your `Provisioning Profile` field is completed. Please add the domain you created in your Firebase console to the `Associated Domains` and prefix with `applinks:` -TODO - image +Signing & Capabilities Click the `Info` tab, and add a `URL Type` to your project. The `Identifier` can be called `Bundle Id` or whatever you wish. Add your bundle identifier to the `URL Schemes` property. +URL Schemes ## Dynamic Links With Custom Domains If you have set up a custom domain for your Firebase project, you must add the dynamic link URL prefix into your iOS project's `Info.plist` file by using the `FirebaseDynamicLinksCustomDomains` key. You can add multiple URLs as well. -TODO - image +```xml + + + + + FirebaseDynamicLinksCustomDomains + + https://custom.domain.io/path1 + https://custom.domain.io/path2 + + + ...other settings + + + +``` + +If you don't add this, the dynamic link will invoke your app, but you cannot retrieve any deep link data you may need within your app, as the deep link will be completely ignored. ## Test Dynamic Links diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index 7722cc7d3dbe..08398bb3638d 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -145,13 +145,11 @@ final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance. ## Realtime handling Whilst the application is open, you may listen to Dynamic Links using a stream handler. The [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) -getter returns a `Stream` containing a nullable `PendingDynamicLinkData`: +getter returns a `Stream` containing a `PendingDynamicLinkData`: ```dart FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) { - if (dynamicLinkData != null && dynamicLinkData.link != null) { - Navigator.pushNamed(context, dynamicLinkData.link.path); - } + Navigator.pushNamed(context, dynamicLinkData.link.path); }).onError((error) { // Handle errors }); From 6698c0df37c8091eb2eb86d5f79c1f236ed47fab Mon Sep 17 00:00:00 2001 From: Elliot Hesp Date: Thu, 2 Dec 2021 14:40:12 +0000 Subject: [PATCH 118/125] chore: update changelog --- .../firebase_dynamic_links/CHANGELOG.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index f66307b71d06..ef6489315ffe 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -1,21 +1,16 @@ ## UNRELEASED -As part of our on-going work for [#6769](https://github.com/FirebaseExtended/flutterfire/issues/6979) this is our Firebase Dynamic Links rework changes. - Overall, Firebase Dynamic Links has been heavily reworked to bring it inline with the federated plugin setup along with adding new features, documentation and updating unit and end-to-end tests. - **`FirebaseDynamicLinks`** - -- **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. -- **BREAKING**: `DynamicLinkParameters` class has been removed. `buildLink()` (replaces `buildUrl()`) & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance.*`. -- **BREAKING**: `DynamicLinkParameters.shortenUrl()` has been removed entirely. - -- **NEW**: `buildLink()` which replaces the previous `DynamicLinkParameters().buildUrl()` -- **NEW**: `buildShortLink()` which replaces the previous `DynamicLinkParameters().buildShortLink()` -- **NEW**: `DynamicLinkParameters` class is used to build parameters for `buildLink()` & `buildShortLink()`. - -- **NEW**: Multi-app support now available for `android` only; `FirebaseDynamicLinks.instanceFor(app: app)`. + - **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. + - **BREAKING**: `DynamicLinkParameters` class has been removed. `buildLink()` (replaces `buildUrl()`) & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance`. + - **BREAKING**: `DynamicLinkParameters.shortenUrl()` has been removed. + - **NEW**: `buildLink()` which replaces the previous `DynamicLinkParameters().buildUrl()`. + - **NEW**: `buildShortLink()` which replaces the previous `DynamicLinkParameters().buildShortLink()`. + - **NEW**: `DynamicLinkParameters` class is used to build parameters for `buildLink()` & `buildShortLink()`. + - **NEW**: Multi-app support now available for Android only using `FirebaseDynamicLinks.instanceFor()`. ## 3.0.1 From 6164afcfbeafc3efa745d7ac771bbc10e1c05a6f Mon Sep 17 00:00:00 2001 From: Salakar Date: Fri, 3 Dec 2021 19:10:42 +0000 Subject: [PATCH 119/125] - --- docs/dynamic-links/usage.mdx | 10 +++++----- .../lib/src/firebase_dynamic_links.dart | 2 +- .../test/firebase_dynamic_links_test.dart | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/dynamic-links/usage.mdx b/docs/dynamic-links/usage.mdx index 08398bb3638d..6fb3a04940ab 100644 --- a/docs/dynamic-links/usage.mdx +++ b/docs/dynamic-links/usage.mdx @@ -40,8 +40,8 @@ For example, the `my-awesome-app.page.link` has been added on this project: ## Create a Dynamic Link -A dynamic link can be created directly from the Firebase Console, or programatically via the `firebase_dynamic_links` plugin. Once a link has been created, -you can use send them to users (via emails, push notifications, in-app content etc). Upon opening, your application can handle the link however you like, for +A dynamic link can be created directly from the Firebase Console, or programmatically via the `firebase_dynamic_links` plugin. Once a link has been created, +you can use send them to users (via emails, push notifications, in-app content etc.). Upon opening, your application can handle the link however you like, for example opening a specific screen. ### Build Dynamic Link @@ -101,14 +101,14 @@ final Uri uri = await FirebaseDynamicLinks.instance.buildShortLink(parameters); ## Handling Dynamic Links -To handle an Dynamic Link in your application, two scenarios require implementing. +To handle a Dynamic Link in your application, two scenarios require implementing. ### Background or Terminated If the application is in the background or terminated, the [`FirebaseDynamicLinks.getInitialLink`](!firebase_dynamic_links.getInitialLink) method allows you to retrieve the Dynamic Link that opened the application or brought it to the foreground. -This is an asynchronous request, so it make sense to handle a link before rendering application logic, such as +This is an asynchronous request, so it makes sense to handle a link before rendering application logic, such as a navigator. For example, you could handle this in the `main` function: ```dart @@ -142,7 +142,7 @@ String link = 'https://dynamic-link-domain/ke2Qa'; final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(link)); ``` -## Realtime handling +## Listen for incoming links Whilst the application is open, you may listen to Dynamic Links using a stream handler. The [`FirebaseDynamicLinks.onLink`](!firebase_dynamic_links.onLink) getter returns a `Stream` containing a `PendingDynamicLinkData`: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 14276d899e4c..6e0fd485d845 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -68,7 +68,7 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { } /// Listen to a stream for the latest dynamic link events. - Stream get onLink { + Stream get onLink { return _delegate.onLink; } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 2a2119a42049..9a2160aec96d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -178,8 +178,8 @@ void main() { ), ); - final PendingDynamicLinkData? data = await dynamicLinks.onLink.first; - expect(data!.link.scheme, mockUri.scheme); + final PendingDynamicLinkData data = await dynamicLinks.onLink.first; + expect(data.link.scheme, mockUri.scheme); expect(data.android!.clickTimestamp, mockClickTimestamp); expect(data.android!.minimumVersion, mockMinimumVersionAndroid); From 10e184342950d6ee422e1bd4851c11cc9befb283 Mon Sep 17 00:00:00 2001 From: Salakar Date: Fri, 3 Dec 2021 20:17:46 +0000 Subject: [PATCH 120/125] - --- .../firebase_dynamic_links/example/lib/main.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index cf6c2dbe3ac1..051807f44b95 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -69,9 +69,7 @@ class _MainScreenState extends State<_MainScreen> { Future initDynamicLinks() async { dynamicLinks.onLink.listen((dynamicLinkData) { - if (dynamicLinkData != null) { - Navigator.pushNamed(context, dynamicLinkData.link.path); - } + Navigator.pushNamed(context, dynamicLinkData.link.path); }).onError((error) { print('onLink error'); print(error.message); From e31dace36ac5fa6439b22491cbcbc37508e97f2b Mon Sep 17 00:00:00 2001 From: Salakar Date: Fri, 3 Dec 2021 20:29:17 +0000 Subject: [PATCH 121/125] - --- website/dictionary.js | 1 + 1 file changed, 1 insertion(+) diff --git a/website/dictionary.js b/website/dictionary.js index 38b21335aba0..f092941e6172 100644 --- a/website/dictionary.js +++ b/website/dictionary.js @@ -94,4 +94,5 @@ module.exports = [ 'web.firebase_cdn', 'xml', 'yaml', + 'programmatically', ]; From fea98752f3ecd15e3a7dea2d0340278c8c68e260 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 4 Dec 2021 13:39:10 +0000 Subject: [PATCH 122/125] - --- .../firebase_dynamic_links/CHANGELOG.md | 2 +- .../firebase_dynamic_links/README.md | 2 +- .../FlutterFirebaseDynamicLinksPlugin.java | 32 +++++++------ .../example/lib/main.dart | 3 -- .../example/test_driver/instance_e2e.dart | 6 --- .../Classes/FLTFirebaseDynamicLinksPlugin.m | 35 ++++++--------- .../Classes/Private/FLTOnLinkStreamHandler.h | 24 ---------- .../lib/firebase_dynamic_links.dart | 3 +- .../lib/src/firebase_dynamic_links.dart | 7 +-- .../firebase_dynamic_links/pubspec.yaml | 2 +- .../test/firebase_dynamic_links_test.dart | 17 ++++--- .../CHANGELOG.md | 2 +- ...base_dynamic_links_platform_interface.dart | 3 +- .../lib/src/dynamic_link.dart | 20 --------- .../src/dynamic_link_parameter_options.dart | 22 --------- .../lib/src/dynamic_link_parameters.dart | 15 ++----- ...method_channel_firebase_dynamic_links.dart | 33 +++++++------- ...form_interface_firebase_dynamic_links.dart | 5 ++- .../lib/src/short_dynamic_link.dart | 6 +++ .../src/short_dynamic_link_path_length.dart | 6 --- .../lib/src/short_dynamic_link_type.dart | 16 +++++++ .../pubspec.yaml | 2 +- .../dynamic_link_parameter_options_test.dart | 45 ------------------- .../test/dynamic_link_parameters_test.dart | 12 ----- .../test/dynamic_link_test.dart | 36 --------------- ...d_channel_firebase_dynamic_links_test.dart | 14 +----- .../test/short_dynamic_link_test.dart | 2 + 27 files changed, 99 insertions(+), 273 deletions(-) delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart create mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_type.dart delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart delete mode 100644 packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md index ab5e77880ba6..5b5b40c9e292 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/CHANGELOG.md @@ -4,7 +4,7 @@ Overall, Firebase Dynamic Links has been heavily reworked to bring it inline wit documentation and updating unit and end-to-end tests. - **`FirebaseDynamicLinks`** - - **BREAKING**: `onLink()` method has been removed. Instead use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. + - **BREAKING**: `onLink()` method has been removed. Instead, use `onLink` getter, it returns a `Stream`; events & errors are now streamed to the user. - **BREAKING**: `DynamicLinkParameters` class has been removed. `buildLink()` (replaces `buildUrl()`) & `buildShortLink()` methods are now found on `FirebaseDynamicLinks.instance`. - **BREAKING**: `DynamicLinkParameters.shortenUrl()` has been removed. - **NEW**: `buildLink()` which replaces the previous `DynamicLinkParameters().buildUrl()`. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/README.md b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md index a08beb5e7ee6..87c26743522d 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/README.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/README.md @@ -19,7 +19,7 @@ To use this plugin, please visit the [Dynamic Links Usage documentation](https:/ Please file FlutterFire specific issues, bugs, or feature requests in our [issue tracker](https://github.com/FirebaseExtended/flutterfire/issues/new). -Plugin issues that are not specific to Flutterfire can be filed in the [Flutter issue tracker](https://github.com/flutter/flutter/issues/new). +Plugin issues that are not specific to FlutterFire can be filed in the [Flutter issue tracker](https://github.com/flutter/flutter/issues/new). To contribute a change to this plugin, please review our [contribution guide](https://github.com/FirebaseExtended/flutterfire/blob/master/CONTRIBUTING.md) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 4671a78ff6ec..4b4c2cc05d9e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -134,7 +134,7 @@ public void onMethodCall(MethodCall call, @NonNull final MethodChannel.Result re return; case "FirebaseDynamicLinks#buildShortLink": DynamicLink.Builder urlBuilder = setupParameters(call.arguments()); - methodCallTask = buildShortLink(urlBuilder, call.argument("dynamicLinkParametersOptions")); + methodCallTask = buildShortLink(urlBuilder, call.arguments()); break; case "FirebaseDynamicLinks#getDynamicLink": case "FirebaseDynamicLinks#getInitialLink": @@ -166,25 +166,23 @@ private String buildLink(Map arguments) { } private Task> buildShortLink( - DynamicLink.Builder urlBuilder, @Nullable Map dynamicLinkParametersOptions) { + DynamicLink.Builder urlBuilder, @Nullable Map arguments) { return Tasks.call( cachedThreadPool, () -> { - Integer suffix = null; - if (dynamicLinkParametersOptions != null) { - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortDynamicLinkPathLength"); - if (shortDynamicLinkPathLength != null) { - switch (shortDynamicLinkPathLength) { - case 0: - suffix = ShortDynamicLink.Suffix.UNGUESSABLE; - break; - case 1: - suffix = ShortDynamicLink.Suffix.SHORT; - break; - default: - break; - } + Integer suffix = 1; + Integer shortDynamicLinkPathLength = + (Integer) dynamicLinkParametersOptions.get("shortLinkType"); + if (shortDynamicLinkPathLength != null) { + switch (shortDynamicLinkPathLength) { + case 0: + suffix = ShortDynamicLink.Suffix.UNGUESSABLE; + break; + case 1: + suffix = ShortDynamicLink.Suffix.SHORT; + break; + default: + break; } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart index 051807f44b95..259a6c9989dd 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/lib/main.dart @@ -88,9 +88,6 @@ class _MainScreenState extends State<_MainScreen> { packageName: 'io.flutter.plugins.firebase.dynamiclinksexample', minimumVersion: 0, ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), iosParameters: const IOSParameters( bundleId: 'io.invertase.testing', minimumVersion: '0', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart index 744e2313a298..44a8a870700b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/example/test_driver/instance_e2e.dart @@ -40,9 +40,6 @@ void runInstanceTests() { packageName: androidPackageName, minimumVersion: 1, ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), iosParameters: const IOSParameters( bundleId: iosBundleId, minimumVersion: '2', @@ -101,9 +98,6 @@ void runInstanceTests() { packageName: androidPackageName, minimumVersion: 1, ), - dynamicLinkParametersOptions: const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ), iosParameters: const IOSParameters( bundleId: iosBundleId, minimumVersion: '2', diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 1c6b031e7c70..520c7c9ec470 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -301,24 +301,19 @@ - (void)onDeepLinkResult:(FIRDynamicLink *_Nullable)dynamicLink error:(NSError * } - (FIRDynamicLinkComponentsOptions *)setupOptions:(NSDictionary *)arguments { - FIRDynamicLinkComponentsOptions *options; - if (![arguments[kDynamicLinkParametersOptions] isEqual:[NSNull null]]) { - NSDictionary *params = arguments[kDynamicLinkParametersOptions]; - - options = [FIRDynamicLinkComponentsOptions options]; - - NSNumber *shortDynamicLinkPathLength = params[@"shortDynamicLinkPathLength"]; - if (![shortDynamicLinkPathLength isEqual:[NSNull null]]) { - switch (shortDynamicLinkPathLength.intValue) { - case 0: - options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; - break; - case 1: - options.pathLength = FIRShortDynamicLinkPathLengthShort; - break; - default: - break; - } + FIRDynamicLinkComponentsOptions *options = [FIRDynamicLinkComponentsOptions options]; + + NSNumber *shortDynamicLinkPathLength = arguments[@"shortLinkType"]; + if (![shortDynamicLinkPathLength isEqual:[NSNull null]]) { + switch (shortDynamicLinkPathLength.intValue) { + case 0: + options.pathLength = FIRShortDynamicLinkPathLengthUnguessable; + break; + case 1: + options.pathLength = FIRShortDynamicLinkPathLengthShort; + break; + default: + break; } } @@ -349,9 +344,7 @@ - (FIRDynamicLinkComponents *)setupParameters:(NSDictionary *)arguments { components.androidParameters = androidParams; } - if (![arguments[@"dynamicLinkComponentsOptions"] isEqual:[NSNull null]]) { - components.options = [self setupOptions:arguments]; - } + components.options = [self setupOptions:arguments]; if (![arguments[@"googleAnalyticsParameters"] isEqual:[NSNull null]]) { NSDictionary *params = arguments[@"googleAnalyticsParameters"]; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h deleted file mode 100644 index a4c5f3c7b513..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Private/FLTOnLinkStreamHandler.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -#if TARGET_OS_OSX -#import -#else -#import -#endif - -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLTOnLinkStreamHandler : NSObject -- (instancetype)init; -- (void)sinkEvent:(id)dynamicLinkData; -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index 37443f463bf0..aa34be3fe913 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -12,7 +12,6 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links show AndroidParameters, DynamicLinkParameters, - DynamicLinkParametersOptions, FirebaseDynamicLinksPlatform, GoogleAnalyticsParameters, IOSParameters, @@ -22,7 +21,7 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links PendingDynamicLinkDataAndroid, PendingDynamicLinkDataIOS, ShortDynamicLink, - ShortDynamicLinkPathLength, + ShortDynamicLinkType, SocialMetaTagParameters; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; import 'dart:io' show Platform; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index 6e0fd485d845..a1532a28c871 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -79,8 +79,9 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { /// Creates a shortened Dynamic Link from the parameters. Future buildShortLink( - DynamicLinkParameters parameters, - ) async { - return _delegate.buildShortLink(parameters); + DynamicLinkParameters parameters, { + ShortDynamicLinkType shortLinkType = ShortDynamicLinkType.short, + }) async { + return _delegate.buildShortLink(parameters, shortLinkType: shortLinkType); } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml index 122b2250e63e..96f7109a6d97 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/pubspec.yaml @@ -13,7 +13,7 @@ environment: dependencies: firebase_core: ^1.10.0 firebase_core_platform_interface: ^4.0.1 - firebase_dynamic_links_platform_interface: ^0.0.1 + firebase_dynamic_links_platform_interface: ^0.1.0 flutter: sdk: flutter meta: ^1.3.0 diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart index 9a2160aec96d..4c05fb0a33e3 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/test/firebase_dynamic_links_test.dart @@ -47,11 +47,6 @@ DynamicLinkParameters buildDynamicLinkParameters() { providerToken: 'providerToken', ); - DynamicLinkParametersOptions parametersOptions = - const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, - ); - Uri link = Uri.parse('link'); NavigationInfoParameters navigation = const NavigationInfoParameters(forcedRedirectEnabled: true); @@ -67,7 +62,6 @@ DynamicLinkParameters buildDynamicLinkParameters() { uriPrefix: uriPrefix, link: link, androidParameters: android, - dynamicLinkParametersOptions: parametersOptions, googleAnalyticsParameters: google, iosParameters: ios, itunesConnectAnalyticsParameters: itunes, @@ -231,6 +225,7 @@ void main() { DynamicLinkParameters params = DynamicLinkParameters(uriPrefix: 'uriPrefix', link: mockUri); final shortLink = ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: mockUri, warnings: warnings, previewLink: previewLink, @@ -238,6 +233,7 @@ void main() { when(dynamicLinks.buildShortLink(params)).thenAnswer( (_) async => ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: mockUri, warnings: warnings, previewLink: previewLink, @@ -260,6 +256,7 @@ void main() { List warnings = ['warning']; DynamicLinkParameters params = buildDynamicLinkParameters(); final shortLink = ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: mockUri, warnings: warnings, previewLink: previewLink, @@ -267,6 +264,7 @@ void main() { when(dynamicLinks.buildShortLink(params)).thenAnswer( (_) async => ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: mockUri, warnings: warnings, previewLink: previewLink, @@ -354,11 +352,15 @@ class MockFirebaseDynamicLinks extends Mock } @override - Future buildShortLink(DynamicLinkParameters parameters) { + Future buildShortLink( + DynamicLinkParameters parameters, { + ShortDynamicLinkType shortLinkType = ShortDynamicLinkType.short, + }) { return super.noSuchMethod( Invocation.method(#buildShortLink, [parameters]), returnValue: Future.value( ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: uri, warnings: ['warning'], previewLink: Uri.parse('preview'), @@ -366,6 +368,7 @@ class MockFirebaseDynamicLinks extends Mock ), returnValueForMissingStub: Future.value( ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: uri, warnings: ['warning'], previewLink: Uri.parse('preview'), diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md index a0f083857730..08378c690145 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/CHANGELOG.md @@ -1,3 +1,3 @@ -# 0.0.1 +# 0.1.0 - Initial release. diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart index 87e9909bb2ff..20afa43504cb 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/firebase_dynamic_links_platform_interface.dart @@ -9,8 +9,7 @@ export 'src/pending_dynamic_link_data.dart'; export 'src/pending_dynamic_link_data_android.dart'; export 'src/pending_dynamic_link_data_ios.dart'; export 'src/short_dynamic_link.dart'; -export 'src/short_dynamic_link_path_length.dart'; -export 'src/dynamic_link_parameter_options.dart'; +export 'src/short_dynamic_link_type.dart'; export 'src/google_analytics_parameters.dart'; export 'src/ios_parameters.dart'; export 'src/itunes_connect_analytics_parameters.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart deleted file mode 100644 index ca0e93293725..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/// Response from creating a dynamic link with [DynamicLinkBuilder]. -class DynamicLink { - const DynamicLink({required this.url}); - - /// url value. - final Uri url; - - Map asMap() => { - 'url': url.toString(), - }; - - @override - String toString() { - return '$DynamicLink($asMap)'; - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart deleted file mode 100644 index 7d91428e8ed0..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameter_options.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'short_dynamic_link_path_length.dart'; - -/// Options class for defining how Dynamic Link URLs are generated. -class DynamicLinkParametersOptions { - const DynamicLinkParametersOptions({this.shortDynamicLinkPathLength}); - - /// Specifies the length of the path component of a short Dynamic Link. - final ShortDynamicLinkPathLength? shortDynamicLinkPathLength; - - Map asMap() => { - 'shortDynamicLinkPathLength': shortDynamicLinkPathLength?.index, - }; - - @override - String toString() { - return '$DynamicLinkParametersOptions($asMap)'; - } -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart index 44430bf57067..426ffd74ed1b 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/dynamic_link_parameters.dart @@ -2,22 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/foundation.dart'; - import '../firebase_dynamic_links_platform_interface.dart'; /// Interface that defines the all the parameters required to build a dynamic link class DynamicLinkParameters { // ignore: public_member_api_docs - @protected DynamicLinkParameters({ - this.androidParameters, + required this.link, required this.uriPrefix, - this.dynamicLinkParametersOptions, - this.googleAnalyticsParameters, + this.androidParameters, this.iosParameters, + this.googleAnalyticsParameters, this.itunesConnectAnalyticsParameters, - required this.link, this.navigationInfoParameters, this.socialMetaTagParameters, }); @@ -32,9 +28,6 @@ class DynamicLinkParameters { // The domain URI prefix must start with a valid HTTPS scheme (https://). final String uriPrefix; - /// Defines behavior for generating Dynamic Link URLs. - final DynamicLinkParametersOptions? dynamicLinkParametersOptions; - /// Analytics parameters for a generated Dynamic Link URL. final GoogleAnalyticsParameters? googleAnalyticsParameters; @@ -66,8 +59,6 @@ class DynamicLinkParameters { 'link': link.toString(), if (androidParameters != null) 'androidParameters': androidParameters?.asMap(), - if (dynamicLinkParametersOptions != null) - 'dynamicLinkParametersOptions': dynamicLinkParametersOptions?.asMap(), if (googleAnalyticsParameters != null) 'googleAnalyticsParameters': googleAnalyticsParameters?.asMap(), if (iosParameters != null) 'iosParameters': iosParameters?.asMap(), diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart index c1c7f543b3ae..240e2fdb77f6 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/method_channel/method_channel_firebase_dynamic_links.dart @@ -155,30 +155,33 @@ class MethodChannelFirebaseDynamicLinks extends FirebaseDynamicLinksPlatform { @override Future buildShortLink( - DynamicLinkParameters parameters, - ) async { + DynamicLinkParameters parameters, { + ShortDynamicLinkType shortLinkType = ShortDynamicLinkType.short, + }) async { try { final Map? response = await MethodChannelFirebaseDynamicLinks.channel .invokeMapMethod( 'FirebaseDynamicLinks#buildShortLink', - _withChannelDefaults(parameters.asMap()), + _withChannelDefaults( + { + 'shortLinkType': shortLinkType.index, + ...parameters.asMap(), + }, + ), ); - return _parseShortLink(response!); + final List? warnings = response!['warnings']; + return ShortDynamicLink( + type: shortLinkType, + shortUrl: Uri.parse(response['url']), + warnings: warnings?.cast(), + previewLink: response['previewLink'] != null + ? Uri.parse(response['previewLink']) + : null, + ); } catch (e, s) { throw convertPlatformException(e, s); } } - - ShortDynamicLink _parseShortLink(Map response) { - final List? warnings = response['warnings']; - return ShortDynamicLink( - shortUrl: Uri.parse(response['url']), - warnings: warnings?.cast(), - previewLink: response['previewLink'] != null - ? Uri.parse(response['previewLink']) - : null, - ); - } } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart index 38a4447105a7..8d25d55034f8 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/platform_interface/platform_interface_firebase_dynamic_links.dart @@ -86,8 +86,9 @@ abstract class FirebaseDynamicLinksPlatform extends PlatformInterface { /// Generate a short Dynamic Link URL. Future buildShortLink( - DynamicLinkParameters parameters, - ) async { + DynamicLinkParameters parameters, { + ShortDynamicLinkType shortLinkType = ShortDynamicLinkType.short, + }) async { throw UnimplementedError('buildShortLink() is not implemented'); } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart index 350a2dd44682..a988846f3839 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link.dart @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'short_dynamic_link_type.dart'; + /// Response from creating a short dynamic link with [DynamicLinkBuilder]. class ShortDynamicLink { const ShortDynamicLink({ + required this.type, required this.shortUrl, this.warnings, this.previewLink, @@ -13,6 +16,9 @@ class ShortDynamicLink { /// Short url value. final Uri shortUrl; + /// The type of this short link, e.g. [ShortDynamicLinkType.unguessable]. + final ShortDynamicLinkType type; + /// Gets the preview link to show the link flow chart. Android only. final Uri? previewLink; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart deleted file mode 100644 index 5629090caac4..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_path_length.dart +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/// For specifying length for short Dynamic Links. -enum ShortDynamicLinkPathLength { unguessable, short } diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_type.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_type.dart new file mode 100644 index 000000000000..c758803c2732 --- /dev/null +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/lib/src/short_dynamic_link_type.dart @@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Enum used to define the desired path length for shortened Dynamic Link URLs. +enum ShortDynamicLinkType { + /// Shorten the path to an unguessable string. Such strings are created by base62-encoding randomly + /// generated 96-bit numbers, and consist of 17 alphanumeric characters. Use unguessable strings + /// to prevent your Dynamic DynamicLinks from being crawled, which can potentially expose sensitive information. + unguessable, + + /// Shorten the path to a string that is only as long as needed to be unique, with a minimum length + /// of 4 characters. Use this if sensitive information would not be exposed if a short + /// Dynamic Link URL were guessed. + short, +} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml index 9e4e7a8cdc31..63753bad63a5 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/pubspec.yaml @@ -1,6 +1,6 @@ name: firebase_dynamic_links_platform_interface description: A common platform interface for the firebase_dynamic_links plugin. -version: 0.0.1 +version: 0.1.0 homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface repository: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart deleted file mode 100644 index bb2a8fdcec48..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameter_options_test.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2021, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links_platform_interface.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('$DynamicLinkParametersOptions', () { - DynamicLinkParametersOptions dynamicLinkOptions = - const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short, - ); - group('Constructor', () { - test('returns an instance of [DynamicLinkParametersOptions]', () { - expect(dynamicLinkOptions, isA()); - expect( - dynamicLinkOptions.shortDynamicLinkPathLength, - ShortDynamicLinkPathLength.short, - ); - }); - - group('asMap', () { - test('returns the current instance as a [Map]', () { - final result = dynamicLinkOptions.asMap(); - - expect(result, isA>()); - expect( - result['shortDynamicLinkPathLength'], - ShortDynamicLinkPathLength.short.index, - ); - }); - }); - - test('toString', () { - expect( - dynamicLinkOptions.toString(), - equals( - '$DynamicLinkParametersOptions(${dynamicLinkOptions.asMap})', - ), - ); - }); - }); - }); -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart index b8b04a167c20..f0a02ff84217 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_parameters_test.dart @@ -37,11 +37,6 @@ void main() { providerToken: 'providerToken', ); - DynamicLinkParametersOptions parametersOptions = - const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable, - ); - Uri link = Uri.parse('link'); NavigationInfoParameters navigation = const NavigationInfoParameters(forcedRedirectEnabled: true); @@ -58,7 +53,6 @@ void main() { uriPrefix: uriPrefix, link: link, androidParameters: androidParams, - dynamicLinkParametersOptions: parametersOptions, googleAnalyticsParameters: googleParams, iosParameters: iosParams, itunesConnectAnalyticsParameters: itunesParams, @@ -99,12 +93,6 @@ void main() { dynamicLinkParams.androidParameters?.packageName, ); expect(result['uriPrefix'], dynamicLinkParams.uriPrefix); - expect( - result['dynamicLinkParametersOptions'] - ['shortDynamicLinkPathLength'], - dynamicLinkParams.dynamicLinkParametersOptions - ?.shortDynamicLinkPathLength?.index, - ); expect( result['googleAnalyticsParameters']['campaign'], dynamicLinkParams.googleAnalyticsParameters?.campaign, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart deleted file mode 100644 index 8ed57f3d04d5..000000000000 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/dynamic_link_test.dart +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2021, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:firebase_dynamic_links_platform_interface/src/dynamic_link.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - Uri link = Uri.parse('dynamicLink'); - - group('$DynamicLink', () { - DynamicLink dynamicLink = DynamicLink(url: link); - group('Constructor', () { - test('returns an instance of [DynamicLink]', () { - expect(dynamicLink, isA()); - expect(dynamicLink.url, link); - }); - - group('asMap', () { - test('returns the current instance as a [Map]', () { - final result = dynamicLink.asMap(); - - expect(result, isA>()); - expect(result['url'], link.toString()); - }); - }); - - test('toString', () { - expect( - dynamicLink.toString(), - equals('$DynamicLink(${dynamicLink.asMap})'), - ); - }); - }); - }); -} diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart index f72f5462aada..eca1d7cf5d90 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/method_channel_tests/method_channel_firebase_dynamic_links_test.dart @@ -43,10 +43,6 @@ DynamicLinkParameters buildDynamicLinkParameters() { providerToken: 'providerToken', ); - DynamicLinkParametersOptions parametersOptions = - const DynamicLinkParametersOptions( - shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable); - Uri link = Uri.parse('link'); NavigationInfoParameters navigation = const NavigationInfoParameters(forcedRedirectEnabled: true); @@ -61,7 +57,6 @@ DynamicLinkParameters buildDynamicLinkParameters() { uriPrefix: uriPrefix, link: link, androidParameters: android, - dynamicLinkParametersOptions: parametersOptions, googleAnalyticsParameters: google, iosParameters: ios, itunesConnectAnalyticsParameters: itunes, @@ -245,10 +240,6 @@ void main() { 'appName': '[DEFAULT]', 'uriPrefix': 'https://', 'link': 'link', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, 'androidParameters': { 'fallbackUrl': 'fallbackUrl', 'minimumVersion': 1, @@ -337,12 +328,9 @@ void main() { 'FirebaseDynamicLinks#buildShortLink', arguments: { 'appName': '[DEFAULT]', + 'shortLinkType': ShortDynamicLinkType.short.index, 'uriPrefix': 'https://', 'link': 'link', - 'dynamicLinkParametersOptions': { - 'shortDynamicLinkPathLength': - ShortDynamicLinkPathLength.unguessable.index, - }, 'androidParameters': { 'fallbackUrl': 'fallbackUrl', 'minimumVersion': 1, diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart index 5d5e933e8634..18758a376f3e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links_platform_interface/test/short_dynamic_link_test.dart @@ -12,6 +12,7 @@ void main() { group('$ShortDynamicLink', () { ShortDynamicLink shortLink = ShortDynamicLink( + type: ShortDynamicLinkType.short, shortUrl: link, previewLink: previewLink, warnings: warnings, @@ -21,6 +22,7 @@ void main() { test('returns an instance of [ShortDynamicLink]', () { expect(shortLink, isA()); expect(shortLink.shortUrl, link); + expect(shortLink.type, ShortDynamicLinkType.short); expect(shortLink.previewLink, previewLink); expect(shortLink.warnings, warnings); }); From 4d7df54148eaa39de0373c5bcedbe2c3994b7eea Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 4 Dec 2021 13:56:59 +0000 Subject: [PATCH 123/125] - --- .../dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java | 3 +-- .../ios/Classes/{Public => }/FLTFirebaseDynamicLinksPlugin.h | 2 +- .../ios/Classes/FLTFirebaseDynamicLinksPlugin.m | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) rename packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/{Public => }/FLTFirebaseDynamicLinksPlugin.h (95%) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java index 4b4c2cc05d9e..ecd806601122 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/android/src/main/java/io/flutter/plugins/firebase/dynamiclinks/FlutterFirebaseDynamicLinksPlugin.java @@ -171,8 +171,7 @@ private Task> buildShortLink( cachedThreadPool, () -> { Integer suffix = 1; - Integer shortDynamicLinkPathLength = - (Integer) dynamicLinkParametersOptions.get("shortLinkType"); + Integer shortDynamicLinkPathLength = (Integer) arguments.get("shortLinkType"); if (shortDynamicLinkPathLength != null) { switch (shortDynamicLinkPathLength) { case 0: diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h similarity index 95% rename from packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h rename to packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h index 416f974f7c44..749b1fc6004a 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/Public/FLTFirebaseDynamicLinksPlugin.h +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.h @@ -1,7 +1,7 @@ // Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - +#import #import #import diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m index 520c7c9ec470..4b996a441533 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/ios/Classes/FLTFirebaseDynamicLinksPlugin.m @@ -5,7 +5,7 @@ #import #import -#import "Public/FLTFirebaseDynamicLinksPlugin.h" +#import "FLTFirebaseDynamicLinksPlugin.h" NSString *const kFLTFirebaseDynamicLinksChannelName = @"plugins.flutter.io/firebase_dynamic_links"; NSString *const kDLAppName = @"appName"; From cfaa418296c9c4cd4c8fb4b54bb9fe04021583c4 Mon Sep 17 00:00:00 2001 From: Salakar Date: Sat, 4 Dec 2021 14:21:04 +0000 Subject: [PATCH 124/125] - --- .../lib/firebase_dynamic_links.dart | 3 +-- .../lib/src/firebase_dynamic_links.dart | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart index aa34be3fe913..0506df45faaf 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/firebase_dynamic_links.dart @@ -24,7 +24,6 @@ export 'package:firebase_dynamic_links_platform_interface/firebase_dynamic_links ShortDynamicLinkType, SocialMetaTagParameters; import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart'; -import 'dart:io' show Platform; -import 'package:flutter/services.dart'; +import 'package:flutter/foundation.dart'; part 'src/firebase_dynamic_links.dart'; diff --git a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart index a1532a28c871..034fea588e0e 100644 --- a/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart +++ b/packages/firebase_dynamic_links/firebase_dynamic_links/lib/src/firebase_dynamic_links.dart @@ -23,15 +23,15 @@ class FirebaseDynamicLinks extends FirebasePluginPlatform { /// Returns an instance using a specified [FirebaseApp]. /// Note; multi-app support is only supported on android. static FirebaseDynamicLinks instanceFor({required FirebaseApp app}) { - if (Platform.isAndroid || app.name == defaultFirebaseAppName) { + if (defaultTargetPlatform == TargetPlatform.android || + app.name == defaultFirebaseAppName) { return _cachedInstances.putIfAbsent(app.name, () { return FirebaseDynamicLinks._(app: app); }); } - throw PlatformException( - code: 'default-app', - message: 'Firebase Dynamic Links has multi-app support for android only.', + throw UnsupportedError( + 'FirebaseDynamicLinks.instanceFor() only supports non-default FirebaseApp instances on Android.', ); } From 29d1f135f9bc3fcb046cd07871d1ac7c85f1d723 Mon Sep 17 00:00:00 2001 From: Mike Diarmid Date: Sat, 4 Dec 2021 14:31:50 +0000 Subject: [PATCH 125/125] Restore exception.dart --- .../lib/src/method_channel/utils/exception.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart index 423258642cd8..235d91e8cb8b 100644 --- a/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart +++ b/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/method_channel/utils/exception.dart @@ -23,8 +23,7 @@ Exception convertPlatformException(Object exception) { /// `details` of the exception exist. Firebase returns specific codes and messages /// which can be converted into user friendly exceptions. FirebaseException platformExceptionToFirebaseException( - PlatformException platformException, -) { + PlatformException platformException) { Map? details = platformException.details != null ? Map.from(platformException.details) : null;