From 51c5733cd7c460951083494ec8c58ee4076dc9a3 Mon Sep 17 00:00:00 2001 From: Till Hellmund Date: Wed, 12 Feb 2025 16:23:29 -0500 Subject: [PATCH] Enable bank payments in native Link (#10070) * Enable bank payments in native Link GIT_VALID_PII_OVERRIDE * Add end-to-end tests of bank payments in Link * Update API * Update legal terms * Update screenshots * Update detekt baseline * Fix Link card brand edge case and address review feedback - If Link card brand and ACH enabled, then use `bank_account` - Rename `shareLinkCardBrand` to `sharePaymentDetails` - Inject `Application` instead of `Context` * Address code review feedback Add `LinkCardBrandConfirmationModule`. * Hide add payment method button if cards can't be used * Update tests and add snapshot --- ...entsFraudDetectionDataRepositoryFactory.kt | 3 +- .../java/com/stripe/android/lpm/TestLink.kt | 30 +++++ .../android/test/core/PlaygroundTestDriver.kt | 45 +++++++ paymentsheet/api/paymentsheet.api | 16 +++ paymentsheet/detekt-baseline.xml | 3 +- .../stripe/android/link/LinkConfiguration.kt | 2 + .../link/account/DefaultLinkAccountManager.kt | 16 +++ .../link/account/LinkAccountManager.kt | 6 + .../DefaultLinkConfirmationHandler.kt | 34 ++++- .../link/injection/NativeLinkComponent.kt | 2 + .../link/injection/NativeLinkModule.kt | 14 +++ .../link/model/SupportedPaymentMethodTypes.kt | 13 +- .../link/repositories/LinkApiRepository.kt | 31 +++++ .../link/repositories/LinkRepository.kt | 7 ++ .../android/link/ui/wallet/WalletScreen.kt | 17 ++- .../android/link/ui/wallet/WalletUiState.kt | 1 + .../android/link/ui/wallet/WalletViewModel.kt | 13 +- .../LinkCardBrandConfirmationDefinition.kt | 116 ++++++++++++++++++ .../link/LinkCardBrandConfirmationModule.kt | 16 +++ .../link/LinkCardBrandConfirmationOption.kt | 10 ++ .../state/PaymentElementLoader.kt | 3 +- .../com/stripe/android/link/TestFactory.kt | 10 +- .../link/account/FakeLinkAccountManager.kt | 9 ++ .../android/link/model/StripeIntentKtxTest.kt | 2 +- .../link/repositories/FakeLinkRepository.kt | 7 ++ .../repositories/LinkApiRepositoryTest.kt | 3 + .../ui/wallet/WalletScreenScreenshotTest.kt | 16 ++- .../link/ui/wallet/WalletScreenTest.kt | 3 +- .../link/ui/wallet/WalletUiStateTest.kt | 6 +- .../link/ui/wallet/WalletViewModelTest.kt | 3 +- .../PaymentMethodMetadataTest.kt | 3 +- .../paymentmethod/link/LinkFormElementTest.kt | 2 + .../ConfirmationHandlerOptionKtxTest.kt | 3 +- ...kInlineSignupConfirmationDefinitionTest.kt | 4 +- .../paymentsheet/PaymentSheetViewModelTest.kt | 4 +- .../state/DefaultPaymentElementLoaderTest.kt | 3 +- .../paymentsheet/utils/LinkTestUtils.kt | 4 +- ...hotTest_testBankAccountSelectedState[].png | Bin 34062 -> 34089 bytes ...reenshotTest_testCannotAddCreditCard[].png | Bin 0 -> 23241 bytes 39 files changed, 439 insertions(+), 41 deletions(-) create mode 100644 paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition.kt create mode 100644 paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationModule.kt create mode 100644 paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption.kt create mode 100644 paymentsheet/src/test/snapshots/images/com.stripe.android.link.ui.wallet_WalletScreenScreenshotTest_testCannotAddCreditCard[].png diff --git a/payments-core/src/main/java/com/stripe/android/PaymentsFraudDetectionDataRepositoryFactory.kt b/payments-core/src/main/java/com/stripe/android/PaymentsFraudDetectionDataRepositoryFactory.kt index 7fd7788ee95..e9ca5929d0c 100644 --- a/payments-core/src/main/java/com/stripe/android/PaymentsFraudDetectionDataRepositoryFactory.kt +++ b/payments-core/src/main/java/com/stripe/android/PaymentsFraudDetectionDataRepositoryFactory.kt @@ -12,8 +12,9 @@ import com.stripe.android.payments.core.analytics.ErrorReporter import kotlinx.coroutines.Dispatchers import kotlin.coroutines.CoroutineContext +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @JvmOverloads -internal fun DefaultFraudDetectionDataRepository( +fun DefaultFraudDetectionDataRepository( context: Context, workContext: CoroutineContext = Dispatchers.IO, ): DefaultFraudDetectionDataRepository { diff --git a/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestLink.kt b/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestLink.kt index a4c5c87160d..30571ea4e87 100644 --- a/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestLink.kt +++ b/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestLink.kt @@ -2,7 +2,14 @@ package com.stripe.android.lpm import androidx.test.ext.junit.runners.AndroidJUnit4 import com.stripe.android.BasePlaygroundTest +import com.stripe.android.paymentsheet.example.playground.settings.Country +import com.stripe.android.paymentsheet.example.playground.settings.CountrySettingsDefinition +import com.stripe.android.paymentsheet.example.playground.settings.DefaultBillingAddress +import com.stripe.android.paymentsheet.example.playground.settings.DefaultBillingAddressSettingsDefinition import com.stripe.android.paymentsheet.example.playground.settings.LinkSettingsDefinition +import com.stripe.android.paymentsheet.example.playground.settings.LinkType +import com.stripe.android.paymentsheet.example.playground.settings.LinkTypeSettingsDefinition +import com.stripe.android.paymentsheet.example.playground.settings.SupportedPaymentMethodsSettingsDefinition import com.stripe.android.test.core.TestParameters import org.junit.Ignore import org.junit.Test @@ -21,4 +28,27 @@ internal class TestLink : BasePlaygroundTest() { fun testLinkInlineCustom() { testDriver.testLinkCustom(linkNewUser) } + + @Test + fun testLinkPaymentWithBankAccountInPaymentMethodMode() { + val testParameters = makeLinkTestParameters(passthroughMode = false) + testDriver.confirmWithBankAccountInLink(testParameters) + } + + @Test + fun testLinkPaymentWithBankAccountInPassthroughMode() { + val testParameters = makeLinkTestParameters(passthroughMode = true) + testDriver.confirmWithBankAccountInLink(testParameters) + } + + private fun makeLinkTestParameters(passthroughMode: Boolean): TestParameters { + return TestParameters.create( + paymentMethodCode = "card", + ) { settings -> + settings[SupportedPaymentMethodsSettingsDefinition] = if (passthroughMode) "card" else "card,link" + settings[CountrySettingsDefinition] = Country.US + settings[LinkTypeSettingsDefinition] = LinkType.Native + settings[DefaultBillingAddressSettingsDefinition] = DefaultBillingAddress.On + } + } } diff --git a/paymentsheet-example/src/androidTest/java/com/stripe/android/test/core/PlaygroundTestDriver.kt b/paymentsheet-example/src/androidTest/java/com/stripe/android/test/core/PlaygroundTestDriver.kt index e955cb29081..bb75b02e8ec 100644 --- a/paymentsheet-example/src/androidTest/java/com/stripe/android/test/core/PlaygroundTestDriver.kt +++ b/paymentsheet-example/src/androidTest/java/com/stripe/android/test/core/PlaygroundTestDriver.kt @@ -784,6 +784,51 @@ internal class PlaygroundTestDriver( ) } + @OptIn(ExperimentalTestApi::class) + fun confirmWithBankAccountInLink( + testParameters: TestParameters, + ) { + setup(testParameters) + + launchComplete() + + Espresso.onIdle() + composeTestRule.waitForIdle() + + // Expect the OTP dialog + composeTestRule.waitUntilExactlyOneExists(hasTestTag("OTP-0")) + + composeTestRule + .onNodeWithTag("OTP-0") + .performTextInput("000000") + + composeTestRule.waitUntilExactlyOneExists(hasTestTag("collapsed_wallet_row_tag")) + + composeTestRule + .onNodeWithTag("collapsed_wallet_row_tag") + .performClick() + + composeTestRule + .onNodeWithText("Test Institution") + .performClick() + + composeTestRule + .onNodeWithTag("wallet_screen_pay_button") + .performClick() + + composeTestRule.waitForIdle() + + // Skips the full screen payment animation in `PaymentSheet` + while (currentActivity !is PaymentSheetPlaygroundActivity) { + composeTestRule.mainClock.advanceTimeByFrame() + } + + Espresso.onIdle() + composeTestRule.waitForIdle() + + teardown() + } + fun confirmLinkBankPayment( testParameters: TestParameters, afterAuthorization: (Selectors, FieldPopulator) -> Unit = { _, _ -> }, diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index 44b6dc619bc..1f4bb954ade 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -685,6 +685,22 @@ public final class com/stripe/android/paymentelement/confirmation/gpay/GooglePay public synthetic fun newArray (I)[Ljava/lang/Object; } +public final class com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition$Result$Creator : android/os/Parcelable$Creator { + public fun ()V + public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition$Result; + public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object; + public final fun newArray (I)[Lcom/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition$Result; + public synthetic fun newArray (I)[Ljava/lang/Object; +} + +public final class com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption$Creator : android/os/Parcelable$Creator { + public fun ()V + public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption; + public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object; + public final fun newArray (I)[Lcom/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption; + public synthetic fun newArray (I)[Ljava/lang/Object; +} + public final class com/stripe/android/paymentelement/confirmation/link/LinkConfirmationOption$Creator : android/os/Parcelable$Creator { public fun ()V public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/paymentelement/confirmation/link/LinkConfirmationOption; diff --git a/paymentsheet/detekt-baseline.xml b/paymentsheet/detekt-baseline.xml index a870e1bb2f6..a23a61fcb87 100644 --- a/paymentsheet/detekt-baseline.xml +++ b/paymentsheet/detekt-baseline.xml @@ -41,7 +41,6 @@ LongMethod:USBankAccountForm.kt$@Composable private fun AccountDetailsForm( modifier: Modifier = Modifier, showCheckbox: Boolean, isProcessing: Boolean, bankName: String?, last4: String?, promoBadgeState: PromoBadgeState?, saveForFutureUseElement: SaveForFutureUseElement, onRemoveAccount: () -> Unit, ) LongMethod:USBankAccountForm.kt$@Composable private fun BillingDetailsForm( instantDebits: Boolean, formArgs: FormArguments, isProcessing: Boolean, isPaymentFlow: Boolean, nameController: TextFieldController, emailController: TextFieldController, phoneController: PhoneNumberController, addressController: AddressController, lastTextFieldIdentifier: IdentifierSpec?, sameAsShippingElement: SameAsShippingElement?, ) LongMethod:USBankAccountFormViewModel.kt$USBankAccountFormViewModel$private fun createNewPaymentSelection( resultIdentifier: ResultIdentifier, last4: String?, bankName: String?, billingDetails: PaymentMethod.BillingDetails, ): PaymentSelection.New.USBankAccount - MagicNumber:BaseSheetActivity.kt$BaseSheetActivity$30 MagicNumber:NewPaymentMethodTabLayoutUI.kt$.3f MagicNumber:NewPaymentMethodTabLayoutUI.kt$.4f MagicNumber:NewPaymentMethodTabLayoutUI.kt$.5f @@ -71,6 +70,8 @@ MaxLineLength:SupportedPaymentMethod.kt$SupportedPaymentMethod$/** This describes the image in the LPM selector. These can be found internally [here](https://www.figma.com/file/2b9r3CJbyeVAmKi1VHV2h9/Mobile-Payment-Element?node-id=1128%3A0) */ MaxLineLength:USBankAccountFormViewModelTest.kt$USBankAccountFormViewModelTest$fun MaximumLineLength:CardDefinition.kt$internal + SwallowedException:LinkCardBrandConfirmationDefinition.kt$e: Exception + TooGenericExceptionCaught:LinkCardBrandConfirmationDefinition.kt$e: Exception TooManyFunctions:CustomerSheetEventReporter.kt$CustomerSheetEventReporter TooManyFunctions:DefaultCustomerSheetEventReporter.kt$DefaultCustomerSheetEventReporter : CustomerSheetEventReporter TooManyFunctions:DefaultEventReporter.kt$DefaultEventReporter : EventReporter diff --git a/paymentsheet/src/main/java/com/stripe/android/link/LinkConfiguration.kt b/paymentsheet/src/main/java/com/stripe/android/link/LinkConfiguration.kt index 2553a137b52..beea6a30715 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/LinkConfiguration.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/LinkConfiguration.kt @@ -1,6 +1,7 @@ package com.stripe.android.link import android.os.Parcelable +import com.stripe.android.model.LinkMode import com.stripe.android.model.StripeIntent import com.stripe.android.paymentsheet.addresselement.AddressDetails import com.stripe.android.paymentsheet.state.PaymentElementLoader @@ -20,6 +21,7 @@ internal data class LinkConfiguration( val suppress2faModal: Boolean, val initializationMode: PaymentElementLoader.InitializationMode, val elementsSessionId: String, + val linkMode: LinkMode?, ) : Parcelable { @Parcelize data class CustomerInfo( diff --git a/paymentsheet/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt b/paymentsheet/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt index a782952018f..9934e378e92 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt @@ -19,6 +19,7 @@ import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.ConsumerSignUpConsentAction import com.stripe.android.model.EmailSource import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import com.stripe.android.payments.core.analytics.ErrorReporter import com.stripe.android.paymentsheet.BuildConfig import com.stripe.android.paymentsheet.model.amount @@ -255,6 +256,21 @@ internal class DefaultLinkAccountManager @Inject constructor( } } + override suspend fun sharePaymentDetails( + paymentDetailsId: String, + expectedPaymentMethodType: String, + ): Result { + return runCatching { + requireNotNull(linkAccountHolder.linkAccount.value) + }.mapCatching { account -> + linkRepository.sharePaymentDetails( + paymentDetailsId = paymentDetailsId, + consumerSessionClientSecret = account.clientSecret, + expectedPaymentMethodType = expectedPaymentMethodType, + ).getOrThrow() + } + } + private fun setAccount( consumerSession: ConsumerSession, publishableKey: String?, diff --git a/paymentsheet/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt b/paymentsheet/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt index 5cacd554878..c7b4ff47090 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt @@ -11,6 +11,7 @@ import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.EmailSource import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow @@ -86,6 +87,11 @@ internal interface LinkAccountManager { paymentMethodCreateParams: PaymentMethodCreateParams ): Result + suspend fun sharePaymentDetails( + paymentDetailsId: String, + expectedPaymentMethodType: String, + ): Result + fun setLinkAccountFromLookupResult( lookup: ConsumerSessionLookup, startSession: Boolean, diff --git a/paymentsheet/src/main/java/com/stripe/android/link/confirmation/DefaultLinkConfirmationHandler.kt b/paymentsheet/src/main/java/com/stripe/android/link/confirmation/DefaultLinkConfirmationHandler.kt index 2470056cf35..040279ed7b3 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/confirmation/DefaultLinkConfirmationHandler.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/confirmation/DefaultLinkConfirmationHandler.kt @@ -7,12 +7,15 @@ import com.stripe.android.link.LinkPaymentDetails import com.stripe.android.link.model.LinkAccount import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConsumerPaymentDetails +import com.stripe.android.model.LinkMode import com.stripe.android.model.PaymentMethod +import com.stripe.android.model.PaymentMethod.Type.USBankAccount import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.model.PaymentMethodOptionsParams import com.stripe.android.model.wallets.Wallet import com.stripe.android.paymentelement.confirmation.ConfirmationHandler import com.stripe.android.paymentelement.confirmation.PaymentMethodConfirmationOption +import com.stripe.android.paymentelement.confirmation.link.LinkCardBrandConfirmationOption import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.R import javax.inject.Inject @@ -112,9 +115,13 @@ internal class DefaultLinkConfirmationHandler @Inject constructor( linkAccount: LinkAccount, cvc: String? ): ConfirmationHandler.Args { - return ConfirmationHandler.Args( - intent = configuration.stripeIntent, - confirmationOption = PaymentMethodConfirmationOption.New( + val confirmationOption = if (paymentDetails.useLinkCardBrandConfirmation) { + LinkCardBrandConfirmationOption( + paymentDetailsId = paymentDetails.id, + expectedPaymentMethodType = computeExpectedPaymentMethodType(), + ) + } else { + PaymentMethodConfirmationOption.New( createParams = createPaymentMethodCreateParams( selectedPaymentDetails = paymentDetails, linkAccount = linkAccount, @@ -122,7 +129,12 @@ internal class DefaultLinkConfirmationHandler @Inject constructor( ), optionsParams = null, shouldSave = false - ), + ) + } + + return ConfirmationHandler.Args( + intent = configuration.stripeIntent, + confirmationOption = confirmationOption, appearance = PaymentSheet.Appearance(), initializationMode = configuration.initializationMode, shippingDetails = configuration.shippingDetails @@ -172,6 +184,20 @@ internal class DefaultLinkConfirmationHandler @Inject constructor( ) } + private val ConsumerPaymentDetails.PaymentDetails.useLinkCardBrandConfirmation: Boolean + get() = type == ConsumerPaymentDetails.BankAccount.TYPE && configuration.passthroughModeEnabled + + private fun computeExpectedPaymentMethodType(): String { + val canAcceptACH = USBankAccount.code in configuration.stripeIntent.paymentMethodTypes + val isLinkCardBrand = configuration.linkMode == LinkMode.LinkCardBrand + + return if (isLinkCardBrand && !canAcceptACH) { + ConsumerPaymentDetails.Card.TYPE + } else { + ConsumerPaymentDetails.BankAccount.TYPE + } + } + class Factory @Inject constructor( private val configuration: LinkConfiguration, private val logger: Logger, diff --git a/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkComponent.kt b/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkComponent.kt index 5e81339d00b..da3cf980f2d 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkComponent.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkComponent.kt @@ -16,6 +16,7 @@ import com.stripe.android.link.analytics.LinkEventsReporter import com.stripe.android.link.confirmation.LinkConfirmationHandler import com.stripe.android.link.model.LinkAccount import com.stripe.android.paymentelement.confirmation.injection.DefaultConfirmationModule +import com.stripe.android.paymentelement.confirmation.link.LinkCardBrandConfirmationModule import com.stripe.android.payments.core.analytics.ErrorReporter import com.stripe.android.payments.core.injection.STATUS_BAR_COLOR import dagger.BindsInstance @@ -34,6 +35,7 @@ internal annotation class NativeLinkScope LinkViewModelModule::class, ApplicationIdModule::class, DefaultConfirmationModule::class, + LinkCardBrandConfirmationModule::class, ] ) internal interface NativeLinkComponent { diff --git a/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkModule.kt b/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkModule.kt index 5c886eae001..705615c1f1c 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkModule.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/injection/NativeLinkModule.kt @@ -41,6 +41,8 @@ import com.stripe.android.link.repositories.LinkRepository import com.stripe.android.networking.StripeApiRepository import com.stripe.android.networking.StripeRepository import com.stripe.android.paymentelement.confirmation.ALLOWS_MANUAL_CONFIRMATION +import com.stripe.android.paymentelement.confirmation.ConfirmationDefinition +import com.stripe.android.paymentelement.confirmation.link.LinkCardBrandConfirmationDefinition import com.stripe.android.payments.core.analytics.ErrorReporter import com.stripe.android.payments.core.analytics.RealErrorReporter import com.stripe.android.payments.core.injection.PRODUCT_USAGE @@ -52,6 +54,7 @@ import com.stripe.attestation.IntegrityRequestManager import dagger.Binds import dagger.Module import dagger.Provides +import dagger.multibindings.IntoSet import kotlinx.coroutines.Dispatchers import javax.inject.Named import kotlin.coroutines.CoroutineContext @@ -204,5 +207,16 @@ internal interface NativeLinkModule { fun provideIntegrityStandardRequestManager( context: Application ): IntegrityRequestManager = createIntegrityStandardRequestManager(context) + + @JvmSuppressWildcards + @Provides + @IntoSet + fun providesLinkCardBrandConfirmationDefinition( + linkAccountManager: DefaultLinkAccountManager + ): ConfirmationDefinition<*, *, *, *> { + return LinkCardBrandConfirmationDefinition( + linkAccountManager = linkAccountManager, + ) + } } } diff --git a/paymentsheet/src/main/java/com/stripe/android/link/model/SupportedPaymentMethodTypes.kt b/paymentsheet/src/main/java/com/stripe/android/link/model/SupportedPaymentMethodTypes.kt index c42e5e06b0f..6d255ac921a 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/model/SupportedPaymentMethodTypes.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/model/SupportedPaymentMethodTypes.kt @@ -12,16 +12,17 @@ import com.stripe.android.model.StripeIntent * The supported payment methods are read from [StripeIntent.linkFundingSources], and fallback to * card only if the list is empty or none of them is valid. */ -internal fun StripeIntent.supportedPaymentMethodTypes(linkAccount: LinkAccount) = +internal fun StripeIntent.supportedPaymentMethodTypes(linkAccount: LinkAccount): Set { if (!isLiveMode && linkAccount.email.contains("+multiple_funding_sources@")) { - supportedPaymentMethodTypes - } else { - linkFundingSources.filter { supportedPaymentMethodTypes.contains(it) } - .takeIf { it.isNotEmpty() }?.toSet() - ?: setOf(ConsumerPaymentDetails.Card.TYPE) + return supportedPaymentMethodTypes } + val allowedFundingSources = linkFundingSources.filter { it in supportedPaymentMethodTypes } + return allowedFundingSources.toSet().takeIf { it.isNotEmpty() } ?: setOf(ConsumerPaymentDetails.Card.TYPE) +} + private val supportedPaymentMethodTypes = setOf( ConsumerPaymentDetails.Card.TYPE, + ConsumerPaymentDetails.BankAccount.TYPE, ConsumerPaymentDetails.Passthrough.TYPE ) diff --git a/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt b/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt index f555fa548fa..b7a9a56ad56 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt @@ -1,6 +1,9 @@ package com.stripe.android.link.repositories +import android.app.Application +import com.stripe.android.DefaultFraudDetectionDataRepository import com.stripe.android.core.exception.StripeException +import com.stripe.android.core.frauddetection.FraudDetectionDataRepository import com.stripe.android.core.injection.IOContext import com.stripe.android.core.injection.PUBLISHABLE_KEY import com.stripe.android.core.injection.STRIPE_ACCOUNT_ID @@ -17,6 +20,7 @@ import com.stripe.android.model.ConsumerSignUpConsentAction import com.stripe.android.model.EmailSource import com.stripe.android.model.IncentiveEligibilitySession import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import com.stripe.android.model.SignUpParams import com.stripe.android.model.StripeIntent import com.stripe.android.model.VerificationType @@ -34,6 +38,7 @@ import kotlin.coroutines.CoroutineContext */ @SuppressWarnings("TooManyFunctions") internal class LinkApiRepository @Inject constructor( + application: Application, @Named(PUBLISHABLE_KEY) private val publishableKeyProvider: () -> String, @Named(STRIPE_ACCOUNT_ID) private val stripeAccountIdProvider: () -> String?, private val stripeRepository: StripeRepository, @@ -43,6 +48,13 @@ internal class LinkApiRepository @Inject constructor( private val errorReporter: ErrorReporter, ) : LinkRepository { + private val fraudDetectionDataRepository: FraudDetectionDataRepository = + DefaultFraudDetectionDataRepository(application, workContext) + + init { + fraudDetectionDataRepository.refresh() + } + override suspend fun lookupConsumer( email: String, ): Result = withContext(workContext) { @@ -199,6 +211,25 @@ internal class LinkApiRepository @Inject constructor( } } + override suspend fun sharePaymentDetails( + consumerSessionClientSecret: String, + paymentDetailsId: String, + expectedPaymentMethodType: String, + ): Result = withContext(workContext) { + val fraudParams = fraudDetectionDataRepository.getCached()?.params.orEmpty() + val paymentMethodParams = mapOf("expand" to listOf("payment_method")) + + consumersApiService.sharePaymentDetails( + consumerSessionClientSecret = consumerSessionClientSecret, + paymentDetailsId = paymentDetailsId, + expectedPaymentMethodType = expectedPaymentMethodType, + requestOptions = buildRequestOptions(), + requestSurface = REQUEST_SURFACE, + extraParams = paymentMethodParams + fraudParams, + billingPhone = null, + ) + } + override suspend fun logOut( consumerSessionClientSecret: String, consumerAccountPublishableKey: String?, diff --git a/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt b/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt index 55837c54234..21eca79aecf 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt @@ -10,6 +10,7 @@ import com.stripe.android.model.ConsumerSignUpConsentAction import com.stripe.android.model.EmailSource import com.stripe.android.model.IncentiveEligibilitySession import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import com.stripe.android.model.StripeIntent /** @@ -76,6 +77,12 @@ internal interface LinkRepository { consumerSessionClientSecret: String, ): Result + suspend fun sharePaymentDetails( + consumerSessionClientSecret: String, + paymentDetailsId: String, + expectedPaymentMethodType: String, + ): Result + suspend fun logOut( consumerSessionClientSecret: String, consumerAccountPublishableKey: String?, diff --git a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletScreen.kt b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletScreen.kt index c13ad2723b7..71b34d6f539 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletScreen.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletScreen.kt @@ -39,6 +39,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.stripe.android.core.strings.ResolvableString import com.stripe.android.core.strings.resolvableString @@ -423,10 +424,12 @@ private fun ExpandedPaymentDetails( ) } - AddPaymentMethodRow( - isEnabled = isEnabled, - onAddNewPaymentMethodClick = onAddNewPaymentMethodClick - ) + if (uiState.canAddNewPaymentMethod) { + AddPaymentMethodRow( + isEnabled = isEnabled, + onAddNewPaymentMethodClick = onAddNewPaymentMethodClick + ) + } } } @@ -533,7 +536,9 @@ private fun BankAccountTerms() { Html( html = stringResource(R.string.stripe_wallet_bank_account_terms).replaceHyperlinks(), color = MaterialTheme.colors.onSecondary, - style = MaterialTheme.typography.caption, + style = MaterialTheme.typography.caption.copy( + textAlign = TextAlign.Center, + ), modifier = Modifier .fillMaxWidth() .padding(top = 12.dp), @@ -645,7 +650,7 @@ private fun AlertMessage( private fun String.replaceHyperlinks() = this.replace( "", - "" + "" ).replace("", "") private const val CHEVRON_ICON_ROTATION = 180f diff --git a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletUiState.kt b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletUiState.kt index 53e3330ac89..02602098789 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletUiState.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletUiState.kt @@ -14,6 +14,7 @@ internal data class WalletUiState( val isProcessing: Boolean, val primaryButtonLabel: ResolvableString, val hasCompleted: Boolean, + val canAddNewPaymentMethod: Boolean, val errorMessage: ResolvableString? = null, val expiryDateInput: FormFieldEntry = FormFieldEntry(null), val cvcInput: FormFieldEntry = FormFieldEntry(null), diff --git a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletViewModel.kt index f5c0dc2d5ba..cc0008c7677 100644 --- a/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/link/ui/wallet/WalletViewModel.kt @@ -21,7 +21,7 @@ import com.stripe.android.link.ui.completePaymentButtonLabel import com.stripe.android.model.CardBrand import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerPaymentDetailsUpdateParams -import com.stripe.android.model.PaymentMethod +import com.stripe.android.model.PaymentMethod.Type.Card import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.ui.core.FieldValuesToParamsMapConverter import com.stripe.android.ui.core.elements.CardDetailsUtil.createExpiryDateFormFieldValues @@ -36,11 +36,6 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.Result -import kotlin.String -import kotlin.Throwable -import kotlin.Unit -import kotlin.fold -import kotlin.takeIf import com.stripe.android.link.confirmation.Result as LinkConfirmationResult internal class WalletViewModel @Inject constructor( @@ -61,7 +56,9 @@ internal class WalletViewModel @Inject constructor( selectedItem = null, isProcessing = false, hasCompleted = false, - primaryButtonLabel = completePaymentButtonLabel(configuration.stripeIntent) + primaryButtonLabel = completePaymentButtonLabel(configuration.stripeIntent), + // TODO(tillh-stripe) Update this as soon as adding bank accounts is supported + canAddNewPaymentMethod = stripeIntent.paymentMethodTypes.contains(Card.code), ) ) @@ -344,7 +341,7 @@ private fun WalletUiState.toPaymentMethodCreateParams(): PaymentMethodCreatePara val expiryDateValues = createExpiryDateFormFieldValues(expiryDateInput) return FieldValuesToParamsMapConverter.transformToPaymentMethodCreateParams( fieldValuePairs = expiryDateValues, - code = PaymentMethod.Type.Card.code, + code = Card.code, requiresMandate = false ) } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition.kt b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition.kt new file mode 100644 index 00000000000..49d72b69ed5 --- /dev/null +++ b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationDefinition.kt @@ -0,0 +1,116 @@ +package com.stripe.android.paymentelement.confirmation.link + +import android.os.Parcelable +import androidx.activity.result.ActivityResultCaller +import com.stripe.android.core.strings.resolvableString +import com.stripe.android.link.account.LinkAccountManager +import com.stripe.android.model.PaymentMethod +import com.stripe.android.model.parsers.PaymentMethodJsonParser +import com.stripe.android.paymentelement.confirmation.ConfirmationDefinition +import com.stripe.android.paymentelement.confirmation.ConfirmationHandler +import com.stripe.android.paymentelement.confirmation.PaymentMethodConfirmationOption +import com.stripe.android.paymentelement.confirmation.intent.DeferredIntentConfirmationType +import com.stripe.android.paymentsheet.R +import kotlinx.parcelize.Parcelize +import org.json.JSONObject +import javax.inject.Inject + +internal class LinkCardBrandConfirmationDefinition @Inject constructor( + private val linkAccountManager: LinkAccountManager, +) : ConfirmationDefinition< + LinkCardBrandConfirmationOption, + LinkCardBrandConfirmationDefinition.Launcher, + LinkCardBrandConfirmationDefinition.LauncherArguments, + LinkCardBrandConfirmationDefinition.Result, + > { + override val key: String = "LinkCardBrand" + + override fun option(confirmationOption: ConfirmationHandler.Option): LinkCardBrandConfirmationOption? { + return confirmationOption as? LinkCardBrandConfirmationOption + } + + override suspend fun action( + confirmationOption: LinkCardBrandConfirmationOption, + confirmationParameters: ConfirmationDefinition.Parameters + ): ConfirmationDefinition.Action { + return createPaymentMethodConfirmationOption(confirmationOption).fold( + onSuccess = { nextConfirmationOption -> + ConfirmationDefinition.Action.Launch( + launcherArguments = LauncherArguments(nextConfirmationOption), + receivesResultInProcess = true, + deferredIntentConfirmationType = null, + ) + }, + onFailure = { error -> + ConfirmationDefinition.Action.Fail( + cause = error, + message = resolvableString(R.string.stripe_something_went_wrong), + errorType = ConfirmationHandler.Result.Failed.ErrorType.Internal, + ) + }, + ) + } + + override fun createLauncher( + activityResultCaller: ActivityResultCaller, + onResult: (Result) -> Unit + ): Launcher { + return Launcher(onResult) + } + + override fun launch( + launcher: Launcher, + arguments: LauncherArguments, + confirmationOption: LinkCardBrandConfirmationOption, + confirmationParameters: ConfirmationDefinition.Parameters, + ) { + launcher.onResult(Result(arguments.nextConfirmationOption)) + } + + override fun toResult( + confirmationOption: LinkCardBrandConfirmationOption, + confirmationParameters: ConfirmationDefinition.Parameters, + deferredIntentConfirmationType: DeferredIntentConfirmationType?, + result: Result, + ): ConfirmationDefinition.Result { + return ConfirmationDefinition.Result.NextStep( + confirmationOption = result.nextConfirmationOption, + parameters = confirmationParameters, + ) + } + + private suspend fun createPaymentMethodConfirmationOption( + confirmationOption: LinkCardBrandConfirmationOption, + ): kotlin.Result { + return linkAccountManager.sharePaymentDetails( + paymentDetailsId = confirmationOption.paymentDetailsId, + expectedPaymentMethodType = confirmationOption.expectedPaymentMethodType, + ).mapCatching { + requireNotNull(it.encodedPaymentMethod.parsePaymentMethod()) + }.map { paymentMethod -> + PaymentMethodConfirmationOption.Saved( + paymentMethod = paymentMethod, + optionsParams = null, + ) + } + } + + @Parcelize + data class Result( + val nextConfirmationOption: PaymentMethodConfirmationOption, + ) : Parcelable + + data class LauncherArguments( + val nextConfirmationOption: PaymentMethodConfirmationOption, + ) + + class Launcher( + val onResult: (Result) -> Unit, + ) +} + +private fun String.parsePaymentMethod(): PaymentMethod? = runCatching { + val json = JSONObject(this) + val paymentMethod = PaymentMethodJsonParser().parse(json) + paymentMethod +}.getOrNull() diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationModule.kt b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationModule.kt new file mode 100644 index 00000000000..d23e97acffb --- /dev/null +++ b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationModule.kt @@ -0,0 +1,16 @@ +package com.stripe.android.paymentelement.confirmation.link + +import com.stripe.android.paymentelement.confirmation.ConfirmationDefinition +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoSet + +@Module +internal interface LinkCardBrandConfirmationModule { + @JvmSuppressWildcards + @Binds + @IntoSet + fun bindsLinkCardBrandConfirmationDefinition( + definition: LinkCardBrandConfirmationDefinition, + ): ConfirmationDefinition<*, *, *, *> +} diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption.kt b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption.kt new file mode 100644 index 00000000000..52331fa15de --- /dev/null +++ b/paymentsheet/src/main/java/com/stripe/android/paymentelement/confirmation/link/LinkCardBrandConfirmationOption.kt @@ -0,0 +1,10 @@ +package com.stripe.android.paymentelement.confirmation.link + +import com.stripe.android.paymentelement.confirmation.ConfirmationHandler +import kotlinx.parcelize.Parcelize + +@Parcelize +internal data class LinkCardBrandConfirmationOption( + val paymentDetailsId: String, + val expectedPaymentMethodType: String, +) : ConfirmationHandler.Option diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/state/PaymentElementLoader.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/state/PaymentElementLoader.kt index 8f8319e46a4..8b895c5fb6f 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/state/PaymentElementLoader.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/state/PaymentElementLoader.kt @@ -537,7 +537,8 @@ internal class DefaultPaymentElementLoader @Inject constructor( useAttestationEndpointsForLink = useAttestationEndpointsForLink, suppress2faModal = suppress2faModal, elementsSessionId = elementsSession.elementsSessionId, - initializationMode = initializationMode + initializationMode = initializationMode, + linkMode = elementsSession.linkSettings?.linkMode, ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/link/TestFactory.kt b/paymentsheet/src/test/java/com/stripe/android/link/TestFactory.kt index bd0f5461bf6..de82a79461b 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/TestFactory.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/TestFactory.kt @@ -15,9 +15,11 @@ import com.stripe.android.model.ConsumerSignUpConsentAction import com.stripe.android.model.CvcCheck import com.stripe.android.model.EmailSource import com.stripe.android.model.IncentiveEligibilitySession +import com.stripe.android.model.LinkMode import com.stripe.android.model.PaymentIntentFixtures import com.stripe.android.model.PaymentMethod import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetFixtures import com.stripe.android.paymentsheet.paymentdatacollection.FormArguments @@ -116,6 +118,11 @@ internal object TestFactory { originalParams = mock() ) + val LINK_SHARE_PAYMENT_DETAILS = SharePaymentDetails( + paymentMethodId = "pm_123", + encodedPaymentMethod = "{\"id\": \"pm_123\"}", + ) + val LINK_SAVED_PAYMENT_DETAILS = LinkPaymentDetails.Saved( paymentDetails = CONSUMER_PAYMENT_DETAILS_CARD, paymentMethodCreateParams = PAYMENT_METHOD_CREATE_PARAMS, @@ -150,7 +157,8 @@ internal object TestFactory { useAttestationEndpointsForLink = false, suppress2faModal = false, initializationMode = PaymentSheetFixtures.INITIALIZATION_MODE_PAYMENT_INTENT, - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ) val LINK_WALLET_PRIMARY_BUTTON_LABEL = Amount( diff --git a/paymentsheet/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt b/paymentsheet/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt index 72e182321db..2db37847980 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt @@ -14,6 +14,7 @@ import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.EmailSource import com.stripe.android.model.PaymentMethodCreateParams +import com.stripe.android.model.SharePaymentDetails import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -37,6 +38,7 @@ internal open class FakeLinkAccountManager( var createCardPaymentDetailsResult: Result = Result.success( value = TestFactory.LINK_NEW_PAYMENT_DETAILS ) + var sharePaymentDetails: Result = Result.success(TestFactory.LINK_SHARE_PAYMENT_DETAILS) var listPaymentDetailsResult: Result = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) var updatePaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) var deletePaymentDetailsResult: Result = Result.success(Unit) @@ -146,6 +148,13 @@ internal open class FakeLinkAccountManager( return createCardPaymentDetailsResult } + override suspend fun sharePaymentDetails( + paymentDetailsId: String, + expectedPaymentMethodType: String + ): Result { + return sharePaymentDetails + } + override fun setLinkAccountFromLookupResult(lookup: ConsumerSessionLookup, startSession: Boolean): LinkAccount? { return linkAccountFromLookupResult } diff --git a/paymentsheet/src/test/java/com/stripe/android/link/model/StripeIntentKtxTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/model/StripeIntentKtxTest.kt index 6a2fadcbc6b..a3b059a9d0e 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/model/StripeIntentKtxTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/model/StripeIntentKtxTest.kt @@ -14,7 +14,7 @@ class StripeIntentKtxTest { fun `When test mode and test account then all funding sources are enabled`() { val supportedTypes = stripeIntent(liveMode = false) .supportedPaymentMethodTypes(linkAccount("test+multiple_funding_sources@test.abc")) - assertThat(supportedTypes).containsExactly("card") + assertThat(supportedTypes).containsExactly("card", "bank_account") } @Test diff --git a/paymentsheet/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt b/paymentsheet/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt index 0aafaa18f43..1ff976f126b 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt @@ -19,6 +19,7 @@ internal open class FakeLinkRepository : LinkRepository { var mobileConsumerSignUpResult = Result.success(TestFactory.CONSUMER_SESSION_SIGN_UP) var createCardPaymentDetailsResult = Result.success(TestFactory.LINK_NEW_PAYMENT_DETAILS) var shareCardPaymentDetailsResult = Result.success(TestFactory.LINK_NEW_PAYMENT_DETAILS) + var sharePaymentDetails = Result.success(TestFactory.LINK_SHARE_PAYMENT_DETAILS) var logOutResult = Result.success(TestFactory.CONSUMER_SESSION) var startVerificationResult = Result.success(TestFactory.CONSUMER_SESSION) var confirmVerificationResult = Result.success(TestFactory.CONSUMER_SESSION) @@ -103,6 +104,12 @@ internal open class FakeLinkRepository : LinkRepository { consumerSessionClientSecret: String ) = shareCardPaymentDetailsResult + override suspend fun sharePaymentDetails( + consumerSessionClientSecret: String, + paymentDetailsId: String, + expectedPaymentMethodType: String + ) = sharePaymentDetails + override suspend fun logOut( consumerSessionClientSecret: String, consumerAccountPublishableKey: String? diff --git a/paymentsheet/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt index b9b9fcd0db7..96d76e13b24 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt @@ -1,5 +1,6 @@ package com.stripe.android.link.repositories +import androidx.test.core.app.ApplicationProvider import com.google.common.truth.Truth.assertThat import com.stripe.android.core.networking.ApiRequest import com.stripe.android.link.FakeConsumersApiService @@ -50,6 +51,7 @@ class LinkApiRepositoryTest { } private val linkRepository = LinkApiRepository( + application = ApplicationProvider.getApplicationContext(), publishableKeyProvider = { PUBLISHABLE_KEY }, stripeAccountIdProvider = { STRIPE_ACCOUNT_ID }, stripeRepository = stripeRepository, @@ -679,6 +681,7 @@ class LinkApiRepositoryTest { consumersApiService: ConsumersApiService = FakeConsumersApiService() ): LinkApiRepository { return LinkApiRepository( + application = ApplicationProvider.getApplicationContext(), publishableKeyProvider = { PUBLISHABLE_KEY }, stripeAccountIdProvider = { STRIPE_ACCOUNT_ID }, stripeRepository = stripeRepository, diff --git a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenScreenshotTest.kt index 1b374f23199..1b3f0737825 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenScreenshotTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenScreenshotTest.kt @@ -139,6 +139,16 @@ internal class WalletScreenScreenshotTest { ) } + @Test + fun testCannotAddCreditCard() { + snapshot( + state = walletUiState( + canAddNewPaymentMethod = false, + ), + isExpanded = true + ) + } + private fun walletUiState( paymentDetailsList: List = TestFactory.CONSUMER_PAYMENT_DETAILS.paymentDetails, @@ -147,7 +157,8 @@ internal class WalletScreenScreenshotTest { isProcessing: Boolean = false, expiryDateInput: FormFieldEntry = FormFieldEntry(null), cvcInput: FormFieldEntry = FormFieldEntry(null), - alertMessage: ResolvableString? = null + alertMessage: ResolvableString? = null, + canAddNewPaymentMethod: Boolean = true, ): WalletUiState { return WalletUiState( paymentDetailsList = paymentDetailsList, @@ -157,7 +168,8 @@ internal class WalletScreenScreenshotTest { primaryButtonLabel = primaryButtonLabel, expiryDateInput = expiryDateInput, cvcInput = cvcInput, - alertMessage = alertMessage + alertMessage = alertMessage, + canAddNewPaymentMethod = canAddNewPaymentMethod ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenTest.kt index 46c1deb7006..8f0b13fd524 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletScreenTest.kt @@ -582,7 +582,8 @@ internal class WalletScreenTest { selectedItem = paymentDetails.firstOrNull(), isProcessing = false, hasCompleted = false, - primaryButtonLabel = "Buy".resolvableString + primaryButtonLabel = "Buy".resolvableString, + canAddNewPaymentMethod = true, ), isExpanded = true, onItemSelected = {}, diff --git a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletUiStateTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletUiStateTest.kt index 56b8ca0c134..47b7d36385d 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletUiStateTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletUiStateTest.kt @@ -155,7 +155,8 @@ class WalletUiStateTest { isProcessing: Boolean = false, primaryButtonLabel: ResolvableString = LINK_WALLET_PRIMARY_BUTTON_LABEL, expiryDateInput: FormFieldEntry = FormFieldEntry(null), - cvcInput: FormFieldEntry = FormFieldEntry(null) + cvcInput: FormFieldEntry = FormFieldEntry(null), + canAddNewPaymentMethod: Boolean = true, ): WalletUiState { return WalletUiState( paymentDetailsList = paymentDetailsList, @@ -164,7 +165,8 @@ class WalletUiStateTest { isProcessing = isProcessing, primaryButtonLabel = primaryButtonLabel, expiryDateInput = expiryDateInput, - cvcInput = cvcInput + cvcInput = cvcInput, + canAddNewPaymentMethod = canAddNewPaymentMethod, ) } } diff --git a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletViewModelTest.kt index 4ab48ccde2b..2190e074999 100644 --- a/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/link/ui/wallet/WalletViewModelTest.kt @@ -52,7 +52,8 @@ class WalletViewModelTest { hasCompleted = false, primaryButtonLabel = TestFactory.LINK_WALLET_PRIMARY_BUTTON_LABEL, expiryDateInput = FormFieldEntry(""), - cvcInput = FormFieldEntry("") + cvcInput = FormFieldEntry(""), + canAddNewPaymentMethod = true, ) ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataTest.kt b/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataTest.kt index bbc3942b281..ec2f5796b9d 100644 --- a/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataTest.kt @@ -1326,7 +1326,8 @@ internal class PaymentMethodMetadataTest { useAttestationEndpointsForLink = false, suppress2faModal = false, initializationMode = PaymentSheetFixtures.INITIALIZATION_MODE_PAYMENT_INTENT, - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ), ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/link/LinkFormElementTest.kt b/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/link/LinkFormElementTest.kt index 97b51df5908..ab631aa3cea 100644 --- a/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/link/LinkFormElementTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/link/LinkFormElementTest.kt @@ -26,6 +26,7 @@ import com.stripe.android.link.ui.inline.LinkSignupMode import com.stripe.android.link.ui.inline.SignUpConsentAction import com.stripe.android.link.ui.inline.UserInput import com.stripe.android.model.ConsumerSession +import com.stripe.android.model.LinkMode import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.paymentsheet.state.PaymentElementLoader import com.stripe.android.testing.PaymentIntentFactory @@ -137,6 +138,7 @@ class LinkFormElementTest { clientSecret = "pi_123_secret_123", ), elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ), ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/ConfirmationHandlerOptionKtxTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/ConfirmationHandlerOptionKtxTest.kt index 91fcbc31012..f7fb9fb3ff0 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/ConfirmationHandlerOptionKtxTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/ConfirmationHandlerOptionKtxTest.kt @@ -462,7 +462,8 @@ class ConfirmationHandlerOptionKtxTest { initializationMode = PaymentElementLoader.InitializationMode.PaymentIntent( clientSecret = "pi_123_secret_123", ), - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ) } } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/linkinline/LinkInlineSignupConfirmationDefinitionTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/linkinline/LinkInlineSignupConfirmationDefinitionTest.kt index d0e21c15658..620563ab485 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/linkinline/LinkInlineSignupConfirmationDefinitionTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentelement/confirmation/linkinline/LinkInlineSignupConfirmationDefinitionTest.kt @@ -23,6 +23,7 @@ import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.CvcCheck +import com.stripe.android.model.LinkMode import com.stripe.android.model.PaymentMethod import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.model.PaymentMethodCreateParamsFixtures @@ -662,7 +663,8 @@ internal class LinkInlineSignupConfirmationDefinitionTest { initializationMode = PaymentElementLoader.InitializationMode.PaymentIntent( clientSecret = "pi_123_secret_123", ), - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ), userInput = userInput, ) diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt index 9add88e041e..92e4a9dd9ee 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt @@ -39,6 +39,7 @@ import com.stripe.android.model.Address import com.stripe.android.model.CardBrand import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConfirmSetupIntentParams +import com.stripe.android.model.LinkMode import com.stripe.android.model.MandateDataParams import com.stripe.android.model.PaymentIntent import com.stripe.android.model.PaymentIntentFixtures @@ -1064,7 +1065,8 @@ internal class PaymentSheetViewModelTest { useAttestationEndpointsForLink = false, suppress2faModal = false, initializationMode = PaymentSheetFixtures.INITIALIZATION_MODE_PAYMENT_INTENT, - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ) val viewModel = createViewModel( diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/state/DefaultPaymentElementLoaderTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/state/DefaultPaymentElementLoaderTest.kt index 22e37e32958..0d51c29eef9 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/state/DefaultPaymentElementLoaderTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/state/DefaultPaymentElementLoaderTest.kt @@ -653,7 +653,8 @@ internal class DefaultPaymentElementLoaderTest { useAttestationEndpointsForLink = false, suppress2faModal = false, initializationMode = initializationMode, - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = null, ) assertThat(result.paymentMethodMetadata.linkState?.configuration).isEqualTo(expectedLinkConfig) diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/LinkTestUtils.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/LinkTestUtils.kt index 7724dcba99b..8afb4acc21f 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/LinkTestUtils.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/LinkTestUtils.kt @@ -6,6 +6,7 @@ import com.stripe.android.link.LinkPaymentDetails import com.stripe.android.model.CardBrand import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.CvcCheck +import com.stripe.android.model.LinkMode import com.stripe.android.model.PaymentMethod import com.stripe.android.paymentsheet.PaymentSheetFixtures import org.mockito.kotlin.doReturn @@ -64,7 +65,8 @@ internal object LinkTestUtils { useAttestationEndpointsForLink = false, suppress2faModal = false, initializationMode = PaymentSheetFixtures.INITIALIZATION_MODE_PAYMENT_INTENT, - elementsSessionId = "session_1234" + elementsSessionId = "session_1234", + linkMode = LinkMode.LinkPaymentMethod, ) } } diff --git a/paymentsheet/src/test/snapshots/images/com.stripe.android.link.ui.wallet_WalletScreenScreenshotTest_testBankAccountSelectedState[].png b/paymentsheet/src/test/snapshots/images/com.stripe.android.link.ui.wallet_WalletScreenScreenshotTest_testBankAccountSelectedState[].png index 443ac2ea03b577ba77a132dec604bf2ca9fd96da..970e05e37a3140ae755b14572667de5049de870b 100644 GIT binary patch literal 34089 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 literal 34062 zcmdSBWmHsc_&2J6Fo3{-5|R$xh;+-)0)kRQOUKaNIh2%0x3qLO($WpmA>G}5HqUxL zo-glt&ws6R_9y0^weQ*cy6gJIMTp`jDJ%?PjAzfDVaZ5~e|h%odHb_x$Xg&(phdpy zLGal#pJy`SqRK8hd%w|K@MWAHEWL+j9)#z1tAFdbU)n!dC#2X9aR~5j&Y-_U7Bf!p zg>0t0c^{mDD~d-+AB8LWCIk3B#ryYW0o!Fw2?9|<{d0*zLFiZE)77|JY+q1tcnE?Z zz$;(9y2(X>zj)CxAi!rSF$gu#YD$klfT5&V0pG#U;H(TV9u#ED`5FoZK_UX7(jZ9Z zs3Hg*xQY0G?IU=QE9G@;=-jsD9#)gdJq|2b5)$e?AHA zr)EJTgfXtGa1l>UIDBT+*+bu_LxAnLp8v0|M=(rLtB`HA<>N8*94%8nUs0;K-^l}S zUxfyILDgX@t+p!_j}EzOuJftrGuQ9}g24Z>3Yi$mA0uf@#UTW&|LnCf3+e~p-MNe5Qlm(%$&@EuI5lM6jV?7lVK#T#3uSi1;l=i|AK{~wCa%ZsVfOv^&In; zRbA;)A%OyXK{^?nnsEog@RX-Z4zB2ywZEcfN!SF-aqv=bt!#MiGcB@rw-3#0uR+d zo+@O{*{w@qc^nGXuNI-}172;L^(UW^*Uea1I-=~O_b30SCTzRVk3bloKh2dMF0}tQ zri`76?VWfPVo!iRC&%bQ+lz{iPh!}1@lFAle|YVFew1(C9SLkNJ!(3)UTm>P8|~J7 z$p7`LiUQh@7%6i7(aW<#$ZkU}%rkx|LBP5^&EO(M;zAn%Mq8nW$SDlRkXSb;khIMm zx=bUa&K{GkT|ZdW9qYL6pW{&T@GN;vJBk?@#d@6CT5pT|)66fu9FA1fVJMCb0A~KS z6)6J(+?p~k$iT!DKQ{J-&zbep;^RL|OVS`Ojy~XCV>%|`3)hh{WY^7W0;1r7!Kr^%8z=D&aAy~N*(v?vaj zbJ&!=#>ek(x|Tg7tu$fdyv5*@H(bL_eD7GJvszp$M9pD56hAT|b|5G?(;^~wD*LhF zZ4kCZ!7kCJ#2ZDOwUFJbt`vifq8C4+qfLgPcBdys%?#bOOA%2auS|N5SL1hziz{GI zA~H`^r+w@=T&k|!>qv5;W#L6iI=U&(h~w2f85fuSh7PBRWrL*dODZ~P`jWvQaAw43 z)NC=YQ@NzD0p`dQ5ab~@e><~A$$9Ct4qHh@ZE8B&0rPdcabG{vT5htol@dI&t50Qj zZA0@Q-u=K8n&z>CUw>L6b$+$ZG--<5__gheJkDsjkF?;`NTuD}K8}orM&P%Q{*&wQ zE~4T#4}=HogLQS{ z;qE)zYHOq2URh?}=~n(76zAthNrcALM@qPCEpHm0tf?QIx*&;4CK2koNgXuY+B(mG zX+I@Fa70d;HUd1QFYhp|lk9YebpwKz6Oyf(m$E%SvDnn5tCi}Mo=>W(GebO92P4<5 zqD97*XKnA6JGvJ(d7bvM=O0_g-LOd`cO@Fw4f3SL#QX&o05wL1(_p7j(^01 zGv#=(ZRy!|jwk2HIoUQ}ZKQP1yW&Fc&=$w}ayu-mkwIcDZ}Rt5oW&p(#;duOZd5?9 zj4X*ND=MmOC8*plw2JEas`2n0m07x^$UQ|_N)er>=A%DFYfk*R0z8E8%HlT+&>`(L zmW|5vQ4}W<^Rki_`UbD4*-Afb@L=u=9D3}qPL1UhR{I{FuYX_>DPn_hOQZFp!l1!r z#)Gugg1A9&(fKGUx+)J~_B)cS{76k5-&uPr3)1yk7Yd0~cyH9N#x%~4My?ZsT*;>E zcC8(biM?3botc*AdcjqkXE}%TcSp$crU>Iq+gT*HyIO@n7R2rqd}nWeYUo!^k2`f+ zD4K+728=h%a zOEQe}2vnroA~Ejq^?<5K0vi120~$)HZ(X>4+|Tn|IORdbCO%j{-oXa;fwB|H@FeP0 zI=T4r)!e?#^h>2sWP;@l76C3xZS7P;W8=aPT-@B-;T_o#w+G%It+mX}8*ZwWxHAI; zm&Z`3B*Vs&>mA`gtu&!mXB?&GX#`?{5fd)51J9VHVXQWD>X?~=y-Y-2wfw7A?C5ZA6Iu&JkfkT;M=k{!755}N2Y;&<(1 z4zERkCuwSQy;rHuQQxv0aCI?2%AA~;AZvZT0RX=y()WoSU0{N=druLR6w&lbIZoc5WC(#)f4|4tspiKb&{XlzwsFXNlkZnI;~^w zvAE9V{4F9Trmmz756W4Q#wrk25ApJ>eCH!)5YX<3Ci{B*1G%*Skwoe9E=uB}<;vk^ zRiLfALmwT|H$7sLe@Db4cDLh$)v%CsHC>Ld8Jv|r;N68epa@coT%T&I7SS+P8naDU z!hBR+adlkJg~Ge1f0}q*R9q!7M>{O41Odw>(@G(6g;-as$t6bs%cnZz6UqSt^Ej{r zn>M__jCajR=KqUt9s4HpQlj+X=1cpRZn;TEN%3X;w}`9An;X7@H)}AXrH#<-&1P!+RXkkz^8QpY;gm2z|9&Rg@ty$p^tH$35_AA&ipZP5y-u!Sw zLKgbRD_H+~w+qYDK+=G45mT6y!M#CoAf1on*>M?0HfM(-MVhoDyk9_`;kdKDTg%3t z4-z75Orz%1ED#i!n{V>%P-FTId*dZaP zw_<6z04;yRhdYuO=R%R^)Z#Zlw+4UkSC@3&GnEx|-0r1@w`ro zNbLjv1Ximd$-FhpY4X0^@oP{`>nuM9== zl_(}G5G>aJ{w1t(G_A8#5v2LN5}$oBh~%=b@Njoel+XeIYM?euwx)dBgeHUVshRCCFp}JtdLUuoY&yT7 zJ2`MqFT5pc4?q_sXzm*$hoBUy7Ekf}Y-Ls=F@YTsMuc%jXkFpy1;@X}FBc!R4)gye zmiL7vX4bK;U2dCrI__u2E`_~0)r8d`zDM|G&^s`)*AE?FTVgdiC*VJ1n_W^;V$V6> z;!B}J+^$Vcmk)}}I=D=IUmV}x;EWrgn2ML*>E+f(QFxx^#8)FP@pK)H)CD3)k9tHM zHW{pTo6=hO>_?l<$?<_({s@*4{E93q zlinUT3I6n>ts?L+F!FDF+bdn8L{8V-4K(;rdx02pU3F`L-)adeUD4b@p?_k$V>EZ-d>uSvexmMB#;` z1a;o23^`pA`jcrq8Jtp*bT0g%QQ5@P7l^$ZRD<${CT;&r^Fy72*Ep{1z^ z5_nGFzJfeQRJz+o@q-2d9&`MEgtz{OZz8F7JpW?wh}!?&Bvu#VF$pV3XP$`}T^fSn}wAwM+}4{9|CUULvF zbQ?*mH!y~l0EU(zx^hFmC{4ZnTYWyI^@}|a3FX+W;}{BJI$WC(N1w*a^s6;jD*LuL zDYT5|a8$SVGUNxA0CvyLVB5ic;{{oqodE<7DlO$BVMG`YXXoU)o_b$oZ64DVDnwTn zLD1fCgUUzb*r5K;Z(_w?wko$~h)Fxz)df>df{gDC6TCLi{3cug=cAKOhFZhW*vQCR z2?>cG@$s9NJ|4TfyZd?62nVWjtZ)|bb&Z#f8~k_AXD9iN-PdXs#MTn;SJxeE3xs59 z|G^;QksDu?tG*Ez{Z8mqHaO9J*dU0F>Am=k>oy;lik6*S)tITAfBlx!&b&}m+D&&_vk}d_YulMxb5?CG zT5kS{Yfk3G6M^5JfKbNgs1s*Dn8Gb6fE&4gmj&2?%vqYB@mXbMiUoy@lMCOvL_|cE z$QM>Wd?$Ci;=4Y_y6oAT!TfzeLzgGLR2tOBQY-xH*1GW?@`lp|VQ5(6HGG#!0eM() z!-b-Fm+e3kG*NK9Dz=sKt@a*<@~HyKa&tdvCxa_qnc$U}(kk1U)fX*n*hP1xE7Tqy zysNLT*S0E#c&BWdBRPsVY)RwOAY`IV8ZL8kbNXK?G-V%`Hr+Iz?TW~ed!D^m@H(%) z%xP-M;W{|H10B<8(;%)TjO=I+{5olJWMj>i_HO510i*%VF*J8A@nWiZSnUXn?=Q^> zTe64}?%hIcsq~?NY_<&lBDphx6vp!Qv?2bx0dRoq$wxjoxu9dz0q@9m4*n2j?2DnUVNq z5Ws)vK<$hhUljkWlZ))8Zuuuhmz`NqBaw80D4M5K|IH^p)TuMF|E+)+znhW54EIjr zqePlq#0=|mhUG7FTP+>}epCTACN?n`MDtmx8DoOciJ13rFif1te7dbtU0pS-gN9h0imR`bpdzw5uz z@{^vY|oJWLzUV$EZi>QkbE3>7gt?)Wuow$k_{Vm0W{( zC(I{StB0N@n4E2?tp71iK-*2VnN%e8Cpk-zd(Fz*6kcI|TJ`r8n4HboMIVPcbAFYz zFQ}{USFqY+ew=tl&ssRKf6_<1FvLyfssL&Fo>o}7g)FD(x})_&BlW`WHncBL1ATy> zfi9G7+S!pL;uSQQ!iw9CKjCaly*)DRZ_p9UVUzf?!qispmh$yz%h?Z}#nikx0VIXq z$j5Wp>yzEs3TyAMgIyle@J>3zev!vJruy}g<@fG7WiKhJ)rZphM+_trS{|44ba!l# zgG&C^MSzyCPZ>_Sk|}yQhMQ?`FN5k=JKD3>W;S)=r*s|_@$iNkS9z>vb62e?yyrDf zPPO|#ehnB*JoOhm={bGxas)E?tJ*N$-PzecSS$E8-Rq*7LCs%bxdNGoyNEyg_Ac~6 z$I9|)qfr|nhlu-VzHhBkLc>X)+&882N|>&-v_=eB!&>frYNGRoQk{pLr^#RE>j$$7 z*L~zU#DEiU7-*9VXI-aoWCp39yy0VQW2Sei4&ohB0^yLrZ9FS$F|TutHfrf>MShw7 ziqdq#8f9-^(mXGa3t1RNrb1x9Zck~V{9Ug(Am%rm???c83lLiRCP%NKa`Mf~HP-7b z-dxh!8Hb)#iVxc+y1k>Tz3)v#gE5xxBr@#i1w|j5Z`(#U4qYy@)BV~p?C;*yFTtW} z7lojg{y^l`dMlORf}dy_e00!Uce=-V1ciWAL9Rse<-%i(z(dd3Edf}B9(kUn(pOqz9Pby7fo1f)B=a`_Xc>;a@A26v zW5{okt$Igw8%$_0Gv<#(2+oqqQrmi{OH?z77)Y!zsV98!2S_4roK??#eCXaT_SDwR zgmkHTmdMhqthw9Qlo4BKu%ov*t`#O1mT5S!l+XoMDnQE>TQAd~!GU*`i~Y)L(6AR* zhmQgu(mcGrVQ5<$;6HRIxc5FFm-C~7m~bi4`)zuhcU6j1i?F9SnUE>h_Hj1)TOPWn zek7~SLLe!8a9_=7;cH8ZLBh?)Of_%kyETSNE*9|i{W!XXVt}3&XX)PVC?bAn z{;K`w9tXeX1YW!D!5*8Ve0(5l17g+ zX51t4plQu#Lti2WO-R>$3jlDnehdyKmX#GeqgEg5^|`~YkDsj41cVuPetG;gDU(Zh zr_IQujq@5|-yI>un1)Hn63uVmYw-Mbe7Gr>(h(q$3h|vcwIkm^>_fJ~c^2|YlogKs z-~?s|b*G=vv4qzC+it&?WCQbrT@Yqlc2h=;bjzN6_HUWvz~)XaQvrgoX(#(uYOHt1 z#(Ae)2n7}5Zf-L`Eb6AI)5+DTMP`qp?lx;m4NY?45n|4(ybu&1yBS48?x)}vlTfMl zvct+u(uL_SEkO353Eva4{7mYF;pRIzRaF2BI`=O1S+uSqD}`qR%yx1>tI+qR zBQ}?Wx|CFr1*Up3;$Q#iXj(lC0}CKq2nsXn#6kjn{@B~2vWtDI&|Qy$@jP0u$Oz8~ zGEeCArC6p8T8=gKiw03HW5(!_pXl0v6KzsfssfpxtcHS)!bkUZ@EGzNIfH&S+Gc|_ zbYt5({0_r)7!u?IJj%#%mj-rU0$6zNl&5rPq`dt)^ukQ*qq*<56_Udtu1Q$_{P{n6 zDlh+aZ>x7$kFQqO6=6*tqb31Eyh8Y?x!qsY|5#pnvE8GV)-xhT2#dqF^^gXTaRiHx z?{B@Cx+A6fLtf=AKp>Fb&2I32$9yIWWd8T#uTSP}2qL){J~zfsmmNDD1B#t`c>U-G z=$ZTc`1Xr=;C9DvL$00W_WbaPnub)i!U`F?hY?Jdj|LeJTm8f%#7plfq-Ve^X8Y*sFtEjsS4*6ZvxF*}V2jWC;f{cXfHbwVh&WR#V=lb#(oL z<<=IFccjq<0btdy%9V$te!)xBO)1H*yA3x98j59@+vrb~)|c~sG~C34ON=4Zo#+m# zpwc)Wimh|B{%9OGmh>wVFNZk^XLN`U3G)s@_9gDo>Blnc{eH%;$42V}TW3bQXdbnD z*i-3-Cxj|0DmR#~wPkE=%axUnI>r!ZucrnNak+8+I1to9AIzUEJdC~a$P*nkMp^`ku&-R24aeeidfOFY;~a0 z!@iQ_6a!_L{nZ3_d2kPi^0sjl17guPMSu{*} zt))26A)V?!?|;=xYG>2)(C%wnD}pRru`oV&=1u=ls-&S3&?Q`);^92&;W+|9rs&GB zNy2_|#k;#p*>T{;fdVB8$~BV)P+xgHF)h9lox6W%YxE&re? z7MF&415Pz3d1cfMg-OdTm zDn`8Fm|-F>8J)B8h6SLgDnQ#^-v}9hn=9bArF?-z=Te0mlx0qq zlbicSFFdxX$z!lGGZR|NrX|f~R=Bn``U(%v?!%8E-6J!3hzKmBt?hQbCu;SJhK8}i z7$bbja;!r5bPxVTZBz5Bq8CVAam0(yo?Ei?54Ki`lpNo(zPM{>sOFI$B`di+lu z*2%dX0He*tu8+Ha=QK3Tl3AmZ63gD*KQa9L!)0Fg1bo)wdw?<%^P~y5dGaZeoX6|B z4#Rk=Pi8iC;SGHD-XnrkRFQRm&<%p5;UPT(iI|<^JzW!Juh)9-18BY`*X}8Xwp(Si_KBFhcmd6}YT z{Drj`b;8$vg-CkrXyQW=3Sl(g>>(_OXPY7}^w9CY6B9k5Y`?R%-*O8$9Yg{2ZlT%8 zm71!~gQ%4($UuMP@2rGtw?YE#obz5Bz;;5%FSiB6iAhKRQUO}}$|zaDx%`v4Z%@Wc zaO&M1lEHo24}gu>vHjK2sxA7%aO}Dr4+QM;RJTwaX`@Gty5Dg(aKwm!4bR)>yl4eBaT0R-QLwj`$oX2z-o26 zs_LclHOLkzg0P*|z{=v22xZIsjINi-dOxw3^IxWuc=%FOy2XR?gVQ}4W8kE4Ck}7< zm%g2QC9~9w=KRkm<{!_A@36XV{-wDO!8GHf^_t*E|8RGNPdlfGGV;I&SPh(1ufp9l zp`g&wkC%=u)|^(~`RIIl^ly9fbW}g1fb*VM-_=^nxpjUSk}4oyAloD1-4YliTw7Z! z;9Z$5pLol}B-Jf%Ygs4xES|FK+(sxdv1A=YMn-jpzvyymz`)$JmWhb1^KkWP&}Z2g z)Xg*#x!aO0c2|JRS8$D_THTzv5~E>KYy+C*PQIGqdVwS30|2ZX8d>1b5;{^gMAopy zm(XFQwSRa40-P;1auo%kG&Rgh8+53>;l9Y)P_uSz_dpr9*nXqG3$2t`1A+`Z`^3~D zi&r6nmEKJ$EHbrpr#IQ}rw7SGZ)~`UP&c3^}11Nc*i=iatr9m78V|LxiJU>lIoK%j-YFU0utG zU;4Ys{)*5M{@*Xt1x1oNQ`9fc|$Kh4+ocK55nJ{f^yuD zx-lR{zdlQ%Kr9|3%b%scBm?rPW;#w-D^fBpA-#9?g|^UvngE)#m;5cAxdVWM#jn@J zl&S~fV!s`AKez7r8C^(IyD^3cW_pq7FGC1QGbGvF3e`cb8ub7K>G^2oS-`6!>f{t5 z5Ltr&`>mpDMaP-8LH&(__kmqm`oR0&Hi6zwRlQF4Z6+6_h*LF{i;BRgW;5JoI+&!V zpY6LIpxg&hxa#~N=@vXYvd1GLT5EoYz{v0n15f6yCkfk9YOH2v4gU&#werIG9FX=J zx;Zp4mhbIWvUhpQ91^V|XD^A|i;MOW1A}>^W4;Mq7dn<)yj~7JdZWFv+&~(E53Li^ zLw{H-P|F!EH{zF^2FSFbU;VG+mf?Ei*%>6XW3MOU`dgz5=PBnkuHpyNdyB4wzAX6e zmivd`S^vJ*#InJ1L#m}`7ULX=gOBI}`WKHvQP=GtkI1AYoV0K%9$7hNKSQWeO7j(9 ztx==C7)+}EDX|EOo0~*3$hDz~AQSi#Jbu6PUMM{!^A^xuh-CkiPuIFDlsTb%&DVEt z?|gHRnAvZEH1!!G-r#ylunVI)U?}=`!R!m^q$sMh87aKK*_2OrD%fxM@?-}Qg3E#9 zzRIuWY;T53PF!rJMLSa&_Z!?w_K#<*{>5Of4oA0=4t=jWQ^=oIC$JkcCG7oWPMIxq zIH*s=;;t@WtD4{|OS=ZvAfK~Dr8Wek%x6ULQ!012RA*sFo*Okv1ZeU-a`2GAp;xZ$YL~(|@4%!(v84wr-Ux=}uEkKIM|j z#tcC?1~rKJ^ympe#4)DacP8FA{?@Qk9O!!i?)F7)vBxB({q3L(qHw!X|K0W76HV^= zP=)FBl&rKfSSe|n3vD%IqPmErTFU8wU1jxVE2(x1XdU zjJl-S+-lZ6*qWl@VQb)3Ias*W4y~x-`H$ZwquQz~iKuXQF8fACyz(R%1-`u3c@jkh z4wCh<7BYimnBzX216p?cTdjPsKIMROM|XXTu>Wz-nlTfm-+bPoqJ4?GgF0#-r{R{g z<(2Kh>&Wt+NmIZrfQ!27HT^h$YTXx%yXsIw-!-D+y(*Ua+Fv~b#{Ybjgx9nV1;t`Q z;s#6}(~&ff)DND*vGt{?wO!>dwO5BhUHXf0b_m_U?>Hvy>NAJfB|+tW0tB{^!WVuT z0Wj|8JPa!~k#B#J;X{WV5vuBG-plgNQa*rpOM5EZEGS&`y{d32^h)vQ zlJRu{k->8aTpp$PnKS()p+*XacgOE<(EIe!R9R9*jFQ?5}uv8obv3ezsjPtpbI}W`S;|yhzu-Wxnz{cdY z&efo11>4!zJQk==IUgv6iyed%Nkdj%j()&-75uCd>-IZpX7Egct!>BwCwRYC$+%JE zbI|(R<|8inSxF|I2BBy)1ZrTQ2 zpKLXo5L$=4pFr$P=({M(W1V}7m~~?NNGnW&zrCAoiLNS&6SFH;#evS11a zW~#?gn~4Jn{QPU`4Bf7aAI=vlEas{U&{wIpByp|EJn&4La8aTK+yd{mqM}0JJi|_) z=heZ#h)E8J8kOm$U4g8dMHjtI3b;M9L*KPdqFlTk$-vKP^c4SXW}-^`q|EnSG82e^{aO>z6`5$L4?0t4*U2S{^U+^UK#qNy`l`35$sSXo!V!Rq-H-h>AhBz zf834=V4=O%3J36-Ep3A7RU;D{%Zm=`u7=!6AyMssRm2f&+4UNk%GkShS**7NkX+Cd z0wUlLx8`<=VlT0&6ZNJkLA~6m&r>dHYR{OC6sDT;b)%jGiiO+I^u}?YV}4WvmKsAV zb+QOo98*LiL90|9`#~+>ssa#DkK;>0Sla&XaP7rO(w`-5V9d*XP9u>Ql|vbZ#71(v zU(|qwbeByu-SYWx-es(fe*a7?vNIs*tn;wpMhJxlb1+!{M+#3~V5T+nmd^Zm+H)QZ_zm;B*3ffLm_i-Z>eyz{-IGt%?)R4&#X6t|pa1r$Cy6)E-6U33EcM7{u z7fTHU?4Zn5DwtWlT3y7+GD;W54Cg-h!B83Bn?f-uJuzx}S^8l*|5wou*U+iHhq9~# z-ZghtZW#h*O}1zgmRO_bn(NRVnoAzY+75DuO0+>uKk<0U-;36(w}3xzW%ciUMCpii zz{*_emD4XW=BU;^MY*u@E)fcDo0V66;KIUE`YJ{(DiX zv-#2>`S@|kvm)C*lS_pWM}OJwv@y z`!krxYagyY&kz$a-Zv*wYdY)PpwlUETP!f8Uy{)DPifug%U&%jjXlowR(SR6@DbU{ z5wOm^^$ZG&zv@i0uLnal=<;&KTOz|QFe|0pDKuxPS}u2_At*VHDmO|W>z>;LS;?I~ z_{qRq8T~=};fv{|u5)?8H__+0T36cQ2myIlJuHp6$NGJynM7BpiH07DK|0JK(#7I& zH*T0_;zGSHEw`pbM^ZkCEsJ*O6tCSe*||S~0W)XO0Qdgj`#XHOMiruX8&Op3bV{-2 z^aBE@2b$wZaDIisrI#~5DUaR_j`C+;fCn`Bj^@L}qs{uK+RD@GSd91rx7a?vOh0VA<;R zRzZfw>-FP)MuoL~emT31Yr7nPr}#MzVRMKD`m(2J$M3+O4VY4x5TAg{u?zl# za2CLRHpbTVwOnu#z5RUadKbqg$f=qp0p546knFYlSF>Tv=5o<`e?~XXfNr=q_}JcP z((f;$aB4WROt0BagPeT-kKY+lIs_SHpsAg60izqiL$-^(Y5Nb|k4GU~3Xn4iN5|rq zT&kjgnU;6z+Yd2b$PG;M0n|lps&37%C7H3Puu0N zp74|I3Wb!m(}DZnE+?7M#+?d3>J+@ylx%$0Ld()JRW7Ao+-Xnv=Un`&_DWlsvBTt$ zA1QX*RGV+q>)#(WGW4vrGyB59L>!ZO_Bhf^@%-6(gkB&dQsWCTM@e4Z&Pj2YB55)msLBPaI zAtwdty1ASXih|U42IUQ^xKnXpeQ!lmM8uoiT$34RK)xdc_>@<78qkj#xvyWxI`Fe{ z2q@gVe8W~ac^K0}HA?(0>lMLLv%l2DSf!7Rmw<7c#XLc_2q)mX>+DSYj{MopqjOp5 zz5YCD;ycfBaq{pBVyR9qkeLOvLLdTI82(V{hLm3hd4Gw|UiwSPMe87UZM_@|?x5q+ zR(A~uOKkd}S~PQT{z|OuLA7{p+3{|g0aHZ_lDnFB|Mm|}Njj9@o>jD&+g2*Vd7p?C zvUcMOm3BjEguiZi3<@|qjW6PuTv*RjxU~z{7sQoiY^QYJ$kPJYK-$;PF{-a5zl;7|y*(kP8f#H$iL17pfbql+=oFDMj}#(I!iF^%x<3BC z!f_^`)aO`Ix06Qa=mtT2Qb_?1zz`8yLww)G`QP*Y|9_ZB{J*JZIBWY8N|*x}jybux z6CaZuk^yh~IeNf|f94On5EZ+$y+_Z zKVPCpj|e>JV?-CRQ=PO}pnI~p5UW~Z#HF@<{*jajAI_BeWo`OBr3qTC^W^$@0}urB zcltA?%p#x#z{g^ap2izZPdH{zUHcO@R(V3h${>FsmGZ-J?y~X4G2nu6Ouaw>SU5ZS zmAaQ#P8A-D)-hpeO&^B3Xl2BxidCRJ)e>Ivi5C65w7A#DUzR2~EEBQ<-gN}e&lYDe zT4`P)WRuFz-qB7I8?DFU+3po#Kq3H3POj!3utDso$*R$OmBfj}<0zw_>Xlt9QDUP@ zaki1+91a!WTl%rmfN}kI=;1_wNjGju_ddzP+t^<#=HSwXPZcEF$7pzu9Ul zRE-w=SxoLo#9Jlv^WMt3aW!hC}H%`gqOK}YgP@WlvuGco6a1?LxNFR~k6*snCBI5|l54WzAZc_p+^Y5# zt81t^@$PG~9pm+X2EoIYk+b_{Wb-dyV&!`M7&50?_Qk z@5e0SrN!?Y)?V^~y^0o)mZJCOoE4wS2Z(9q)3zf@OH1P!l#KfUX>W5e(&m%}rzcaQ zUlX4V&|W~>#Mm2u`VLFn{;(i;4vCo^<*_adwIiqk-f`r$?k_UaGnOA(5tcDOxg!MM z7HGHCPgB3)HkZVVf?NCCI<%kt`Jy~ueLnN%+qZA)<=whx3|hX8et?(#Fuw7?OUr3* zo+%_`Q>EvrHsRG}f`*;be{Z~N3TT5%;-yg{x~DZy+8{ME+fZ7zCXh1dTi_rOSUnuR zbbaxM@mCoJQ=vH^n+_iQdw1Oh(lco<8|9!`_9zhAEkp|Ijv(WaV5tJA-*(x$uc_zT z9OA285y?BkxkW`<Vuj0BG`n8V(e^t80>)Quli(&megOK% zB0enI6HJACv)SuZ?;YxOww59lrm4RUz$173QrkhPAZ;s?*wt7QDJ!a1E;Lsd_=+xb z{X&2|O4u{VvrZiIH&)pqQ1J4isV80_0B`Q7{LP2gW7dA#(?9 zCAIYxnBN{?+rMMf2ml)dYPYoo8yuj&7nAxF|2qShU+ndqXV9nbJz1k;?*Cv54`X-U zdux2#LZ&J3xoiQ)jXo_b;IcdViaY%H8;18V9>vvot^bqwWatc*0!S3K1cUak3}o783fqU59DFCHvSq< zPb)p;PpkJg;9b4rCHQ)MY1p%aP*U} zm7w->7Hxg^5)u-(De1-U(}O(XAOolvj+uwNe6b+F+Y(2z^M>`R52W7uH@u5y)6MFx zm8yHsQMm>%#FO?#+O@s#^p;a9go9AtH>EWkwU&c4=2Ph&db7IedpJ57Jt8L_QI>lO z1wBWA$%S#@OY1z)u#xjOf;xRnjE*F#6bLrD+7Gn~;@w+L`lqn3lBy-SIDFvsp{%U0 zX1+8o*1yj~Fc{-#ngDCn!4*)!U^Y8DtMQ~OEF9a1(fb0$D$b|oiPjwg=-zHYXl7JEiQ+4M5=Dj=2aryhyNl3cIjdB5rz!IzTYrrC)eoZrF zDq*y#orOl(ILU?a_1Li%47g9fHy*gjS^eIJB=Xt&3V1Cx(L9xW5vyk)ez^|73Cmf^i)7q$!%sozB)pTpAKPDP7C<&u#>vp$@{f+1(69}2v7@I4ooX%qV`>f8(B4l9&{R^Q(mj7ubWGtn zKewi~k@$P*X-wH{BE3j{f7+nliyCu#4E`)-n*#O=HrP}K;fU8W$1~9gluDnfR~jwh zv-DZB3F+ZF;S;s^x3;I6z3|w6K|tJT*4k=K1A)j$)RdGA!IC<-9@fZ&_Aw(OQwo4Gq2^Fckf8yY0j@|cU z8eRaWhmVUTwqUkCfhlw2#kV(IL|MbBQ*3=j+|NZuCt^Fh==!VbnK++7U%VV_u9EPD z^cTCN0Zycl{lrr>88_pIE(7%O6blE!5R@wx z=q?ZHG5id@_l@O4(HBwMd_-V6C*{^n#$r|%;~t|L@gycHDp?FoVQpQrt7;ynOW%jnZBdz=oUPBeNG*~sAg9^*q`sNIaIy>m}sgI$7UMVD%qQ^?I zjh7U*kxVO(_UH^cx{AjwM&PiIcG}@}k#z@3;!q&deZxx#!htKCFnP_x zwdD0g+#Fzsdkw`o!o=(CLh39XITW&yqZ>mB6qhmWWZ-+1%pCB?NP7bVP$9-R{{NK` z{!f&}c8x+|&gC+U$;8=3`OO^}^N5|$@G-;Tn5Rn00KhcT1%f$=RcBACIq_#tsmYir zrQ&vmUW`8#nW8@NRY|g^5YtpFJ}j;=X?AMFcQ`iS(r0cf0gE!N@k~xD$bcYgjNPB1 zTWrpzn$PuRfseCo?9kv4cBj#uZ;I0}xCqyi5uKw`=0m(@DtNch+;9DQLbW%kilah^DJ^SbEvXggSLVIb zs5w(gG2@TTb|gdfn?!=!SqybAymrjkKPP8xDkpYV8ofoVm4{ZbA?11}Xz(D}^ytRD z#wJs1emhTg8e!<+?QIaxobz>fu%E;As^e0>_lu$LU7=cE#Y?>C5ygm+Oo!|38iuh$ z2gOiN%NO40%M%-@yEyV!kn1{6=fWzrf3wLERq45*gzLM}jq5}I0`O9jEtVFFt5gX9 zz`~LNuEBHr0@_VZT8sD@kjwr?4`G84Z17fZB#F7e&~hJ-xYmzH5>tD;lF-pK2-j5!OSz% z8i1rDO)WY&t@LBAC6BkAXms*lU-hV}r#pQjnVIw8|H*Q`r1~v}gsa3TK ztT{J0@G{RxB^*^Mj_z!Qx}`Qq(N4Z_VvQL*wj3suoMY5p)J==c=9foneJ(Pa%1#@- z**9V4NpZfKQH=Jkp5Wx}N!i$K@wVwJ*p4MW5zuop{afJ&IB=pa0 z*5W1cX2(%qrq+a3-&_xJY`RRPtg_f+Px#)G`(>X{ZhM1_gKfxwdWtXt}rn&#qToKF8&XK6qE#R^6HQy9kln;_PYai~rIY7yTF{js{PB za2khQUti=WVQ04VfUrP3EB7YGw{*0nT2yu=tE_!l8U36s+vp`-w;MvI4!3HJn>~*v zCpV3QC3X+nH-{<{53@j)xY6*~R8KlgtXI~D^Ert3E`tGW=rK~0t}i`dRnaM!vz6~V zPeee@!{ZKLSK%BnmY3h!|CD+YASC#+5mW+WK(YqO^seAF?uBmhs>?7n2A?8J`|On^MU5W%=}F|M+lE zi$yXs1^L{hzOJ&mQ(>iy02AU*7v+bJtIOPFnPTS8q0h0d739^Kai5#MjKU7*?s^r) zo%vS&LBJ+AzO|YsHT6dW@%Yx@#41wQx{6-WuUEOFVtj84qFywckZC}J-z~vjF>H89 z-|7mOn36Jc+w`ryz`d*8SDLV6=D9}8P95bG;X!&1M+v`Sa~_;@nB!PIuRAOFVre@1 zuPbid9eo*7?>U~D>d#4z2T4*C%b9@aAI1^>2_HJ&zTEtH%GpA%#GQRjN9E&g|3mp1 z0r4(IJIZmZqdUg(D>T&}b^E>RZP+vBEqg*)vY5YX;M^`GFE;>bWKyjnMnW&3zpWLaY{pW^LU*g|nwVTNxIGA{h62s04AFtzYR30Zj3KcIXB9m%63TLvG5qED zs;3_Ma!ZoiNmbxm$>0|6CH;lK)}PA*@37d10-E5-#L9-B7f*}{NtyLX(L|q-j2k#S z-a|sqZ%fjkbqgKl?Rd{S?;~;TWy9W5f>k*;%91|l+TTm_{F@-he}dP$omaC=1u9(vseA!KIJx_I)J+OzsgN7Kl7n%ZNO zr9&7Hl;wJ{!s?8)cn9&FL2f^;@)y6Y`W*wxSvx&l3`5n(sfPEbTx6d%5yG5Y(UfEt z@#1jJOV;lsVMITDJ8jGGfH*=B9rgp;Rc5@nk%1FPlVm8@<@fz6F5gAQ-ogw%v*%pT zqPM!JRhyNuUj*Hk+4%s*(6Q?27~Dcz8zVP6CHvX02EG|t&t);^9!;j0UAr8Fi=HtN zAD2-I1%Rhao@3(K@`{+sd+Y&fqS_IqbINA9tbAS@(qz@93rUekVT546dkbKzAVa}A zpU_bEkdJHQK>Zx}vke+pZS^;V%;8rV4je@xer;>%aUZhvY;`m^5BvlEq8n2WomF;|-hRr;S>+;@9DWSYkoK#O*&x=5W)#VUk=ZgJ z_D%-Z-9oj(k7SqO^SAs|2;M@jA+*A|2$h0D8PKUYqoW;W*V!HiuTVFYW(#g--X0OlC8 z5RBj%*4FAE693(RaCir&yTv0d^9Su1(@xukU@`jQmNQv$LPptn4pm(4>~#CXU7!N= z|7!2Mqv7iRb)}Ms7Ksw=MG&u+7~Lo#Btnp;m*_;VV~mo-AZmgrqYR0bM2+4BQO6iT zj5az$FoVHh40q@Ko%_dK>)yNWT6f)Z&RX~E|90Qs{yd-ZY&xYe*H5o|_Rf5u#YRPo zIQJ?Gz&T)=+&`LRf#Oxz@~O>z)g6$GIPB>}d zOvS##=S<8hW=g(nA^%_<(GI8f9f1Wu&9n+*k9z`?9=z*Yf=={J_&Ad?YJ^b#p|baz16=K@!moV$jZHx z=rE!5$I-U|KvmCvt)&%*h4`9wXnl z^1lfu``yguF-bNliMRVJW;O>WmAu%ory$<76(Iy~8<*8B6uH-jEBqF9VLOS1E6x-8 zW+K7_6m{`hmAXxK``5cCV;cVSA6O4|AV@jgZ}&UUwM#>RE4HFaB%kZt%qg6;(HySa$E;5rL*g3-;8-46n`BF&0~w^9h|b zW^*UDXu$>k4{RnYuMv%&u#)X_CWWs^8gOq(lj#aul^kwshu6Ie+!X;5hEblGl(;>_ z9bSLBa+(FtagcG&8S&T(sm%5klgt3^bw)BLD`d;fW;m^70B%vLpiPHTz6DQzbmPf~ zvELg*V;w1%ZJgB4MJ>~%x%vPzDQkY$oz@$E*5e|mzrJ_4m)?cf7|$54%YN%-_d3^M zW= zn6rn@X0NN8?bEO8{N?QvZBIPeI|k39XjwyVYrjQQ?_UCxb%ss31>qcD9+a2A@nwM8&{JY0&p1jIn5M*}p-IK~dn{6X$l4YOoeWL)G|xvcwxG_hOfs;>H7Zc&@I zPuGdrelQTZ5$pjx?kd2dx^;bSxSG+WtDP-DXT)aLy#l0i{G<}DY79C5xIK%prPF;c z00{J8g@NoZdOBkpyV50@XX|WkIFJtE(re7`?>1O0LcCPQ6S>FA*50_+u)oTQ4)4B}@_Z8Ff4S|ljos5^`z1DnhS4~L1&Ha+K0A3f z{`J@aYujc1&t;{_yIC6gS%AFMg8bGzo3rkt(y&y$zy%2Z`Q;Q@rJ97t?KvY}9$?E`h&0L}D&n@Lys!(v|(Xn5;+E$52 zeyI4{K35q4B8xgx`pQvVIhTJZsVrYNf?55iZok;xn=PHJj-<<9%D#+zDL>F-1U|&+ z93TnxjMM#=c&Xt(w={O2ois$OeuH{?qst693N( z9k!pplqPq4x(buwH|9BDnL2)Bds5NBx1Gr>j5J6o_+vb3L^lZ?xg9@;RxxUEr&+c~ zZT#fJ0u@B4|UBg1}CU)ajuJ@0950QSk0M>b^KVp4X+d!ops&+$c>AC51iErC| zSAoz1oITB9LB2x+<~1z`_VLrFt~)O8pZQ7_2XhLye(FfUy7-;|{!_AdZgq(T;D}q3 zbqTRw3fv^;f3AO4SxK6n8iN+=ah@5B4mQ01S&ZJo9Pl?|V^gy;%h_V23}?pS_KNIj z`BG^jMj<~$tcKRLr~;=?d@(yau`;vp{A()ggm8ZxqHr2XzOaz`0#3+k2(TtMYwI>+CY-}YkP^bE$vJzIMJ6+QG(#S-|0;xo1nYY?o61+FWnlbnpd`w>YZ);Uc=pqt(my&#s@}axU#*ACHRBghCmgj87F0h zv7j{8M=J9TqOODznk-C^wtA?|x5i6nX6}OR6b6IB3{Q2~hj%k7(aJ8r%v~{&dxV3p zPYpeO&=LcnS_Lf4H$!N>7)L?K*w>v!4**YpDvH&5lUbe9i};gsx7nC&Oj*TkS8t+O zaQs8TkOW+7C9L|K!pw;WKf@%~()vW?0{12S(*b{>`YH8TR7>&No{)5nbK9}YG0lWI zr-)E|+5YE!+i>`E5!6@=D9I4=1*c?{EV;%Ybk!{7mWZo#e*L$H3D1gj?%G9ce0?j+ zuf6DX{P8QPvf;S;=9py=mP=C3g_rA5uzk%Jd~7x`zg8QNo#U-fSr6#lku|UJ-cWN( zYVz4WdxiJTBQAYq+KzV_$fGN!)xmi{uz;asrj-!yLvSt-oiN0UT}a7vIH;efbX=4q zhsV!QmrQjX_B&`0N=^+|WX5js>VZE9qC2BVQYN)l)(7!ZZ|v88mj+FLOLmgo1WehZ z*?XJmra}6zXuq7+B^P`-2oes<6^Vh?X z>uf3g*h267iV}_k)-Jzy(_vF*{lg=}W|I7+J-3x4_!ela1V*W=I`sCf6Yqk$Y6MgR z!}3#k*4V`@J#YL9nrQURnSo8SFGb7H#ET?k+m^uy3pHkSV~XPX$OPHFT9Y6K4!izJ zBdrSzvSkeM-ArO~YlpQLB74@ov0%vrqCDu2EFb^*gWd444c1o)at!dv5B%jtGh@4s1;)i1r;W zK6Q5IDE|6#7n%*ke2jsRFqyIdAY96o&=rgT`+ga-QzMDzfoXUynb3pKzEO>D970CH zBhI5+Zr_#98A9k&J%)~64ejzs-^~#mCB60bjdPY5r9|V|jp&hewme%|SBNG+MPC7e5%-3YA{|7$Kh z(!d{k>Blv)+K68@&F|~BZm;Do+R}TS5YfI0(_p5i@Xl&RL#fYvrCd+>#+rsEt6s0a zEY-goIC@Ef3F!hB`D~Yew}%UJ5&1<2l-Ao$M}!O-EBhTBxTx^%skS$tquXZ`Jr7y? zjXnyElO=*@{B`MmI-)_Ca|=It&3Hup9<*{Pqq3aBt!N1%N>a=eofXawmFmfa#Uk6? z^!?^y*M9xpcy{4FV%J_u&+tlL-{h4qZeNqxL8-l`!tauuq}jgI)Hm;bE<8QOyh{pG zQ!@+AkkN=-rtQ}k3}*fbd*akzCA?{%cg!O?vJ_o?xT8Ml)*#{V^*E$M{_mhdm_+za zEvii@{zIB{T0dssRLV&_<)X_3bcZ(dx`xcnGhAmK_Kvd64g*(z-palICQW2_h~-f% zJDq$xL8*fwlICWS{iKc3*r&}xTZH9&q_AlL^7U3@}OjcZtc{|y-NLcUaau6qHoe< z!ew1)=<%DkCUdPH+tsPpGP@a<;j(m-L5y4APr(%&G)j(vk`nFr7u7n!#J#<;ov9oK zdYK&{y8R<#0HXUwkF0FN?{nl!m@h>&m&QCN1Q&}=z4~fA#c9BNpM9IzjY4TOuR0%p zZ$!iFTV3qGF%cQyayScXv!L2tUYRi}vc0lX1%BH!_i-K4)WX%71R8yTR0f9yGTJDT zd1dq$GL(Y@RWAn1PgoiRMjG8m z8;-DOHqFyx0_ZS2ljV3CVIKc3qRF(z~9Zb>cBHdyA7VmhC57iU;NCI60o_VaJo zuP$uggkEmH=DChvdbda^_NPnweR-)|&x+5!+}pt;aFouit+`aVO$oh}TF>t_0_Hjk_Nw0w zyraTrQ8E4Y(f7#gBY7+P`ap3b1QN&{0F=g5dLoCuFW!w({*(u}b4@nJL)0ZMzf}qP z#2iLnpAN+0(eT#RP=Hj8P*^sPXB;Nnp>FjNIUrCGT6xT->pi-zHH2{U&%X|Z))AyBd8 z=*p)FB@e&mJo3|QMUSh4;Xq}unI@3G85TW`%o1GOdOmtOcX^fJvb1hROAq%xb4 zKLTQ?5&JLT>y{T*OVG09GuW*ZXyJ=!ljVEi(N0_%Z}AfntN_NRF%6zl8s!pKELK(77J?(~;9DB=hdu9g+dPH8Y?+ejDK8ZB^tU}c zCOB=CQobCueiZ+lw%=MDz#j|_L4tF(!_RZLve@W*rynD}9Sx2;egTrYz5UtFz_+AW zFY2JRurRAp6CpKawI@b0=I?V22#$wCbauEd?FKRbMlhmPUG776(m>>snu|>@KP6a4 z45@0<#a@hOxN%0t$a!OEG1C0U?@Q1(T(4*^NX7H)E)D$!t#pA^Gzz`4q_g3)0Hkig zXQ7s>`OKd*Uv-})yl9R~EjTj?&}_VVgBS7)nvE}L(aSh!EE~04WA!G^f0%_Ip29$H zgBlDetn$&|lBc5^d_5y&k;*0kACkGkRw3}7Y5EiL4Ebd0XI1q#a@_rQSdZ=T2xbD8 zNjvg;e-#9-?utD#`Eo;21dhbC7jE92WFehj*34r9-dgc>o7=<=JJtd>AFm1>s^}D) zyHtjIO82gV1TYb7Y6Ol%^zF>{*)2!JbrH56u1MGH14ZTFJ3c&oT-h|d z{Oeo@srEDTn>XDLIn6mrBuCnG543~u9>d<9Wx2W$L(58>>!IUCXz%#8`WsoP>~NiP zfhH5SE(K5!T)-XwV0cB}1St2UxUT2j7-WN!7 z2MKrme(v&}?wU@sN(-MdKZeOnWq)BKO9!u!55^WgigwdKfB|YWN^A9!K8|!(-SEC| zn8~{A6w_g?Fx)Hex1Pc~${X#o@!~h;-*(P0B;$Ua-2fy?obp_n#l7e()_EEjD?CuV zH67xAX#-hG9L5@&zbBmSf-fzC088=P)1MVVml=N3#T##hVh_rcXYNzK%QiMn;OPHS z2xOd(jMQ42$jwVA(dOE?bjeukik&J)@kKyaWR$f#TSWw7>ag*axdZfuG3$972Pu56 zy=FDqfyIpQ+-qo5tv?EKHu_m`g@O<6;a=r{kKEfa{~`!nA&%fz(op+w~%^Cvk_i%Qs`LknAH;q%0yWND+OA7vJgy2H3n+d*!G7e98Rg zlL7-{uo$7v5L25KnqbCAOg^2U7&_}kV(E0&&BTvAt#t2H=8fsOk8>n72QtG}K~H;( z76+;ZiLL4l2DM9}!K0UOm(Cs%L!JM|K3IX;dy1lzE&e*Zim%sA;B#;mfq7EzQi2a? zVWv4mq|?LOJ(g_G;S(d6?XQda;8MyHJUud5q*9~LYm#x3k`|9RCM@m820J%FWREYP zE~|)jUD0$b2-+?%_AfVx><8ssDRzQJV!m1olX}O3XQoQ>EAMAxTdXG>q~vpog7rxa z=F|AUG-FMX&8H2X39`!&>ce1ft#q5BV5UmFu;zdYZk?56eu9P12Rl<}h_pbGO4j^! zo0!{OX;`@kpI)2${#24$H(+tRwOc-QxWchi z$}~HLlYa;M-D2$L6z!xLa-{uZ=Y~1UitdLLubkk+DuJBV3eFpS69%T+5)V~_p-(}o z*;15UrU2uz%~aj~JLX0sb;6|ifvDOv(CASIdID-{x*RHx3pTIQSSKs^-0*I-pz^-7 zS{f+k%jk;|vwjoI`LyJ)V`-EW{JnB#)u4T_KkO)G2``d8<8G>Lq%eC-c-I77icL~M zUcoPGrrLa(pU<)~y2Y8=&t8y5u|HNL^^y824cbNpIvpnH2iDVUI!ay@@jcyGR;9Wo z;Xg=eg~i=2?_#-6ZKez_#byd%yraPQ5}GQ3EXg7ZCj}6x|KVaa^j(_7Y+l$t%42z4 z!nFyX4tg8q(DlIqEh9SHI|ftBN?GPo4KJ;$$0sJ=th|aLN}DBOG-rx}g{uTm>?&=j zekYxr@GIsH=?!5CBi18v&-Bz<<)~GO%P2su0V3GP`(OqI4mh=1*?tnx`2=oSn{_5@ zO`7N?b5H+a|0Sjd6|TeynyJ!k1CMtb4E7hMm}0f}Klre{w2p)3?7JFgjg*I>e0adb z16Zq?V)uvnDxS$DQYKceh!7TlIaj!nJUrWkySxu&Cwd9kGZTvg@BQVn><*OEvGQCQ)b&h%?XZqt3#wePut%iU zzI4}Alin|HoS$<8+Up71BI5*qTMgUd~iHkWa#_|}!@#vu)2SgS}4 zwSdk!U&s$je1OOTcx55GaULr*t;Av3tF3vtSlPld0i4qIofLb^y>q(jDcQ+xt-uN2!tbQ6(K$sD> zV!-LK`90G+62BoM%dv^eH)ejLe9>v*nklAdmIsEoe_+N|Klzbf8cWi1?F{aSuhm$O zSMCz`wssiI$3u!x#H0C5n?qbjD%9qv$8>Tn&1eSIB@t%ym0F+?jyZYrE~iQ2Wy8({ z$_ux}S%MPCi7GfG=%*0}cUdKOS}aHLHw$yblQHNH-tyUA)6sR=5?Bb)@?gE`Gp2jN zYDB0{nu*VRUBXS}!(PXy!W_x+Fu5CPMyYl-Vfg|ilhO5WGPA!vSnK=swY69*LP(tu zd8T)VJCRqa99u)6`)p$jD7%PjHm!7=9;mfpwM+=wTu8C=wz=0tKjCCyu!p=+Yf+_@ zUImI$dq1%=;Qv6h&tkmglf$Z1kBIMC{RA5adha9N3t~pra8Sy}<&AiToK@0;+KMV| zo7&R%z%rvfXoh;|?@}9VBq!QfHP}$0Oq0W(er1g@ZPrgw4q-EXrA=aEDS9F`YJl0H z3^nlZpw7wq_M(bcH-5ucDyz{dKsW*H=oR=^XLH!!l|3Kg%jR_-ypRK)eg4(`zqRPp zU1FGD4PWD@DG=45dH57g^P!OL%&kW(XALt1&gaVfJ6>R9!eX^ISBfr^=bLS&W|YfH zweHZPN2Dljq)}Z68w<;t5Lx_)TeMG)e6* z0fEXNzy%GCZ7bEVayQ&N=8PEjLrjxymxXallxtw!ZJ7)vS)U6GixeH-Ha&Vj;hk z9H+a@;E;iaa_IhYQ-XN&+qb<6NeK-tn;G7~j6djJ)#V=*FJArUaFxT9?4nGq0GN2P zp4ry8nkPsvE+8O12>uFO%$S%^N>|q~zm*tqorMJv?=}@MSRYqF$Cpm=A`PHa@HbbuZuV+Q+wVKP3D)Is6zdAn-&f#_--fUZ`R@ z`p&v+GHr7U;^0U*Bbrs7Bim6AxIzq88)O6eMp?h_$qvn5IUvg=ds5OIccS0D6y_tR zg@eCPiF?Q?y{yLV)m;>))~!lue6vJmpS)@TV)`f|ugyHQnv{8fb434WFi$wqx92|W zQ$jD1PCg=nH>_on4Gz~Gcdi>a3tJx@IPT<}zVw=MMULxb)%LAYQw3uT?Xwi;+|f&! z$jTQpJJkWY`-@%Z!t@C~8r7&_)N!E%of$n_%Vj-l+JZPHLoYO}g(b{D6hF~vbt5dT2HMUfV{!nCIZd_z>8vU)hR-Oi z{uPjM$@|7H8r<>Nft&!0{1p$%I4UE0WVY=^r4Z6(aN6zmvtOx{AEzZM^`#OceOOg* zuUTS?s~_jRR3YmS)EtG>DDv(^QqeuRy?dE;@)Ot%{c~2z?%Ky*g%Ng}{o^O;^a1|=RqEJ^vPtGWfd{t8rJ*b ze)z^wpobdT^u7gE`~ApHoZd|~%q68A`I~~2Kdt4lQcd?bt&1Nl!Z2aE#mQd{the?t z%|TuiT5FjgzC?#UD^Kp=Lh0e#$4yI+O()8-0msI5-sYoKV%nWQ-N#gqWrbsYY4POK zRC0!bQ*1l0UB8smkCwTdj6P#EZ!e$kBfL1hU|3C=c++Am!n)~AdWJy)buXf^!Y*M# zFqoQ5d!cS>9iQg0zoieIec@T26Oe~zD4fDepntH>$|y)4P-QQoum+?QsQDU~T3CC} z;cs)=x^ha^PX}g%%OnxCgkNzNFWW9@XFl-?J#2N{ad^jfZT@v}!k`@|Fe z%O4`0BusA6w%QrKDF(Y6>f@`mYRH+iBh8^RLqojbA5nb}HD9l8N7&R-WcW_TG0{ac ztJ8(N)tGFbBs)pr1>YLGP}s*=P^@ZqyZoBh$s^>!XGZ}M@~%_lAeU~uonYg!YTEG2m;Y2B*I zJ{h-eyHi`eCeM)u`qPAKvA6ri+|6I$5UGlfg?m;Kc>gZv4x7rA7%;Al*!$E|DwE&0Z`vU%EvZJ_m&b)>Lup%t>XNRKC zW?6cpPk+JXSyOkfg#p%!X)1b;!iK(v+xA~NPwkV4avmKmXXRvnTp*!9s?J0NN$?XjXOTHcksjpHw7+UK=Cgtu?GoDAP5V2S+u6W&&$p5&xIol|Fr)7pfk zb$2^F{#%acZ4OJ$lNJ??#QQHC4dJZjtuG93@@0|nm?uigEw)~#WpsF^5dGHELsHwZ zu97fhBPe_^4s+a8_M>si2hkmb;hYX5o!*!pBYX+yIp_OmtZqiJUP3I}AE{zeW>K3s z<)hdg%cq=9cn>Wqse@(V+!2J{j~|T^5sr^x@EF4-gWDj{4sO1IA?HDEw2p+-aZ$UK zb)?IfFQ5IUM`Ul(@xMrd5B^CQuNtZ-@v{0<~ANPbCiheH$_Zp@Wc zpWJ4h@o9FQfpmHl*Sll?SS#IraZ86@Q8j&B@S3SklC;?{XKqxRQw5}Mzlxnh+S1mi zp-Yz!yLlLY?4e*9DI{^ftpsFxF;Pe;%#D&wDs!=%1QVoIm}aG%fB`G0csTM>(G_%B z%)}W3-r~s{5tmeK-8qz(V^y>C+=U3d%g?HQ3~KmApV`NqXJv~7am;g!@KqSY1>P;~ zhRu|qe+Xl&4|1NdCN9SaT!Y@kr*Zk8D!*b?3nVAKQ;g}A)?$fy`(W*V2Q8rYuFnt3 z^C(xo`U89rei#J+4ly-vRwrJ#1|TFfw;yG#)4y7;`w6@U7xJ_BY|PuY1CGNgi?;z} zbn;O-^Ay%zD@ZR2KrAjDd_Jt(20%Mrpdu*xIVDc~^B)|vv}YVrv;Ge{>c)C1mmmeI|^6W@G*k_3Gf8pVF~409*~EfR0j;NI$lEU@l><|FqECHlEbE2Xw!PSHy4bh zJKUGgBf#05f{_{zTIzcX6yfGt(!1F}KdeNRjZw_)mD*Ftc(#-Lsec!8pHb_ceYXze z*lCJi&8_KXwzRopDIJVF0L?w@v&731TlU|tcuG!&E=2=%p@+$vDhnjm%&s*G@<>lP zw$K%!y58Y&VV1rC<&(2+-ph9+o9i?G3si4WY6ZLfKOPU8ebl0(c_;IK&j`fw>F~AC zz`?AQ*HOG41lZh1IVL&sj1 zzAJ;9$RAs*tUyES3=6G&n2;9Ja+U&MCQ#M=Zks#_Ep(tV<>T}BfFp^11NA`V<8Lrt zXGt{GQxdiW>Dx(k(DFWe1H7wA2OBps9^(c4c}S36>|dQB4mBQg8yj*(>YrY4GaDpn zC#KPJ5vW})p+7so3{uZ+_23UE9;nyP;M8SlwAZ+I&&ZFLcf`Bn+cg_WA8xCEF!MmY z~et7?X)#XcM8YnZA%qc=M>?UM7#M2iO!W5_1R*BznEpt~ro@mLC z3SCsjxq^;iES&dP`X45<>Z`Os7mtXZGZiz(&1)^0vaX>onjG;`d_xv~UB3j$rlvlN z5_OO+NT)>IBiueER?5?AE1@QXL2V~`1@QKBHN1O!! z5e{K#C3h-IR4lYrQHh(7*(R}wcZ8#^L<%mb#}XZ1H#0LGidCVXMpA@2JHN&@hA42R zqJv4qEh3?jd~#vM8?_0MmB$6#_azIgK(Q)hd3jvWeP7ZhBmwNPLMreKt%HSHgIC{w zIb>v?=Yim+Bn(b?kYPFIRot60^kRc2P<$IHt5UpkWXT)!2syhu1qun9jX(p&PA?L; z32W=j8ykdU_iySQ*8Wp}09f+b@eIXMJ$^l^MgHAfd=eN^wcbiAN1XVbhgO!y6`De( zcrwm0QN76&`zV#xQMU?QPv*$r5p^`UtnIMYadA@(=hnFBlu=yXVq?#lwC>SZbJ+2k zR^Byi%MJ&W&A63HU0Io0VedJarP|bGnXcf-%AcX+)G66w&sKNiabxScx!|zSNltWX z&ap++k>iw{tJ~qcV^2UsXjtDej_7mjo0$#qG@5u3Tedq>e^Q8!41FTgP z4I`jP;Hty#B9JvC{&!~B=ZVIU=93z0Bw5p5=P|r;*xp+!(AHeolBM-D+!AUp<(2JT z>uI$+=-+rf_~G0pm*=lXRYVBmCZXzn(}I5D2K0L!U~2OTe5{Pt<~y{P&zX1VUG!+C z7BwEaoot_a1WXaR&`pymL81DJyInhLE#&nTYQL zA3=V2i^xe?x#L!z6DK}rI#y)|cvuae92f4%ug4Gun~1IfhreH=n`#dXA+wNbt+o*> zYY)kW9j2#R>G<@;0=}aSE6WL{$anHC^psS>ol5yeee*Gdq|jlaW$RG0V<}ly%6hQ{ z?cJu-lDRU;<>@lh+`fVfv93I7M5AV@Gmd%hLVfI|8gmGxT<#N_6U()B`bW=69RZ3n z!!u)ionXQTYY1w8O==TM4L<(T=3>=&6om5$4ag~%<(qOR61=6Sr`=F?xlp12!)Vm(e#T+4YOt+7+at=OU@C3!LYn0SPEBn4_;@`4 zBPg_sEL9!8?&N{mMPTF^Rcx2GDNy@X<;@1nXodAY7&N<4y4RT>!s0<)!xb9MIh~wz z5Ndx-s(ezOeA95UV%}s6>uQpB)>mDG;AA+JaOC%zO>3%^>+FS*PslE01z+=hFvVdl zcFV!FWY)s(aPHp6YkL&H_Bb7S+?+)D4Y^37jIy^W$>t;Q$Tt)DxT${kkama0E1fe# zglJqS9zZlAuyWDcf+!Q_{#6%FGy>t_P}5RdgU3qfk7hJM|f-n;F_Hj!Haiaoi+7;wdt> zU@4m=@EfSHktfQ7Tbih}_o*eBo{@@GZfeTQ)$Q92l64RmW1meK9)j!?^_6D;X(EqWm*e<9 zRKZvohp)IOOm!k}!XphMKdX8yLeHJ2Yr}&h#4n9o>_3x!mVUNBMt+Ta6{MGu({@7b z%&d~EuQ!J}wRXN!QE5}44mjf616B*sLspTLqr?5qh!7UupaJivWL=h}T5M^Rw=rC? zEG-8z>6(++6NqgF*;Lgba@dXGolfzDO5$tW<}9V}8_qQ;J|gsxEfuV74WB69lotkm z$YVmNBc+i&2OGAA2`YzOYi+>#)zH#tv;M(tC1vqFHN@vCri>Dj2lY3vF1PUQT-n=n zO?Am9-VJK!Yv0xGB>%x8Gw&K_c>;E~1xf3^GeT()v8}q=WuN2n&=Jci$gdiCnQ{}~iYGZbEWG{; zQcXFa^Ge4GoULeI>LPtNy6m`khA7E?y&J7w>i2uESSFVtG+S^2zb zCMsYyH`pPZS^4EqB7(qW~Rn+PT*i8by}cj{W@pTI#OYWGrw zV+@Tl2J-31M@Mx{DXVp%yUAaso;;DV@NZWExCsiWyVBI({IMNSD35Sx(_~yHoF1NI zLN)?F0;FK7>8j*YKK5m;A*6p7q4+NL`m7A}pOm0m=}4YxxZ!IygJT1nX{N2$e(mCu zD7)lL9Ts8bFqcyg3|ORhsbs7fIdLm+&y368sdZ&L)R%CGtA>`92Vo*{Grn>+j-b03 zmmrqGT`IF_#w`s~7wKeyflC~weJeLJvh~*A>kkj^WWlNFf9>hZP41s|=-y|lNQQjR{qR_SHVXKk`y@)(0 zvf+GQo2NcoU&vD>MXLZ{jhB4RvVyk@-7Y5FnW^2T&0y81KJs;Ff@Ccga6SPLP?VpL z+=##cEU~B8XTRsJZ=|baUhk&oRA4c|K6e_4ZJZKwPn)M~N;`ON_?MZ#m31qD9Y z*MX%m1IkXJD+VpgwXrMN&XqD+=~L47QCk{Gmu9MX9OSAYyLA!WzyClA4#kx)ypEK=I$|CZO-Wv=Ek7 zt+S-}4ipO~`S9p!VA^k2dviM(SV3L>pfH{N4MwGnUXSH^8Q3Mx!hspB!H3|3p8F6d zzmw`oe{v{MJey0aQLN}MSt&OeJKh-A!vlgsKB>SX^faiX? zK}_QxolbSgu(D{-n-9}hXqX_m&i+nlpzg#~Y4d^e+x_|Bfo`yUx32cS*8)%)fT*VO(O4IGgCz4fpCmAJKo7jdO@ zizl>vH%v_c`r!R4;T&KSpysct}KzdqWA9E*GiY^3Ks%2Fp_=)ARp75 z*bBRzjsSzD{|`s{{}pq{olLRz3bky&N=IRIef^<40|Sf_I~!B=U1LkO?9Pvx1Zc5A|kq{{6=1z zi0E1e5fSkk=`G-lS`|Tph{!lvSzcE6+3LkevK?(8zbNM2U13qoT_%-fmM_sa-mt9vs68Yc`ImFHd}U!7 z<011v!!z!9L4iMm(rtf)CYJrG509niuM-i;1OeYe9snO8;OLng@I{`Ki0BjPH6o%1 zjKC4ojsKZOZIrC~VPWB{dtbS&U^7V^nxgp;JC%PoYH0m?x`9m&L2eUPLOS=^hbLTUaEUURROhMmcHR zsDK)V&F>2l(Lcx-&qlIUpU{zZ(CN*uZp^~UHSRQYz?{Qn>2fQyFk|ANf;`)l&=_E3 z;qqp=gT)3+V~LtP27)ziuYke-r!&ffYHC^7h#?IR3mX`o_|m}?3CzyPL+E!gr8ylJ z`Q$Y4Gp)UOh8|)fBF)72eL@>g+rL5ELD}k_5$f;io&#;^1z|54|2R@Z_QFV^4bsHc zL_}E)nwUHvd($uj`62`dRWLBUS&1R4>Vn&{KmdFq1p!n2OzvvtLmpfO0+amz^yx2N zqEJr5<1Nu=_V(*iK9M0IrK_TcV4_dASUWm9t=6UgIj*AuLMYoM-!I>os&Xy0va#6< zEwU8zTIUJy-8B;R;_b8@;`cfBJ$Nc;Gq`k*tE3HQ;vn#XZbX zQtaeXV{eS>x1YK0k>Rkv277xG2h)9&12*r-$jZvL&r$>Z52<=2U$h?{9-ee~co%uY zYeBBacQ(6KRMh`;r4hJj0##aBJ=M3PVs7sLpDTu|o^x`>mKs#5`uorMiMm8H`R*4N z#HM3UnIk|k1_M2NBV8G|SNy?2K|Ogrwaa~#irpuB$mQkYcNqB5W@C4m5n9!5jnx(i z&gwFw+7Y9S_#f{H0SBve6fSycu>A{%ZqgLd10Q7-72!>nsT!Sceu9ed3(p@nZqf52 zl1+~TYalbun}j_9k4ZbDX1Da^ z^>r!>_B;A+?NM88)QQ%3?fh~>7y99^4;)vRhQ%%OvVSWuf)^Kt7) zjEa-fIb>!SCDt_^#rRsWx5-tf9EXi?2V3Lchrf7r(&mJwe>YF_%?8e@Pd|k<`L(|5E&OaDK<7dr711IjRyJ-XXPsqK~%Ban?6 z{c>>?XXlFkw8mlYvemED=y)iK6eKbu7>tV%}nAovz~A4J^u4(frP;$(Y6dTadcQO?I1~5 ztBxCV|MAMzI8_3d>V4m@4Q_7cGFB9-ZD_bw)(AVgRU7$NikA32JA&MAqqI-@>ZzSJKTlL5>s70wg)7r9Azi{9Z&X`>u8&gbjI5D~ii^(_7kG%%i66b3sa7bOYI02j z_rg!f(au&&_=x|O%O+%r_o52i;sg%A$8N~er$0MQH5+@JIa^qQr zA|v?w^3Ff3Zwx0{4~#vgsx1rq2?~nlf{l8-{QT8a_wUyzOx9TYkdY&tO2o?ru$W=; z%I)CD7AFfVf_J9fC)2wOu2G2?>21?EgVk?HI)?7Cst#*NBl{&PYW%7dCX3zqYW*M` z^p1M*EoBBfvNm*P1_;BVvN}!_W*AlK*LG$OnXa2Fj?aX(q_85Wtqv0DR@`TxPI9qS5x^=XN@>z)KLHBCVKYM=hx-EFGxUV z#zDp__JT{v)jC#(Ys&lUg_&t#3Z=Ist2s|kPZhs$7Ukr;cmL<1skFpanM&-1oxX=G zDA!A;|CyD=yz2V<+jo8v_ut>jR~vXbP+%A927AGi@CBRGGVK%&W7!QUyZn5L@s}?1 zIftjtVtv3M*3A2seh((C7jO@VT$peiTQR2M(8DsHjPeI!N>RFSz6MhATlAiZW^Iq16WjM}9NkUOChZqfwt;Fo*m5?M zWrafx#Ma$syyU3js4Q%{y~m@YbDf?^!gW8Qd9Fo`-4QW5&;l!~&(ywY($Gvrw*^1>-fVc1sr}pAje<=&kw{`DENdj_Wsjrkjvz!^JM8j&f4~UPDbS?(3Z- z)gg1@w+RIU(BsC$QdEUFRoXngq)m;e_eMho5kKH@T4P z;que8UKvlqx*%MzvHp4;&H%Z85jEh3r7a61og?X++{qTU=cHtBIito5fw!vB)%r(8 zV5Y-l2Wv6={kKVZ2>gg;yKOaa-~%MOp=NZP;Fjizif3smpER`YzMWn_q2A zKNBvdD8{ULWgqqB{NZ{^;~;3S&eKyR8>VUPe(Dw^-_@CFBMOn@5`V9phBj_ox9cn% zpD9qAvBC^W7I+Vt1&K{7=jUD6i%rVyASsK@6lRr!Od7XKG=rvD?87zF6!C^s(LT5C zp0rFT7#>$!E7++jDj0eO2sxshOR7n`zIzEJ@EX_6S|aL=YC~Ba43J(8ZvK|O=cw_Ey()A;^QnQ$=DeCq>w2h(9L&i|Zq$#fvK9rBL&)Zh3nz8IdHx!yL>tr# zeEKHUaa(hJ{nuF?9z(B};};7A+1gJk$tGi=4NK20(k3j6zX+4A?BoGmJwqAOMjUAp zx6z7k8kfrrOnQR>6=bFq^K^UsdeF4rKxS?K!yJ;C;$v`o4lPl76NN5fi!!Lm3r{Hz@BH$By$vsdlq z0z>`%hoPjF@0TK)pwVH+Q&VeMv=_p5(hWI&#bKoNVJMt3$#js>O#O<`hku$;{sweT zx$nn%)k!dul}o>)r1mCl(>Zen_;m{U-K-!6OO?jj&>gRvpEh!lRa;WBIX+kzD39Ry{kL>kQ8)$XTz;sJ4{@NDq9%6@%-&v zltF4^bj93Rs*O^)%n_|VRKBR~Lfyo6H&S15{!w;Lpf0`NmMA6G2XeVrSa53iC!g4l zb0(=IWLP&t)gT2YlV1wf*EKw&x0kLko8p-ED(yRxyf|6f-v0u9i{%qMmU4_Mf%DE~ zz!75qdgkZHirpV`6KlTaHH&OUgV_Mp2Kk<2Mthi9AK9}Sz$=F(t(6e`lE@5D&>pv4Snr{!) zBbi!rOW%Uz`X$VjQC3Gbc`)27)=M0$MUF&^nJvU=oF#vjJQm}mo=Y6e1~#(%L?UQ2 zUMihT%66VOy@B6*zswDc>rm($SUT(&6Xv8g(?5>2Yhh^dZ9n?legvuLG<__CzhMGL zn;X|}yyG;+CP53^{Ai>tQl~QTH>qAz-MdlWkcC<+tAxzx1)NY;~V#M1Bvbt`TOPEMyq%%Yg^~H0nIiPx#+VK@4b?i=d$#2MH+MxaOz4f`p5aX1^ApOWEZ-aK_g044}QLEw7LG1CS8E|Dg~a` zdi&KTGEMR=BIouU00}Mladadnzw+KFPWr*sX@_6}(&dg@%yM*pim4|j`~|>-Xzu?F z`1C)(SRf_<8ps4)!L$dASAa}@@|}X=`-`OHBt|6)-kuW2U~7j-;Zy$i2&X71W>Csr zEZDT0{T7jfe+37KgOfM$ONS483xc&}DP)&GwJ;U$ILh{+OD}K`!x-|An+doP+7Xd~{ z1<$S@2OETkj~=PGxz%)bb@@oP%ze4eY4oWjFRN+|{=mXtHUsrwi=c9Fs*w zm^+Lq7Cx%_8s8+W)R0?QbP{H^hidYY24ZR z#m2_6u(Nkz1eD*rDe__`p&Grz2j{qgLn-{08C`w=^2i4^{AB=ph~T6Nop%I248H)9 z?23BqwU1br7ng(w*?(!dL+>6w4&Ou8o3R!?X8=unBeitbSplOw_+5MvI^mMj1(t5w z*1IXz`@uXH%V?BW5{d9(d?PL@>C@zajc)Px#NB|}ob;)`cT4Lk_dbV&A9&Xn%%CvE z8f(w%_~1{S^YVa|+2W3_-xOI+Slvlk*+E=Z1KWwbIcyz*!s^qpFf$`DGsI2Q^2zVg zyNA9is;sTh#-^tQ7|aa2@8ows4{aPo)U$RNZu&ZsYaW7UwPERo&;DrRnRRIMND-oq z(`|dwU|g}15OpFwq|;!&Xar$6p~z-7yU6%E27^k$d%RFHzgMXLQWvz1W?+eun3kva zEgFF=J^{82qlpSXk)FXp{@6QYWC?|t_H5*mvv2M*NUa`VubmhN8MyrID;dCBA0=MY zSSUqriG9%SV0P9wvJ2%{ubGCO@89#W!u`^TO-c7MV2X%TP0ZiC9-(>UY2#S|l^Tq3 zVhGc0PNi{aDM&QC7uzQGBnJIYzK99wpmDQcAXj)wU$i1uwl6L#T^c++-Oo|ioRRQ6 zps}X?d_7jbhHqQ$J3vUpv9GU-vZWYh43wv&RNy`8^r!F#<JYY&xGdbye5OtsDy z7Ow3NEsTv@>g=Y>%|9-v+0QhD2RDUIz-<43j?*m)_d%seMAqufF`!kwKWqdy19i zW>vT2_d$8_z3Yk|UqFRYQmEU{INCZWtv!yX13)uZ73PMn;ELvW$E-?il#Qh{qULNMJ$QO1sASzxsj^AEzCv&%e8 zk+4E7nQx2!Q)3GbY2G>b+{el-p-8}fp5I?XzPA3mH79U519c;Gs2wC*Ok7?b4EdyX z-8*@&P_OWjb+M%GG^@6apy)W&DBW#D|IkBz{$uU;I%lL-$M4EleW;4L=anyA7}Hx1 z6N5Tg3U8;0Zu;1tjm`+z?TYB@rLB}zj(RVTVDcOr;filpLQA>DYCI>a_-)#^=kO^r z@M(G(v(RDZL{l5(^-p?K8`yWM{xF}V!Phl5o7a%>C72$;#1|+h(RcI+dz1z9YwQxT zU=%uYoi2rrdv5TiDohoHO-!o}%^xVCQS?81s5jR>O|AU%p~l`+5Gpxc^Bjgl|t z9GUv-rL4%Mq~!fCfoHjcVfNj214wj8=Eh%+zkjkdAaYh(4K zLXM5}@pSkoRc(iF>zCrb0-d_yJ;f;nJpyYdH)}KWL(WbP`=6qY%QyvgC%u*5sEag4 z{b;cZD!A~|qq2Yqec#CEo*SwpcUse8H`sRgz@!^m+)wbd_7S|-u{t*@`qeAU{PU{H zDo;usS*k-KPO^E}kx4fbx_OivWBN(&8eu=+O!c6V?a9bdO-V-p!JE8PrPc0?s9r@^ z*}?kN$)=v7et6=o6zC&9aTW&8WM;%kC7gmfQ=bQD^OK%%nRLjTZrUrQc~Y*Ld^MD!w`3GUlDAtMIJ+&P)TQ z2xMslN+rNgtdQI#3IG1m$*%e*nEO#KR3y9G)D`*pUtA>mL*3Lcz}A#5wukDQ>CNPY zu(HQG3t`Kf{p(bieBJO#gO-P%*2nEUPJ_bJ+SugW-N3G$Ayw<8mIH`siISH-kRKAe zY5s2OZe_^xrk$S(I+6~8cAeulY9pm=&X*zko_)ppm6!9X#|(GN6GJxYA2 zin2WD|D)_*U)|^wDyGNYm47Yr36*!9hsRp?fuoC`Ou1XzNJZt2;k{db(Xnz?Hf_zz zsVYLx8OKVQ?jjyK2HA@Et*$q851nLJeSl8^spuxaTBiG5V$`dc?T zGo9xUzPq@xspyN!Sxo;Wcr24PBmeO)#eyO_>dCnGtXPN^pSO|0%Wm%=F$l19<2L5d z=Z;2X`@<8TS5!3FhXMk;qq;oduWI|DLP5|u2VbMC8m2LuA+PyNhqK$5es{^8amP@_ zFv#>kO-c1j@3T`Ep3{4=XbHRY6EF=k3GwedpG*at&h?ac2GRxUr61cyMD|a!R*u~0 zv(>!)V2q3w`?Cj?DJ!tcp15Cb8)HW73kykH=SGi#82^c48vD#sz~PQz6nwFIlJdg# zVR5fo()zPR9evg!VjGXFw*WO-pi|C9p5F9~{mXBwKY!bSSkDkn+3;+*^)v>F;pO(-4Jjrq%#_rh<{pEBEA7)!m`N*f9l6+^uZtWq8viZ9Nd$?K`G*l!)kOao^Q zkD68TZ%CyOH06@d1NvrCA?JpJtkVvha;#ij8l$7`5f2AM3Ul5I^1UeaxSy>bDv}$^ zD#kW$)YbpGzk9DqtnDJ%M=j|1#!1*{wq?|9B^b=dhX_uQecSFbrk0JQ%#PJlQY^b) z59}7vROhXmOYwHdEtGFxvCO+H@}-atQ&~X$lt&kVGJhZ!HE^LdajXju2vcGtJAt3XP5iL1E_l<;WP(!JFWK_Tnf#I%iz6ezu)nQIb9~+-0*;FZq;r z)2F*e+C5^EMdB@|jXnObwr8Rs6$|N{$q0;=As=gj_G2pAZWsb-Y%-uV`k- zcUe^u=>CFW)q`IR_JVq>^NAb^AbDol#}E%+$mO_e`!baj6+I7)j67C8?DD>rwLKi? z%Zt$5`5f6e{Ke|cZkQOY==47YJIWXuz6*68H-FnICy(odG<;W2!x|DQus}()O&-P_ zx;&qYP%Xln>6-eY=_ut5Z_%Al#L(FC{wctsXk9X*DV0I7=FvLrtl~toh;a)GtvyLf zcW5#G(C|tYv>U$q{C|PakSme!|BFrk&pG{HLgr5rD;w*c@lw>v>VVz+-K$67%xP*e zK&V+@K`H)`0(NEk+7fYq zeCe;o!RaO`Il^~_kd&0T6RDPe1`X(yavq5^C*Q0vh!cTPkJadgcB0oC4fwAmk@-o3{a4It+g^9k10Xtz^x6Z)G2u+#(XJoQl_Gzv zRZBcyE0Q2|hAXld9|Z-2V?YyPE!%i~J?OS+2*}jgIU~q$e=O{6Xz6S}e2?b>sHS)w@tC3DWR!N|*w{-^&+~Zu_Y%$*X|bsrvxR;x)90l_ z2c2K8OA#3=j)YLoNUhM%QR+ofl2lQXRn(f<_@N#p%>^p2n zUBJBsRgMk8@2&?%zEM$e$Y<&w9BhbuT_pM_G_>a&M8xFO&D78LJiac1J5=>;%<|aX zp5DQ7?Rn8(J&EpdC1@%I0CaddekZ``2l0ucC$@1rCMZ7-eoOAfb0 zfBqOVsdIAC6Y(AeXmgwPlv=pRjD+vW$KoHx%J}2VRHzw+JtwkY;Apb)g=!f?9d@xS z*L!JT!fkPxrZPnH&#}q@?gzvXS*35y=|`KOGKHEuAAgki;eIl{)pOHl#z(+?wap>) z0~#)KFw57r`;9f9rS@&qZxM7v40|T5XKMROd~Ju3zkJ`oIuGbe1N$y;8m=J;d|2(a zV`ZZNSh$xmySMK0Q{_O72-;z34|eT=1u@7%ORL%x{)DxaJR^RE_PDzSdacF^>ult3 z(dy*)sSHj3ym0WFiFUvJ1BSbF4|4-KoIaPEAf|L5T64XGXm8EgR=Hmvrz|^Wm}aWe zn1D!cG5to++4dA>$$=c|D9jrD!;K6SvW5b7|5+$??7(p`MjF<&-hKB^VQbH8BQwrx zYqrm2E8Yfip0JlW7~s76Cwpq_4?K~xj`BxS?=}UsS!ifdR-qg4fmBKKU56A4Wp&&F zpj{>cqG{=wB=ZvcTfrzK?!#uo+ypEpAxsnhJjz&a4UpNavD0c3*khZtGpWg)X5hVE zvpQhXO(2$~cx*>@DwGsmsGh#WC}(!O&$ZJ7%MK~nvVm#ajg3KPP1H_4fOGPX*eT+S?p|KpGJD?G7{vc zm!H-2X3-s)H%T&HqW@D2wl~mdEFL>bsE`c|PH`Ac-#;UrQz+6)^g)_iGmV9fm{;y# zz^T@Ox9+*8-ob8giHI~F-gz72d%jm_bNcuDj01}t-P1hWy~nS{x@AMZe-~8ybv6wx zk@fH>(~A)js#F8#&gH!d`1Sq(wxv?i;uo~C64;Q=%E2*}t76*pq4}w_Yp+p3E*Lr& znGQ?E&6@>nia0?h(gdsA7V(z5FN2+?NJEuRbqu4~0YZb06K!{hs6CN=r-1nG+ zViDhcQ?W^Tg#xwwD5>KgqTW&$Zw03sAO;BvMSjM5poQO2FFBaYk8GOn5079YAB+BK zmh6L-DK=)0$Ma^svj1xqu6c=orm0sr)Nb0+&!E_h%_BPrA#v z_4+<4;rfrbcMKM^{3~&gT6czI)4@rpV9Cb|F#MK<-NP2SEA5Z4KVsU>=BJr_Ph$SM z9Zo7^T&2&e#w;aGf;eTU+6k8tG-y}FAY;r2xh4-WF(vqYbB^LuqmU|L1w(C4S)FSY zb38tQ>a?eN-}KG1lPYN~HkRtb`j38vzgvWW|ih7OtT$rR{ z>Re(_B1`9y?aKbQB(ep!w)5sEeV%p-soo8Kepdie-|k8uNNW`L3pPHrw=QaA2w1#n zzd!5PXg#`YsP8S>?TioF&FIN?qyVFTwY>P+&7qB9=KK zEX*^tKqLLOaG%HUfIAS!%lQN2?XY_uXM!%&7L=lXXJxhR3<2EWpzSN>%F5c>)#jV= zl7mg#`9QDdpm&+tux@7E2gZ)u!>gL*H}t-+4}KF>v(RG{mNL?Z%)3}U{))5&>A84RA zeNVOPDGmjB%XjJl8zfGNp%e!}SI_u@hE?=jqUc1%X*kZ7qWXZfVdiqYb#sC`4L87_ zF68JRNc;E}v@55Zm>yFZU@}v$h~bqtyr&EE%*@jNG9HsPa8&e)SqrNHkcsd32REZ(-o28l(_!y0c!RyHS75(6(*>B237n}PxQ0F zgpwWkhY?Y~V?dQ!Z9ZUhtEuChsl|Ls8O<8VJ%08GA~g|HdIrC7la9a7!{Mv5s?x_* z-O(WD@G9HNYpd0i7nVt&8Dx$S-n8~=Gj1LqHG3HUedn0@61IrKcr_16>#~$^8WDK2$PJ?oTe>g50_J zJ+@XDvH>&hDL1OE)&@zPO&%nkw5GP<=9SdrO5vDkrJ~GAz%P?(%_roe^w&twVrQOM zO|V$9O7W(#8K`B5`Kh^>;TpDaMhtv|$Tu`Y2xThGIlyzx^Ob;Vg*EF~kN?XzppA!Q zRLS=vibvoDwmmgRKK&2FvKA)P$`1A;8u$4UdZf8vEpsTumO`~QJ-zQqkNRacuBv%RJ(bB`B6au zRdx>ZYv@=}J2|IW`lu`a%UL6((vgZeDM70ExxATXRTsgSImLWQ*TuUS3aHq<905>^ zQlZ6~2W7i_8r+;VUE{glFqb6$d#o$pJPNzOz)N$W+7i`~{+I z_9s6`p*3xTlw)jabaci@wuy2dQ)cDg6(0k}3WPzXZ^L5&oq_H1UN*&srw@4cCYfqf zO#1`^<`b0=(*MfQJH%aFK+xR5xYPleaa*o5yH`C@S(&4Nue^m_(8thK@yJV%bNaQs^$6Z$(8`z<{AF|$sg`dPcP9beFi_`luyS4N z*Tts{%zJn3O{Y$~z=zrDUx$14g&>dWML!;vffm-E=qFL}<41W5Yw$_+W>y`41_rSR zStxM_mS zLiR3*@lIVEto#p&*o!`d^ObKU5Jb)^wvvwElh0+9MPm}hc_LM|6gbbk3G@-vsI zQG`D#z=+3bj}9cf*LRtBVe3Pku$YUz12_oHOl+#6Z)2ieWZt1S;F zdL4rYAP`PHkLUp~pNk{C7hhJOX&u^S+e`X`4UwIU-JL}I$8Ufv^a8vJ%8pVfLfsxe z4NN_ZNUc|PMCr=><6xFc{{bZPL?!Bq78MdLkZ93>i%QlV6HJ+!Hg&BbEf53mzM9LJ ztmG%Dm6C}zpVrv)T| zQB7`3<{Zxt&00PGFh$4#ro)h3UifD#%q!HLamV2Kd$8|X<+q@;zo>cf9sxUzVVb4; z&@^JJU$M|wjBpYkKZinMq z>u-rR6m;1Q z%(Az+=xVr^IDB}<{w2DKYt(1h?)3f1Lky12a*?7ROM~W#yO8a&UYcm%KTTS){yibN z;%s^JH+_E{gYNBEX{?xZTU(=97qR+MW{l9e|5VIA=w#|&HH9ZfZ0$W6Nfu#|aZ`q= zw>aY~DedIfc@q&+87ruy|FAG#*9LYC((Y-e$0eJPrQVGSJ%wF!2G?wyflk+3D%doz zC%w9X$5=3Ai^n8KJtamThL@i35&=~7=6M3Z$6LE>ox+ZOq4@4G{~d~P=^8kGu+R&g zv0m=nkw{H$B)Rd#BC-7T>)*`QKZipFCSh$na_#pwvMl1P4vzf>VP{R%I;&~DK;$xn zGfD8ZT3!cqIECo!GmDaaviHG^1bWi7OpeltVLN2>)# zyRhfu3+q>m$mE*wBI(UbxkCrq5L4B6PAppc7zHW1fgx0dfpv+Bg6;00G84>+fwg382a+Z_0n1-e@|*OhSN8VLTzN;s^uCK7V{!kdHMZ5NS;MSM^}YB;p?k~ ze~3tHkP&u4yEvnjgD|i8`Y_pA4k`O#Xt3to>7ixwtN0T7f~tNYB2Q#&D7j%Lc938-+AhJ&C>iz)*)8 zCmj5@0Bm34z$6%e{mb=ftJUJT8=`8dS2K@EE6_93Pa!=bnE8;WNWCtXx(1jPbT4U* zWj~v?)3b*56bqR@qN3!>yhm@DDn`z5M|cF3ZoG$;{Lrrp6XqObWG?JW{oX2Z=HPYX zM#^WwYxt<-u1(Sri(K2(UoXT4I@%eub_`<7??(NTxlY6s)Pm^_trdWcN<`f~v#B{; zlh%gQNq5Cg+t-@I6bmALyfAoFKDoR{`P%qmUFI>aD=PJs#+jj;UP@%jd3#=7K^k=E zYmh3~ajH5F^Kt1K5lHSL-wA1_uiudJM%wn5N@+{$!S4Egs$#wLUbsuan|}*BZNC7k z^uj#FLID=vPecoOG|o99x$REOMVTF`ixv7%cb7o~-vF5n30qMk0etjF!IMq$WKs-l zU-RQuD$x-_NZ#J?W06Fqwfr|xszvL^oYRUnHo`7q|2^Y9z#9D@PO%yC$s1~GGyVC) zs;#T*bYbG;4EWNS+IAF@f21-pE*MyA4BJmpe2|}TmV8F*MIW1vkL;@!%ytuGlLdIL zld&rw4PG^f#t7iww%WMSRZ5R4r}Qim%jS4YJQ-pfwOo%D|4}`Bq~hcoTWo$c81r+q z(b4ZYrK#pdp{>@XdSn@5Udk2oAqgj)4|Q&SGl%oy?*sa7+OepdgdZW+Uab7i{{H^T zzwEftfbJWohX*d!ok7iRghgu(?i}NrpM1iDW<91p9t1sAA&vX8*diJ%WCxm$P>-gf zJ$}**nFO(*%2hP*H@IdSBe+F97QcY9rPy{Sn~f8)kM(Y4lE;n2VU%(H%n>)Rhg;Ix zHUnTrl*`}Uq?<&z8yu%8SJsP87uP$d$o%rsO!|Q;eo?{S1Nr zDTeK^!2Xn489>$BbOl!*`3Had*4J-zVAa`8CSbcw?sn=XpHH0J)-Fl3d#|tJ77f|- z>7TRhSQFh(R~ZXz6nTxG^VdM@eN}a5^ZG{D)eh@}6YEW479k#_Ek4zT%;#d2=+tR9 zS>>joF!*jJCqA%*_oT&YXr6e#izHL%${JGJmX#&Lrk=_O7%wK9!3W*BLp^Of)cVi) z0HK7)_xI(h;y;&F;BpSn|zt@zW}AKC#JYc}@6H?>J<9s^U8Mr;ytcmIPU( zSF?~JB<4mM^gQ-(j`SL>)WElmozG0h>F6k3 z6hj=;e~9t%SCb85Un>p0F_nwGK_?1vCZU&Nl9=8$HXxkLKBWjIr=;sF zVd-8`ILR0JeS`n|nN2xJl*0E-BPJc#jX^mud@bMK-i4)KqmDnHqq?;=(UgUJZz@0M zrpM&j4$hhBytc5&e){U;8-Vm>opRpMQCE+2nrToy-XRwN-}teVn8-^j>$`WN<6?sifaX$ZmJ>gUqeUjDIM| zJVY_jycGmt8`+umnG6~1r>k?`5&bYWE9G`xW=}8S!#G=paCZL`TvqaXLx}cmLY~0s z*``+HES!#io*RizMjZu1EPNYHl5hv3$>_9_%VF8jRvxMaBSK4%WP`$Gcm zepiUYP}h{ZRAfhFzs3Bwm3@U@!X6LZ3%nrt#u8v+@!d$y1FWs zD=7}$wpQkzv&7HO(-V#HPD_Zfe9Z5^i)OUH33X?Tz9s4>#}`+?G#kLuq&O2Asv$gM z1os~@Q|ql9qROruCWup&3ENJOaJAcgEpXcaN}8_f99YsaGhH~<%;s~feU#PJh5B6b zJ2z*DKYddI5a-|}QZ=u*^ZjD%c0~<0XClNWG8OVv0ya^Ir~SYXTE*16i8QJE_*L*7 zCf!Rq9`F#utiIGcE1ZuB}Wq{4Os!$Rj%?+_|IZ55F zp&+sGci+e>H@&5nWA74d!kSh3fvj{OL^GYGa*0+t!TWDoA|q`BiKui_>qH3!)cGI4E3Yoj#-J>hP3`iW&|b6a z24ewyLExkHN~*P?=l5tOk%vd)FOdk7Uhq?*G4b2n>-D#Pa0fJ(eLtV;jVixg?fh5h z=e3<4V{~;nhQA%uo!6G@LPx!n4|CM(gVvj5$JFm>Y zMLZz3d>Y&sEy!kdS^4ez5)I56kPJQFcmj=VDVz^^!Conov#4{z3e*+uivHhctE#Hr zRCKYW1OQEaLzkZNnSDTWF^xSMSqpmD(?7TZB$uBwv`|IvZR4~UOgWvZ`cQ0>mA~jy zpm})YV?E5rJC&g?5Lv_VC4dL`DRA>$vW>@3H8^!;*A`}g?(N%w7s%(2C4lcTul{xC+_!#-W1W}AfuoPg7ARnBDH0zQbdONg9tE~634gdR z$WyS`(|L7yL>KsZz1Qj4+q-)1cIBa(9M8F9PvSk0zlu@ckhiO=ijrgUfyzq#i%{49 zt6a2dR!j4a0rx>^Id!qSbnK|Wz&O$2%?;?{*fALgjm>jz#-QkL)X+~YGU-{)no31n z4({qLV2BA~auoi=yw9A+OGmI)ZHDjv+3a~m;HsSTZ8tzE@BS~P9GHs#{leP+fiwJn zp+pzBQ&WI^vepkSpPCM9`!nT~SYH`7wjJi62XYaVWA}V&e)AYC&w-ixc{rjWDb)FT zV{)gPRfI*aY7xeu2ig_{&azC`zYYBlmZE)(gM4cFRF@o)D;m7V3;!tONQ?Ey=r$fe zdnDOA7iJc_8;Fsztpz11Go);hsO?4KMZ&wW!uL^9NUSV&Le7!ofF*++gW9}GHZWVnF zbi+X?H}3jI6lpN4GbZZ+@WkUqJ`Wgyp#e}D@HjyE>>E?S^gK7rZf0)>5$CZaZBoL36yi4mjQ&4qtjYKqB9=9fvek;+N@pk zf>SfG{vqja)W7t0Y33}O*Juf{`r~4+irx-p6~oN97bBDvY7A^X$I#sI9b2BLh&iI0Fr@DLCeO3Vs~pMy_*7Skue z{kk61y`Z_z>J>xjdORCRg7RW%Pw&{2l32wQC;cl+p&Ws`ueP>y$LcI z#9oQjONyE8#lN)Vxt`?xu*!!v7ElGKQ}wYWp3~izWXnnN$@&`l9DwS$`|46!Lvi<_*AK9 z{uo$GUJliirF8T7)6<=RP1sh9Mt|0|%R>KEhi@L0i*+fZ&JKE^^K2a%iqZ}G~8{bzA73n;(F8syz)p1>CkFX*a(4pJfjpKj^F~E4U%_+31 zi?V_;CbG9S@f6~;2~&$xLFD6}Gn-@C>+*-H*@b#sHxJG_HMr=T^t8+NmN`xd1as8BNT3Omhb7jnJ*eLlDVQ>sa3Y1fNO+Dq&eM>~+5WZHL2g3I4i z&^n5}ggQhRCc|*h3r2&7?t+N+Lk%Bigli!UVbQ%zT~J3yNqV5_$9WT zRH&T-^&6`v7i+TpR!=^C<48K6G7;--JgreoY=3x)KCdsW8PoEe);;PUa?z^|`e+g~ zO)5#)TD2&EYl;MNmZP=%#e5jI(vDUPeZdnDnB9z&KPlqms~DYJhtdvMW5Y zj(HpKSx!ml^2aZMpjp}x&h4>6y~{D51fn9i>LxlKjJqubLE3)tj_N2v8BO^V=R1SS_tWVX}5krL8BRud1 zjK%{r0G~^N4wp)yVe&?G%gldk=e(nuO!hvm>nhQ8(TIqOf}jzIGzqAo3R09R9fSly zARrJVG4y~+q)1a(T96JA2_cd|s998s0s;b|3#c@uDkM@uxli14|MQ-E_T78V-S@oj zIrHDlQ)cEj&wS?l%zQidECkDqm|#p49}#=Qi^dzC*gM5O+y&l{Imb+h*;HOGi4V{K zebxLkv#aA=)Ggf>P5wOqlwE6!`RzF{b90VNUHD_>7KU~7iGnjbqQP6y_zUv9*&H%` z3}?awJ0h>-tWURG=I7^K*z7H?E6l@eXx1z5_wRYLd=i`fcuWSMjA!fqtK2Uyj-B9P zN^JFM7RHzzbB*Cc`(UY%yvO!{ml~en4<5F$|jv!V9 zegBYq>+6g1{D%Q(piZKa?OrnbPff$XP}EZH#N9KanD@XH{*by_1+De~_iAlQT8elzb9&3iUev_bQl+2 zed&0@Lc!`ioVb=BYx0+_xE6`hGZPcS*zpSRjq$pY7~oa_^$~5+pPb-Yh!3rMp0)GV zAXi2I@B;xB41W$Sf8--$Bc%h#!hk-u^L}H3gN-&&xeKP}3s15HmyeDH7?P#021JF~Io!FtnDeti27GYCD2YvSQkP$NdTSAZyp*k;M zr(zgT<|~>d16jTYdipbvyFyba2KHwA+VdX-8rY#}2p^6VaE!8~D#-Kj&TDTraBew5 zJpU-K9p$X+!bV{GZ}kXT+stbqTykIp5gGxlGV$ zWbfl~?r>qybS&tIy-AK+pzalFhB?lYfjUwKe!plY>N0)RkvmPS9arB2_tPJM5xd zdecHhilaHopa~Bp9OvV2P7xqAGd3cC;S~8$@iv&jT{oyYk|J3eC3QeB<-~TtPedh) zeb&t8SztYWbr2aaqa53L61ZpVMeKhwL}B`K$^j%Fh|f zGsSsS7xU-aKf{8H1MtIjBJSVd%3{sH&-bY2$<^DT>`}tFV*J$GW$_E_gf|Z5ny#`) zDdFPfGg3;!RT@es4bJVFO)(1Me;wQJZ(D|rF7B_b56oIpWng8Ldp)#;p%IHQ$;inS2mB+uto~(wCgu(+5X=zKK=sR-iL6ssP>Rzli?QKk&;UJ4m!; zD2shg0;l$Mrr9dpP`KPvqN9BN`g~{=!WteT+W?we0t>`kKIGj$?KxEpiAGU4qujCu zFNM-Pt)97oA$-%|e6*L!mFGD(+Lcd|LZ>2UR?qRa)&4$nqt|oat=<~2fOm7yvw`zL z4q5JB9|fNcA%gQC5Dwsy4wo#l=KAM!U>HGC$rzUe|+ z!+_Nxo1a*78Xm*cE%gng-BRt^dbP2k7Ol3ov}VAUoVn5Ft3iW$+gbR^I@CxRY0OGf zf_}ZlpziR!UB@wqxnLDW@(aWK0+T<5Zue}qhJSoP7YdVRnLxXzZ4^{K*O|Q z$@`nyZLjyjQI_#pHdM`JkIf>^WVze@bLjbflcgt7A##0rV}K3SD{#&vH)&>~g(C@f zvdpFW%{nG$@b89kXZmqYdNL_Ie>MeS}ysOQ(UYx4Z3K(k@Tp`CBl_xnzbs`8$R>e#H z#j-)=^-oAQ)r3MCE%X+AXJ$GL1I~UV+AeH}Y#b}K0(OP_RHW z+PI7Yiwj37Y$OA@JOgan1l(5&E#H;W#gat$l4xk}g%4x8Hp9isv%~1Dv?+V0SIX0i z5r#x}bcAkYL!pB%8*iZBc8igh+lM1hb1YY zd(w$X;VL^d`5Bj`^>dCz#ep2$N88+GDU#f{OvU(gx@WojB5N!gA0*1z&{~VnbRJQm z#FZaqjG}7d&FU&YDKja{vrMx9_FhJ>{ z>rdas7*y74Z|)6fFLEvy#mu#g)&8VRc+@osTf4yK&uOk#BWgh13N#~nCcj%}k!eNfivxx_ zLp?2eqEt&#&{o>HDl2Qk-QFt>=~$J0n@wXa^2(QWxnj7h`WScfnc)XlQ#?kqAFRFp zj3r6YJ>T)QTIdjn>h-Uh$;Yb=I&$*z@paTULXTi#A0|05X=8yQb2nHx4&0*Y8Z&EO zd?m%5g&_2(@mlvD=*(*tU^tXGTPB(UZ{4ev?hvMeK+BOPSmy3{^4ws_UWzaGZ-}Cgynhm~WGw*a- zpS2};`ng!fo}7gYtB7lD)30suA~iHh38*6+akee%Xa>w(PE-k-30q`|e9G%2Z+^lY zZ&bOxDBYdqw!AzYX%-Jp?YZzhMzb+r8jiRRY+z5uyiurMYps(Wa5UKF@LD({Fm+RF zE>T$Cm6nF}Q(u3eXP(b5*{NPk&q*Pdi2`h(6n0^dEpojX9ltkSVaU^(d?mzHn=UOY)o6iK7Bv}-PX-Pg-y9I36eadp#$^=u6`0j_2W1;QSJpF2*TG$k z1A2OH`Yc9N#>0fvciNnC2RD)z#~#M6RMNLxZSmtCcvm@4JNe1C0Bz>gU)dsr8*A;W`|BLL=nZL7w(VbZS-O=n^0hoT`?E(`$IVAw^{YoV6KSWx-gxvUo8Ns%eJ#!}!a zKkZK=sMOZ&JPxkdaU=Mxgbi8zwh==}>KRfS86su|WSBu#pTbzjA&`&Q_54GfILty|Ja68g9z_%w5qj)-KVy Ge(xV$@3Gzh literal 0 HcmV?d00001